CI (SIAX Cloud) / integration (push) Failing after 22s
CI (SIAX Cloud) / security (push) Successful in 22s
Security Scan (SIAX Cloud) / security (push) Successful in 21s
CI (SIAX Cloud) / quality (push) Successful in 43s
CI (SIAX Cloud) / integration (pull_request) Failing after 3s
CI (SIAX Cloud) / security (pull_request) Successful in 17s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 16s
CI (SIAX Cloud) / quality (pull_request) Successful in 43s
- tests/integration/: 10 tests against REAL OpenSearch 2.11 (tenant isolation, purpose/rights filters, generation rebuild/rollback, projection-disaster rebuild §68) + REAL ClickHouse 24.8 (tenant-isolated metric DSL, TTL schema, injection-surface refusals). Honest skip without env - and CI fails hard if the suites skip instead of running. - .gitea/workflows/ci.yml: new blocking 'integration' job with self-identifying service containers (st0re ci.yml's measured alias-collision discipline: run-unique cluster.name / credentials, getent-enumerated IP selection, no-match = hard fail). - STATUS.md: full 8-level Master-DoD classification per capability incl. the honest gaps blocking PRODUCTION_READY. - dependency-mode: NEXT_PHASE=phase-production-build is not a serving runtime (next build page-data collection must compile; guard re-arms at boot) - pinned by contract test. - docs/02-architecture.md: superseded the accurate-but-now-fixed 'every client runs against its mock' paragraph; .env.example: client URLs now actually read from env + new P0 backend vars. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
205 lines
10 KiB
Bash
205 lines
10 KiB
Bash
# =============================================================================
|
|
# 0pt (edge plane) -- environment inventory / example environment
|
|
# =============================================================================
|
|
# Copy to `.env` (gitignored) and fill in real values. Never commit real values.
|
|
# Vercel env for the edge app; VPS .env (git-ignored) for infra/docker-compose.yml.
|
|
# See docs/08-infrastructure.md for the canonical description of each integration.
|
|
#
|
|
# Two provenance markers are used below and they mean different things:
|
|
# * "wired in code today" -- read via a `process.env.*` somewhere in
|
|
# this repo right now (grep-verified).
|
|
# * "documented target, not yet read" -- named in docs/08-infrastructure.md /
|
|
# docs/02-architecture.md but with no
|
|
# `process.env.*` read yet. Filling it in
|
|
# unblocks the integration; it does not by
|
|
# itself change behaviour.
|
|
#
|
|
# The app is designed to build and boot with all of these UNSET: lib/db.ts and
|
|
# lib/stripe.ts are lazy + env-guarded, and the storage/payment/doc routes return
|
|
# HTTP 501 ("not configured") until the relevant keys are provided.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Core / public
|
|
# ---------------------------------------------------------------------------
|
|
# Public base URL of this app (used for absolute links / callbacks).
|
|
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
# Documented target (docs/08); no call site found reading it in this pass.
|
|
# NOTE: api.0pt.app is a dead hostname (falls through to wildcard Vercel ->
|
|
# DEPLOYMENT_NOT_FOUND). The app serves its own /api routes on the site
|
|
# origin, so the honest base URL is the live origin itself.
|
|
NEXT_PUBLIC_API_URL=https://0pt.app
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Database (Postgres) -- wired in code today: lib/db.ts, app/api/health
|
|
# ---------------------------------------------------------------------------
|
|
# Vercel Postgres sets POSTGRES_URL / POSTGRES_PRISMA_URL automatically when the
|
|
# integration is attached. First one set wins, in this order (lib/db.ts):
|
|
# DATABASE_URL -> POSTGRES_URL -> POSTGRES_PRISMA_URL.
|
|
DATABASE_URL=postgres://user:password@localhost:5432/opt
|
|
POSTGRES_URL=
|
|
POSTGRES_PRISMA_URL=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Cache / queue (Redis) -- app/api/health only checks presence; no other call
|
|
# site found reading it in this pass (worker queue usage, if any, lives in
|
|
# services/api, outside this repo's scope).
|
|
# ---------------------------------------------------------------------------
|
|
REDIS_URL=redis://localhost:6379
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Auth -- session / dev-login / service-token secrets (wired in code today)
|
|
# ---------------------------------------------------------------------------
|
|
# Session-signing secret (generate a long random string).
|
|
AUTH_SECRET=change-me-long-random-string
|
|
# AUTH_URL is documented (docs/08) but not yet read by any route in this pass.
|
|
AUTH_URL=https://0pt.app
|
|
# Optional dev-only login shortcut key (leave UNSET in production).
|
|
DEV_LOGIN_KEY=
|
|
# Shared token for internal/service-to-service calls; sent as X-Internal-Token
|
|
# on every engineFetch() call (lib/engine.ts).
|
|
INTERNAL_TOKEN=change-me-internal-token
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Zitadel / OIDC Bearer verification (Wave 2 hardening) -- wired in code today
|
|
# ---------------------------------------------------------------------------
|
|
# 0pt verifies inbound Bearer tokens against the fleet Zitadel IdP
|
|
# (src/auth/zitadel.ts, wired via middleware.ts). JWKS are discovered from
|
|
# <issuer>/.well-known/openid-configuration, falling back to <issuer>/oauth/v2/keys.
|
|
#
|
|
# Fleet Zitadel issuer (OIDC). Default when unset: https://id-customers.siax.io
|
|
ZITADEL_ISSUER=https://id-customers.siax.io
|
|
# Enforcement is FAIL-CLOSED. Leave this UNSET (or set it to "true") and a
|
|
# valid, verified Bearer token is REQUIRED on /api/0pt/* -- 401 on
|
|
# missing/invalid, 403 when X-Tenant-Id disagrees with the token tenant.
|
|
# ONLY the literal value "false" disables authentication, and that value is
|
|
# REFUSED when NODE_ENV=production: the app throws at startup instead of
|
|
# serving openly. Use "false" for local development only.
|
|
AUTH_ENFORCE=true
|
|
# Optional override for the claim key that carries the SIAX tenant id. When
|
|
# unset, tenant derivation uses the documented precedence:
|
|
# urn:zitadel:iam:org:id -> urn:zitadel:iam:user:resourceowner:id -> tenant_id -> tenant.
|
|
ZITADEL_TENANT_CLAIM=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Data engine bridge -- wired in code today: lib/engine.ts
|
|
# ---------------------------------------------------------------------------
|
|
# When set, edge route handlers defer to the FastAPI engine (services/api) as the
|
|
# single source of truth (orders/estimates/catalog/ai-parse). When unset, the edge
|
|
# computes locally / falls back to an honest heuristic -- see lib/engine.ts and
|
|
# app/api/ai/parse.
|
|
ENGINE_URL=http://localhost:8000
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# SIAX platform clients
|
|
# ---------------------------------------------------------------------------
|
|
# WIRED FOR REAL since 2026-08-31: every factory in src/clients/* reads its
|
|
# *_URL from process.env when no constructor baseUrl is given. Under
|
|
# NODE_ENV=production an UNSET url is a hard boot failure
|
|
# (SiaxError DEPENDENCY_UNAVAILABLE) — production never silently falls back
|
|
# to the in-memory mocks (Master-DoD §3/§10). In dev/test, unset = documented
|
|
# local mock/no-op behaviour.
|
|
CL0UD_URL=
|
|
N0D_URL=
|
|
AUD0_URL=
|
|
# Optional service bearer tokens for the platform clients (machine identity).
|
|
# Values come from Infisical/secret refs — NEVER commit real values here.
|
|
CL0UD_SERVICE_TOKEN=
|
|
N0D_SERVICE_TOKEN=
|
|
AUD0_SERVICE_TOKEN=
|
|
ST0RE_SERVICE_TOKEN=
|
|
# INF0 (AI OS) -- documented target, not yet read by any code in this repo.
|
|
# Route AI-parsning / model calls through the gateway instead of raw provider keys.
|
|
INF0_URL=
|
|
# ST0RE_URL is the convention name for src/clients/st0re-client.ts /
|
|
# st0re-lakehouse-client.ts and is read by the real-infra test suite
|
|
# (tests/p0/*.realinfra.test.ts). The lakehouse write path was live-verified
|
|
# against ST0RE on 2026-07-13 with this set; unset, the clients fall back to
|
|
# their deterministic in-memory mocks.
|
|
ST0RE_URL=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# P0 Data-OS backends (src/search, src/analytics, src/metadata, src/features)
|
|
# ---------------------------------------------------------------------------
|
|
# OpenSearch — search projections ONLY, never canonical truth (§42). Unset in
|
|
# dev/test = search capability unavailable (typed error), never a fake.
|
|
OPENSEARCH_URL=
|
|
# ClickHouse — 0pt capability analytics (tenant-isolated metric events).
|
|
# HAS NO CONNECTION to b0ts pipelines or quarantined market data (legal).
|
|
CLICKHOUSE_URL=
|
|
# "user:password" for ClickHouse basic auth; from secret refs only.
|
|
CLICKHOUSE_AUTH=
|
|
# OpenMetadata — metadata PROJECTION target (canonical stays in 0pt).
|
|
OPENMETADATA_URL=
|
|
OPENMETADATA_TOKEN=
|
|
# Feast feature server (online features path).
|
|
FEAST_SERVER_URL=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Payments (Stripe) -- wired in code today: app/api/payments/*,
|
|
# app/api/webhooks/stripe
|
|
# ---------------------------------------------------------------------------
|
|
STRIPE_SECRET_KEY=sk_test_xxx
|
|
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
|
# Documented target (docs/08); not yet read by any route in this pass.
|
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Object storage -- Cloudflare R2 / S3-compatible
|
|
# ---------------------------------------------------------------------------
|
|
# R2_ENDPOINT / R2_BUCKET / R2_ACCESS_KEY_ID are read in code today; all three
|
|
# are required to enable /api/uploads, otherwise it returns 501.
|
|
# R2_ACCOUNT_ID and R2_SECRET_ACCESS_KEY are documented in docs/08 but were NOT
|
|
# found via a process.env.* read in this pass -- verify before assuming the R2
|
|
# client is fully wired.
|
|
R2_ENDPOINT=https://<accountid>.r2.cloudflarestorage.com
|
|
R2_BUCKET=opt-uploads
|
|
R2_ACCESS_KEY_ID=change-me
|
|
R2_ACCOUNT_ID=
|
|
R2_SECRET_ACCESS_KEY=
|
|
# Fallback local artifact store used when no object storage is configured
|
|
# (src/adapters/local-blob-store.ts). Leave unset in production.
|
|
OPT_LOCAL_BLOB_DIR=./.opt-blobs
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Document intelligence / OCR (Azure) -- wired in code today:
|
|
# src/services/document-extraction-service.ts. Unset => extraction
|
|
# "not configured".
|
|
# ---------------------------------------------------------------------------
|
|
DOC_INTELLIGENCE_ENDPOINT=https://<resource>.cognitiveservices.azure.com
|
|
DOC_INTELLIGENCE_KEY=change-me
|
|
DOC_INTELLIGENCE_API_VERSION=2024-11-30
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Customer DB-grant encryption -- wired in code today:
|
|
# /api/connections/db-grant
|
|
# ---------------------------------------------------------------------------
|
|
# 32-byte key, AES-GCM. Encrypts customer-supplied read-only connection strings
|
|
# at rest.
|
|
GRANT_ENC_KEY=change-me-32-byte-key
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# External write-back targets
|
|
# ---------------------------------------------------------------------------
|
|
# Odoo base URL for the bills/write-back adapter.
|
|
ODOO_BASE_URL=https://<your-odoo-host>
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Email -- Resend (documented target, docs/08; no Resend call site found in
|
|
# this pass -- treat as not-yet-implemented, not just unconfigured)
|
|
# ---------------------------------------------------------------------------
|
|
RESEND_API_KEY=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Embedded analytics (documented target, docs/08; no call site found in this
|
|
# pass)
|
|
# ---------------------------------------------------------------------------
|
|
METABASE_SITE_URL=
|
|
METABASE_SECRET_KEY=
|
|
NOCODB_BASE_URL=
|
|
NOCODB_API_TOKEN=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Test-only (tests/p0 real-infra suite; not needed to run the app)
|
|
# ---------------------------------------------------------------------------
|
|
# ST0RE_TEST_TENANT_ID=
|