# API Gateway Local Development

This runbook covers the mock-only API Gateway skeleton.

## Security boundary

The Gateway remains mock-only.

Do not:

- call FinanceManager endpoints
- open Health databases
- read runtime folders
- generate reports
- trigger uploads
- implement POST/mutation flows
- hardcode Tailscale IPs or private hostnames

## Create a local venv

```bash
cd apps/api-gateway
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[dev]'
```

`.venv/` is ignored and must not be committed.

## Run tests

```bash
make test-gateway
make verify
```

## Start the Gateway

```bash
make gateway-dev
```

For the full operator demo, prefer:

```bash
make demo
make demo-stop
```

Local only:

- host: `127.0.0.1`
- port: `${JARVIS_GATEWAY_PORT:-8080}`
- demo mode: enabled

## CORS for later Vue local dev

CORS is enabled only when `JARVIS_ENV=development`.

Default allowed origins:

- `http://127.0.0.1:5174`
- `http://localhost:5174`

Override with:

```bash
JARVIS_DEV_CORS_ORIGINS=http://127.0.0.1:5174,http://localhost:5174
```

Rules:

- no wildcard `*`
- no credentials in MVP
- no public deployment

## Expected URLs

- `http://127.0.0.1:8080/api/healthz`
- `http://127.0.0.1:8080/api/modules`
- `http://127.0.0.1:8080/api/overview`
- `http://127.0.0.1:8080/api/demo-info`
- `http://127.0.0.1:8080/api/activity`
- `http://127.0.0.1:8080/api/approvals`
- `http://127.0.0.1:8080/api/reports`
- `http://127.0.0.1:8080/api/redaction-policy`

## OpenAPI

```bash
make openapi-export
make openapi-check
```

Writes `schemas/openapi.json` without starting a server.


## FinanceManager Read-only Adapter

Phase 5A adds an optional FinanceManager read-only adapter behind `FINANCE_ADAPTER_MODE`. Default is `mock`. `live_readonly` requires `FINANCE_API_BASE_URL` and calls only the approved GET endpoints documented in `docs/integrations/finance-readonly-adapter.md`. `disabled` returns a safe degraded Finance snapshot. Exact Finance values remain blocked; `ALLOW_EXACT_FINANCE_VALUES=1` is rejected.

Smoke, only with local FinanceManager running:

```bash
export FINANCE_API_BASE_URL=http://127.0.0.1:<finance-port>
make smoke-finance-live-readonly
```

Rollback:

```bash
FINANCE_ADAPTER_MODE=mock
```


## Phase 5B Finance Live Smoke

FinanceManager was validated locally in read-only mode against `http://127.0.0.1:8001`. The local start shape was `python -m uvicorn jarvis_finance.api.main:app --host 127.0.0.1 --port 8001` from the FinanceManager source repository using the existing local venv.

Validation command:

```bash
FINANCE_API_BASE_URL=http://127.0.0.1:8001 \
FINANCE_ADAPTER_MODE=live_readonly \
ALLOW_EXACT_FINANCE_VALUES=0 \
make smoke-finance-live-readonly
```

The smoke checks allowed GET endpoints, `/api/modules`, `/api/overview`, `source_type=http_api`, safe Finance `ModuleSnapshot` shape, and forbidden string absence. Raw Finance responses are not committed; see `docs/integrations/finance-live-contract-review.md` and `docs/integrations/finance-sanitizer-mapping.md` for redacted structural mapping. Rollback remains `FINANCE_ADAPTER_MODE=mock`.

## Health local probe smoke

Health is not treated like Finance live HTTP integration. `local_probe` is a metadata-only local probe. Use it only with an explicitly chosen local runtime directory and never commit runtime files or probe logs.

```bash
HEALTH_ADAPTER_MODE=local_probe \
HEALTH_RUNTIME_BASE=/absolute/local/health/runtime \
ALLOW_HEALTH_DETAIL_LINKS=0 \
make smoke-health-local-probe
```

Expected result: `/api/modules` shows `health.source_type=local_probe`, `/api/overview` contains a Health `ModuleSnapshot`, and no forbidden Health strings, paths, raw data, or secret-like values leak.

Back to safe default:

```bash
HEALTH_ADAPTER_MODE=mock
```

## Health safe inventory policy

When using `HEALTH_ADAPTER_MODE=local_probe`, choose only a local runtime directory and treat it as metadata-only. Do not point the adapter at report files, exports, logs, databases, OCR output, PDFs, or tracker data expecting content parsing. The adapter must not read file contents and must not emit paths or filenames.

## AutoShorts read-only adapter

AutoShorts supports `mock`, `disabled`, `local_probe`, and `live_readonly`. Default remains `mock`.

```bash
AUTOSHORTS_ADAPTER_MODE=local_probe \
AUTOSHORTS_RUNTIME_BASE=/runtime/configured/outside/git \
make smoke-autoshorts-readonly
```

For a running local AutoShorts Dashboard API:

```bash
AUTOSHORTS_ADAPTER_MODE=live_readonly \
AUTOSHORTS_API_BASE_URL=http://127.0.0.1:<port> \
make smoke-autoshorts-readonly
```

The adapter calls only GET `/api/dashboard/summary` and optional `/api/health`, only on localhost/127.0.0.1. No media, render, upload, publish, token, OAuth, script, prompt, subtitle, or log contents are read.

Phase 7B verified the local backend start path with `uv run uvicorn app.main:app --host 127.0.0.1 --port <port>` from the AutoShorts Dashboard backend and a temp SQLite/storage root outside committed files. See `docs/integrations/autoshorts-live-contract-review.md`.

## Health safe marker smoke

`safe_marker` is the preferred safe bridge after Phase 6C. It reads one synthetic or HealthManager-produced safe marker and never reads Health content.

```bash
HEALTH_ADAPTER_MODE=safe_marker \
HEALTH_SAFE_STATUS_MARKER_PATH=/runtime/configured/outside/git.json \
HEALTH_SAFE_STATUS_MAX_AGE_HOURS=72 \
make smoke-health-safe-marker
```

The smoke creates its own synthetic temporary marker under `.tmp/`, starts a local Gateway on an ephemeral port, checks `/api/overview` and `/api/modules`, verifies `source_type=safe_marker`, and fails if marker paths, filenames, stack traces, secrets, or forbidden Health strings appear.
