From cb50fc50265285382941d6b01a5dd53b14bb2b40 Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar Date: Mon, 18 May 2026 22:08:05 +0200 Subject: [PATCH] =?UTF-8?q?chore(domain):=20yourplatform.com=20=E2=86=92?= =?UTF-8?q?=20breakpilot.com?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the platform-domain decision (2026-05-18) to every README, workflow, and config in this repo. 7 files updated. Refs: M1.1 --- .gitea/workflows/release.yaml | 8 +++--- CHANGELOG.md | 1 + CONTRIBUTING.md | 2 +- IMPLEMENTATION_PLAN.md | 48 +++++++++++++++++------------------ INFRASTRUCTURE.md | 26 +++++++++---------- PLATFORM_ARCHITECTURE.md | 30 +++++++++++----------- PRODUCT_INTEGRATION_SPEC.md | 38 +++++++++++++-------------- README.md | 6 ++--- 8 files changed, 80 insertions(+), 79 deletions(-) diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml index 80c7348..58a629a 100644 --- a/.gitea/workflows/release.yaml +++ b/.gitea/workflows/release.yaml @@ -11,7 +11,7 @@ jobs: runs-on: docker environment: name: production # Gitea Environments — requires sign-off per branch protection - url: https://yourplatform.com + url: https://breakpilot.com steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } @@ -22,7 +22,7 @@ jobs: - name: verify stage soak (>= 24h on this image) run: | - IMG=registry.yourplatform.com/${{ github.event.repository.name }}:env-stage + IMG=registry.breakpilot.com/${{ github.event.repository.name }}:env-stage SOAK_SECONDS=$(orca image-age --env=stage --image $IMG) if [ "$SOAK_SECONDS" -lt 86400 ]; then echo "Stage soak only $SOAK_SECONDS s, < 24h. Aborting." @@ -34,12 +34,12 @@ jobs: - name: re-tag image as semver + env-prod uses: docker/login-action@v3 with: - registry: registry.yourplatform.com + registry: registry.breakpilot.com username: ${{ secrets.REGISTRY_USER }} password: ${{ secrets.REGISTRY_PASS }} - run: | - IMG=registry.yourplatform.com/${{ github.event.repository.name }} + IMG=registry.breakpilot.com/${{ github.event.repository.name }} docker pull $IMG:env-stage docker tag $IMG:env-stage $IMG:v${{ steps.v.outputs.version }} docker tag $IMG:env-stage $IMG:env-prod diff --git a/CHANGELOG.md b/CHANGELOG.md index 7804e26..aa6af5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Generated section is appended on release tag via `git-cliff` (see `.gitea/workfl - ### Changed +- chore(domain): yourplatform.com → breakpilot.com - ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d54d1a5..3ad8852 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,4 +86,4 @@ When reviewing, check in this order: ## Questions -`#engineering` channel · `oncall@yourplatform.com` · or open a PR with a `[WIP]` prefix and ask in the description. +`#engineering` channel · `oncall@breakpilot.com` · or open a PR with a `[WIP]` prefix and ask in the description. diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index 5595548..573b0cc 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -120,8 +120,8 @@ Three Orca clusters, all on the same hardware until volume justifies separation: Domain pattern: - dev: `*.localhost` (mkcert) -- stage: `*.stage.yourplatform.com` -- prod: `*.yourplatform.com` +- stage: `*.stage.breakpilot.com` +- prod: `*.breakpilot.com` ### 1.9 Observability + audit - **SigNoz** (already running at `signoz.meghsakha.com`) for traces, logs, metrics. Every service ships OTel SDK from day one. @@ -172,12 +172,12 @@ Every place where a future flag would gate behaviour MUST flow through a single - **Repos:** `platform/orca-platform` - **Deliverables:** - **PowerDNS Authoritative** on `vm-edge` (Orca-managed). PostgreSQL backend on same VM (small; ~100 records). - - At the registrar (Benjamin's account): set `ns1.yourplatform.com` and `ns2.yourplatform.com` glue records pointing at vm-edge public IP; delegate the domain to those NS. - - Zone file committed in `orca-platform/dns/yourplatform.com.zone`; Orca syncs into PowerDNS on apply. - - Records: apex `yourplatform.com`, wildcards `*.yourplatform.com` + `*.stage.yourplatform.com`, plus `auth.`, `erp.`, `mcp.`, `cdn.`, `mail.`, `ns1.`, `ns2.`, SPF/DKIM/DMARC TXT records (for M3.2). + - At the registrar (Benjamin's account): set `ns1.breakpilot.com` and `ns2.breakpilot.com` glue records pointing at vm-edge public IP; delegate the domain to those NS. + - Zone file committed in `orca-platform/dns/breakpilot.com.zone`; Orca syncs into PowerDNS on apply. + - Records: apex `breakpilot.com`, wildcards `*.breakpilot.com` + `*.stage.breakpilot.com`, plus `auth.`, `erp.`, `mcp.`, `cdn.`, `mail.`, `ns1.`, `ns2.`, SPF/DKIM/DMARC TXT records (for M3.2). - Wildcard TLS via Let's Encrypt **DNS-01 against PowerDNS** (Lego's `--dns=pdns` provider); ACME credentials in Infisical at `/prod/orca-proxy/PDNS_API_KEY`. - Orca-Proxy reloads the cert via watch on the secret file; renewal cron runs at 02:00 daily. -- **Acceptance:** `dig @1.1.1.1 anything.yourplatform.com` returns an answer; `curl https://anything.yourplatform.com` returns 404 from Orca-Proxy (no TLS error). +- **Acceptance:** `dig @1.1.1.1 anything.breakpilot.com` returns an answer; `curl https://anything.breakpilot.com` returns 404 from Orca-Proxy (no TLS error). - **Tests:** ACME renewal dry-run; PowerDNS zone-diff check in CI; reach via stage and prod subdomains; cert expiry page wired to SigNoz alert. - **Gate:** standard + manual DNS-delegation check by both founders (irreversible from registrar side without 24–48h propagation) - **Effort:** M (was S — registrar delegation + PowerDNS adds setup time vs. Cloudflare) @@ -210,7 +210,7 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M1.3 — Backups, monitoring, on-call - **Depends on:** M1.2 - **Repos:** `platform/orca-platform` -- **Deliverables:** backup cron per VM per `INFRASTRUCTURE.md §3` (Postgres pg_dump, MinIO bucket replication); SigNoz OTel collector running on every VM; alert routing to `oncall@yourplatform.com`; restore runbook in `platform/docs/runbooks/restore.md`. +- **Deliverables:** backup cron per VM per `INFRASTRUCTURE.md §3` (Postgres pg_dump, MinIO bucket replication); SigNoz OTel collector running on every VM; alert routing to `oncall@breakpilot.com`; restore runbook in `platform/docs/runbooks/restore.md`. - **Acceptance:** restore drill on stage succeeds (script in `platform/orca-platform/scripts/restore-drill.sh`); SigNoz shows traces from a synthetic request. - **Tests:** disaster-recovery exercise per failure scenario in `INFRASTRUCTURE.md §10` — at least Scenarios A, B, F validated on stage. - **Gate:** standard + manual sign-off @@ -219,7 +219,7 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M2.1 — Keycloak deployment - **Depends on:** M1.2, M1.3 - **Repos:** `platform/orca-platform` -- **Deliverables:** Keycloak 26 on `vm-identity`, Postgres backing store on `vm-control`, exposed at `auth.yourplatform.com` and `auth.stage.yourplatform.com`. Realm import file in `orca-platform/keycloak/realm-export.json` (committed, source-of-truth). +- **Deliverables:** Keycloak 26 on `vm-identity`, Postgres backing store on `vm-control`, exposed at `auth.breakpilot.com` and `auth.stage.breakpilot.com`. Realm import file in `orca-platform/keycloak/realm-export.json` (committed, source-of-truth). - **Acceptance:** master admin login works; realm `breakpilot-prod` exists in both envs. - **Tests:** automated realm-state diff in CI (`kcadm` against checked-in export). - **Gate:** standard + security checklist @@ -247,20 +247,20 @@ Every place where a future flag would gate behaviour MUST flow through a single - **Depends on:** M0.3 (needs DNS records under our control), M3.1 - **Repos:** `platform/orca-platform` - **Deliverables:** - - **Stalwart** on `vm-control` (Orca-managed); reachable at `mail.yourplatform.com`. - - DNS records added to the zone in M0.3: `mail` A record, MX → mail, SPF (`v=spf1 mx -all`), DKIM (Stalwart-generated public key), DMARC (`p=quarantine; rua=mailto:dmarc@yourplatform.com`), reverse DNS (PTR) configured at the cloud provider for the vm-control public IP — coordinate with vm-edge since outbound mail must egress from a host with a clean PTR. + - **Stalwart** on `vm-control` (Orca-managed); reachable at `mail.breakpilot.com`. + - DNS records added to the zone in M0.3: `mail` A record, MX → mail, SPF (`v=spf1 mx -all`), DKIM (Stalwart-generated public key), DMARC (`p=quarantine; rua=mailto:dmarc@breakpilot.com`), reverse DNS (PTR) configured at the cloud provider for the vm-control public IP — coordinate with vm-edge since outbound mail must egress from a host with a clean PTR. - SMTP submission service account per platform sender: `noreply@`, `oncall@`, `support@`, `billing@`, `dmarc@`. - Outbound queue and bounce handler; failed deliveries surface as audit events. - Webhook receiver at `/inbound/postmaster` for bounce/complaint feedback loops (Gmail FBL, MS SNDS). - **IP warming plan**: write a `platform/docs/runbooks/email-warming.md` documenting the 4–8 week ramp from low daily volumes; first 2 weeks of trial nudges (M12.2) explicitly throttled. -- **Acceptance:** test email from `noreply@yourplatform.com` to `parnerkarsharang@gmail.com` lands in inbox (not spam) on day 1; SPF/DKIM/DMARC all "pass" in Gmail's "show original" view; mail-tester.com score ≥ 9/10. +- **Acceptance:** test email from `noreply@breakpilot.com` to `parnerkarsharang@gmail.com` lands in inbox (not spam) on day 1; SPF/DKIM/DMARC all "pass" in Gmail's "show original" view; mail-tester.com score ≥ 9/10. - **Tests:** automated daily mail-tester check (failure pages on-call); bounce-handling integration test. - **Gate:** standard + security checklist + manual deliverability sign-off (DKIM keys are load-bearing) - **Effort:** L (deliverability tuning is the long tail) **Phase 0 exit criteria:** - Stage cluster boots cold from cron-driven nightly stop/start using only `INFRASTRUCTURE.md §5` ordering. -- A synthetic HTTPS request to `https://hello.stage.yourplatform.com` reaches a stub container. +- A synthetic HTTPS request to `https://hello.stage.breakpilot.com` reaches a stub container. - Restore drill on stage Postgres succeeds end-to-end. --- @@ -300,7 +300,7 @@ Every place where a future flag would gate behaviour MUST flow through a single - **Depends on:** M2.2, M4.3, M0.3 - **Repos:** `platform/portal`, `platform/design-tokens` - **Deliverables:** Next.js 15 app on `vm-control`; middleware reads `Host` → extracts slug → calls Tenant Registry `GET /tenants?slug=` → injects tenant context; Keycloak OIDC login; logout; `design-tokens` package consumed by portal. -- **Acceptance:** visiting `https://acme.stage.yourplatform.com` redirects to Keycloak; after login, user lands on `/acme/dashboard` (empty page) with valid session. +- **Acceptance:** visiting `https://acme.stage.breakpilot.com` redirects to Keycloak; after login, user lands on `/acme/dashboard` (empty page) with valid session. - **Tests:** Playwright e2e: login + logout for an existing test tenant. - **Gate:** standard - **Effort:** M @@ -317,14 +317,14 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M5.3 — Playwright e2e harness - **Depends on:** M5.2 - **Repos:** `platform/portal` -- **Deliverables:** Playwright config that runs against `stage.yourplatform.com` post-deploy; CI job `e2e-stage` triggered after stage deploy; failure pages on-call. +- **Deliverables:** Playwright config that runs against `stage.breakpilot.com` post-deploy; CI job `e2e-stage` triggered after stage deploy; failure pages on-call. - **Acceptance:** breaking change to login is caught in CI within 10 min of merge. - **Tests:** the suite itself. - **Gate:** standard - **Effort:** S **Phase 1 exit criteria:** -- A tenant created via `POST /tenants` results in a working login flow at `.stage.yourplatform.com`. +- A tenant created via `POST /tenants` results in a working login flow at `.stage.breakpilot.com`. - All Phase 1 routes have a passing Playwright spec running on every stage deploy. --- @@ -354,7 +354,7 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M6.3 — CERTifAI: manifest + integration assets - **Depends on:** M6.2 - **Repos:** `benjamin_boenisch/certifai` -- **Deliverables:** `product.manifest.yaml` per `PRODUCT_INTEGRATION_SPEC.md §10` published to `cdn.yourplatform.com`; OpenAPI 3.1 spec; `/v1/health`, `/v1/usage`, `/v1/tenants/:id/export`, `DELETE /v1/tenants/:id/data`, `POST /v1/tenants/demo/reset`; web component `certifai-dashboard` per §5.A. +- **Deliverables:** `product.manifest.yaml` per `PRODUCT_INTEGRATION_SPEC.md §10` published to `cdn.breakpilot.com`; OpenAPI 3.1 spec; `/v1/health`, `/v1/usage`, `/v1/tenants/:id/export`, `DELETE /v1/tenants/:id/data`, `POST /v1/tenants/demo/reset`; web component `certifai-dashboard` per §5.A. - **Acceptance:** CERTifAI appears in the portal catalog; subscribed tenants can open it from the dashboard. - **Tests:** contract test that manifest validates against schema; web component renders inside portal shadow-DOM host. - **Gate:** standard @@ -391,7 +391,7 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M8.1 — ERPNext deployment - **Depends on:** M1.2, M2.1 - **Repos:** `platform/orca-platform` -- **Deliverables:** Frappe + ERPNext on `vm-control` (separate Postgres database from tenant_registry — see `INFRASTRUCTURE.md` RISK-1); reached at `erp.yourplatform.com`; Keycloak OIDC; IP-restricted at Orca-Proxy. +- **Deliverables:** Frappe + ERPNext on `vm-control` (separate Postgres database from tenant_registry — see `INFRASTRUCTURE.md` RISK-1); reached at `erp.breakpilot.com`; Keycloak OIDC; IP-restricted at Orca-Proxy. - **Acceptance:** us login works; a Customer record can be created manually. - **Tests:** smoke test for OIDC; backup of Frappe filestore validated. - **Gate:** standard + manual sign-off (touches `vm-control` resources) @@ -489,7 +489,7 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M12.2 — Trial lifecycle cron + emails - **Depends on:** M12.1, M3.2 (Stalwart must be deliverability-clean) - **Repos:** `platform/tenant-registry` -- **Deliverables:** scheduler in tenant-registry that runs day-7/12/14 emails; status transitions trial → active (on payment) or trial → frozen → archived; SMTP via Stalwart at `mail.yourplatform.com:587`; sender `noreply@yourplatform.com`; HTML + plaintext templates committed under `tenant-registry/templates/email/`; List-Unsubscribe headers per RFC 8058. +- **Deliverables:** scheduler in tenant-registry that runs day-7/12/14 emails; status transitions trial → active (on payment) or trial → frozen → archived; SMTP via Stalwart at `mail.breakpilot.com:587`; sender `noreply@breakpilot.com`; HTML + plaintext templates committed under `tenant-registry/templates/email/`; List-Unsubscribe headers per RFC 8058. - **Acceptance:** in a time-warped stage test (script that advances `trial_ends_at`), all transitions fire in order and all three emails land in Gmail inbox. - **Tests:** integration test with time injection; deliverability spot-check at each release. - **Gate:** standard @@ -498,7 +498,7 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M13.1 — Demo tenant seeding - **Depends on:** M6.3, M7.2 - **Repos:** `platform/seed-data` -- **Deliverables:** per-product fixture archives (`certifai/seed-v1.tar.gz`, `compliance/seed-v1.tar.gz`); publishing pipeline to `cdn.yourplatform.com`; `catalog.demo.seed_data_url` populated in product manifests. +- **Deliverables:** per-product fixture archives (`certifai/seed-v1.tar.gz`, `compliance/seed-v1.tar.gz`); publishing pipeline to `cdn.breakpilot.com`; `catalog.demo.seed_data_url` populated in product manifests. - **Acceptance:** calling `POST /v1/tenants/demo/reset` on either product restores fixtures. - **Tests:** integration test asserts fixture state after reset. - **Gate:** standard @@ -508,7 +508,7 @@ Every place where a future flag would gate behaviour MUST flow through a single - **Depends on:** M2.2, M13.1 - **Repos:** `platform/portal`, `platform/tenant-registry` - **Deliverables:** demo tenant created in stage and prod with `kind=demo, status=demo`; SALES_REP role usable; backstage routes restricted to `/backstage/leads` and `/backstage/demo`; demo tenant audit events tagged `{"demo": true}` and hidden from real-tenant audit views. -- **Acceptance:** sales rep logs in at `demo.yourplatform.com`, walks both products live, [Request Trial] modal creates a CRM Lead with `sales_owner = the rep`. +- **Acceptance:** sales rep logs in at `demo.breakpilot.com`, walks both products live, [Request Trial] modal creates a CRM Lead with `sales_owner = the rep`. - **Tests:** Playwright e2e for the sales walk-through. - **Gate:** standard + security checklist (SALES_REP guardrail enforcement is the load-bearing piece) - **Effort:** M @@ -543,7 +543,7 @@ Every place where a future flag would gate behaviour MUST flow through a single **Phase 4 exit criteria:** - Every flow P1–P16 from `PLATFORM_ARCHITECTURE.md` has a passing Playwright spec. - Stage runs a full lifecycle: sign-up trial → convert → use → cancel → offboard, in an automated nightly job. -- We can hand a prospect a real demo using `demo.yourplatform.com`. +- We can hand a prospect a real demo using `demo.breakpilot.com`. --- @@ -581,8 +581,8 @@ Every place where a future flag would gate behaviour MUST flow through a single ### M17.1 — MCP servers (Enterprise) - **Depends on:** M6.3, M7.2 - **Repos:** `benjamin_boenisch/certifai`, `benjamin_boenisch/breakpilot-compliance` -- **Deliverables:** MCP endpoints per `PRODUCT_INTEGRATION_SPEC.md §10` `mcp:` block; gated on `plan == enterprise`; routed via `mcp.yourplatform.com`. -- **Acceptance:** Claude Code can connect to `mcp.yourplatform.com/certifai` with a service token and call `list_ai_agents`. +- **Deliverables:** MCP endpoints per `PRODUCT_INTEGRATION_SPEC.md §10` `mcp:` block; gated on `plan == enterprise`; routed via `mcp.breakpilot.com`. +- **Acceptance:** Claude Code can connect to `mcp.breakpilot.com/certifai` with a service token and call `list_ai_agents`. - **Tests:** MCP contract test using `mcp-cli`. - **Gate:** standard + security checklist - **Effort:** L @@ -703,7 +703,7 @@ That's 18 milestones. With one full-time agent and standard human review pacing, - ~~Cloudflare account ownership~~ → not used; DNS is self-hosted via PowerDNS on vm-edge (M0.3). Registrar account (Benjamin's) still needs documented 2FA recovery — see new DR item below. **Still open:** -- **CDN host** for `cdn.yourplatform.com`: self-hosted MinIO + Caddy on vm-edge is the OSS-aligned default; alternative is BunnyCDN (cheap, EU). Decide before M6.3 (manifest bundles + hero images). +- **CDN host** for `cdn.breakpilot.com`: self-hosted MinIO + Caddy on vm-edge is the OSS-aligned default; alternative is BunnyCDN (cheap, EU). Decide before M6.3 (manifest bundles + hero images). - **Cloud provider for port 25 outbound.** Stalwart needs unblocked port 25 to send mail. Hetzner blocks by default and requires a request to unblock with proof of intent + abuse contact; OVH and Scaleway unblock on request faster. Confirm with Benjamin which provider vm-control runs on. Block on M3.2 if port 25 is unblockable — fallback is sending via a different provider's IP with reverse DNS. - **Test data privacy.** The demo tenant must contain ONLY synthetic data — confirm seed pipeline strips real PII even if our test orgs accidentally seed from prod. - **Registrar + DNS bus-factor.** Document who owns the registrar account, who has 2FA recovery codes, and the procedure to update NS records without that person available. Goes in `platform/docs/runbooks/dr.md` before M0.3 ships. diff --git a/INFRASTRUCTURE.md b/INFRASTRUCTURE.md index 51a0814..1a3e0fc 100644 --- a/INFRASTRUCTURE.md +++ b/INFRASTRUCTURE.md @@ -41,7 +41,7 @@ Critical isolations preserved even at 4 VMs: ``` vm-edge (prod, m2.small 8 GB, public IP) ├── orca-proxy (Orca-managed; wildcard TLS terminator) - ├── powerdns-auth (Orca-managed; authoritative DNS for yourplatform.com) + ├── powerdns-auth (Orca-managed; authoritative DNS for breakpilot.com) ├── keycloak-26 (Orca-managed; JVM, ~1.5 GB heap) ├── postgres-keycloak (Orca-managed; dedicated PG instance for Keycloak only) ├── infisical (Orca-managed) @@ -57,7 +57,7 @@ vm-control (prod, m2.medium 16 GB) ├── frappe-hd (same bench as ERPNext) ├── mariadb (Orca-managed; for ERPNext) ├── redis-erpnext (Orca-managed) - └── stalwart-mail (Orca-managed; SMTP/IMAP/JMAP on mail.yourplatform.com) + └── stalwart-mail (Orca-managed; SMTP/IMAP/JMAP on mail.breakpilot.com) vm-data (prod, m2.medium 16 GB) ├── certifai-dashboard (Orca-managed) @@ -84,8 +84,8 @@ stage (stage, m2.small 8 GB, public IP) └── qdrant-stage (ephemeral, tiny corpus) Calls OUT to prod: - → auth.yourplatform.com (Keycloak token issuance, under stage client_id) - → mail.yourplatform.com (Stalwart SMTP, recipient filter forces +stage@ only) + → auth.breakpilot.com (Keycloak token issuance, under stage client_id) + → mail.breakpilot.com (Stalwart SMTP, recipient filter forces +stage@ only) → Polar SANDBOX webhook URL (NEVER prod Polar) → no calls to prod Postgres-app, MariaDB, MongoDB ``` @@ -107,8 +107,8 @@ stage (stage, m2.small 8 GB, public IP) ``` INTERNET │ - (yourplatform.com — authoritative on vm-edge PowerDNS; - stage.yourplatform.com — authoritative same zone) + (breakpilot.com — authoritative on vm-edge PowerDNS; + stage.breakpilot.com — authoritative same zone) │ ┌─────────────┴─────────────┐ │ │ @@ -143,15 +143,15 @@ stage (stage, m2.small 8 GB, public IP) └──────────────┘ Orca-Proxy routing (vm-edge, by Host header): - auth.yourplatform.com → 127.0.0.1:8443 (Keycloak, local on vm-edge) - erp.yourplatform.com → vm-control:8000 (ERPNext) [allowlist: our IPs only] - git.yourplatform.com → vm-edge:3000 (Gitea, local) [allowlist: our IPs only] - mail.yourplatform.com → vm-control:587 (Stalwart submission) [allowlist: VM internal only] - ns1.yourplatform.com → 127.0.0.1:53 (PowerDNS, local) - *.yourplatform.com → vm-control:3000 (customer portal) + auth.breakpilot.com → 127.0.0.1:8443 (Keycloak, local on vm-edge) + erp.breakpilot.com → vm-control:8000 (ERPNext) [allowlist: our IPs only] + git.breakpilot.com → vm-edge:3000 (Gitea, local) [allowlist: our IPs only] + mail.breakpilot.com → vm-control:587 (Stalwart submission) [allowlist: VM internal only] + ns1.breakpilot.com → 127.0.0.1:53 (PowerDNS, local) + *.breakpilot.com → vm-control:3000 (customer portal) Orca-Proxy routing (stage, by Host header): - *.stage.yourplatform.com → 127.0.0.1:3000 (stage portal — all subdomains route here) + *.stage.breakpilot.com → 127.0.0.1:3000 (stage portal — all subdomains route here) ``` --- diff --git a/PLATFORM_ARCHITECTURE.md b/PLATFORM_ARCHITECTURE.md index d9fc31c..0b5b06e 100644 --- a/PLATFORM_ARCHITECTURE.md +++ b/PLATFORM_ARCHITECTURE.md @@ -94,7 +94,7 @@ org_roles — [IT_ADMIN, USER, ...] roles within their org realm_roles — [customer] | [BREAKPILOT_ADMIN] | [SUPPORT_ENGINEER] | [SALES_REP] products — [certifai, compliance] entitlements (injected by protocol mapper) plan — starter | professional | enterprise -iss — https://auth.yourplatform.com/realms/breakpilot-prod +iss — https://auth.breakpilot.com/realms/breakpilot-prod ``` The `products` and `plan` claims are added by a Keycloak **protocol mapper** that reads live entitlements from the Tenant Registry at token issuance. Products do not need to call back to the registry on every request. @@ -108,12 +108,12 @@ Three distinct services. Clear separation of responsibility. ### 5a. Customer Portal **Technology:** Next.js 15 (new service) -**Deployed at:** `*.yourplatform.com` via Orca-Proxy wildcard routing +**Deployed at:** `*.breakpilot.com` via Orca-Proxy wildcard routing The front door for all customers and for us. Owns no business logic — it is a routing, auth, and UI layer. **Subdomain routing:** -- DNS wildcard `*.yourplatform.com` → Orca-Proxy +- DNS wildcard `*.breakpilot.com` → Orca-Proxy - Orca-Proxy reads `Host` header → routes all traffic to the portal container - Portal reads `Host` → extracts tenant slug → looks up Tenant Registry @@ -190,7 +190,7 @@ The front door for all customers and for us. Owns no business logic — it is a ### 5b. ERPNext **Technology:** Frappe + ERPNext (self-hosted via Orca) -**Access:** `erp.yourplatform.com` — us only (IP-restricted at Orca-Proxy) +**Access:** `erp.breakpilot.com` — us only (IP-restricted at Orca-Proxy) **Auth:** Keycloak OIDC — we log in with our existing accounts, no separate password ERPNext is our **business operations backbone**. We do not build CRM, invoicing, or HR — we configure ERPNext for these. @@ -262,7 +262,7 @@ api_keys portal-owned. tenant_id, product, scopes, name, ### 5d. Demo Tenant (Shared) -**Slug:** `demo` — reachable at `demo.yourplatform.com` +**Slug:** `demo` — reachable at `demo.breakpilot.com` **Status:** `demo` (never transitions; never billed) **Owner:** us (`BREAKPILOT_ADMIN` curates content; `SALES_REP` reads + logs in) @@ -299,7 +299,7 @@ all real-tenant flows work otherwise same flows, same code paths **Support flow:** - Customer submits ticket via `/[slug]/support/` (Frappe HD customer portal, embedded or linked) -- Agent (us) triages in Frappe HD agent UI at `erp.yourplatform.com` +- Agent (us) triages in Frappe HD agent UI at `erp.breakpilot.com` - If technical: agent clicks "Escalate to Engineering" → Frappe server script creates a Gitea issue in the relevant repo via Gitea REST API → issue URL stored on ticket - When Gitea issue is closed → Gitea webhook → Frappe HD → ticket marked "Resolved" @@ -341,11 +341,11 @@ GDPR and AI-Act compliance automation platform. After updates, tenant identity c ``` Orca-Proxy routing table: - auth.yourplatform.com → Keycloak - erp.yourplatform.com → ERPNext + Frappe HD (IP-restricted) - git.yourplatform.com → Gitea - secrets.yourplatform.com → Infisical (IP-restricted) - *.yourplatform.com → customer-portal (wildcard, Host → tenant) + auth.breakpilot.com → Keycloak + erp.breakpilot.com → ERPNext + Frappe HD (IP-restricted) + git.breakpilot.com → Gitea + secrets.breakpilot.com → Infisical (IP-restricted) + *.breakpilot.com → customer-portal (wildcard, Host → tenant) ``` **Services managed by Orca:** @@ -436,7 +436,7 @@ Data Stores ``` USER ORCA-PROXY PORTAL KEYCLOAK CUSTOMER IdP │ │ │ │ │ - │ acme.yourplatform.com │ │ │ │ + │ acme.breakpilot.com │ │ │ │ │───────────────────────►│ │ │ │ │ │ Host=acme.* │ │ │ │ │───────────────►│ │ │ @@ -671,7 +671,7 @@ Data Stores │ │ impersonated_by │ │ │ │ claim) │ │ │ │ │ - │ new tab: acme.yourplatform.com │ │ + │ new tab: acme.breakpilot.com │ │ │──────────────────────────────────────────────────────────►│ │ │ [orange banner] │ │ │ Impersonating │ @@ -749,7 +749,7 @@ Data Stores │ │ │ │ │ open Zoom with prospect, share screen │ │ │ - │ demo.yourplatform.com │ + │ demo.breakpilot.com │ │────────────────────────────────►│ │ │ │ │ Host: demo │ │ │ │ → slug = demo │ @@ -796,7 +796,7 @@ Data Stores ``` PROSPECT PORTAL TENANT REGISTRY ERPNEXT KEYCLOAK │ │ │ │ │ - │ yourplatform.com/start │ │ │ + │ breakpilot.com/start │ │ │ │──────────────►│ │ │ │ │ form: email, company, password │ │ │ │──────────────►│ │ │ │ diff --git a/PRODUCT_INTEGRATION_SPEC.md b/PRODUCT_INTEGRATION_SPEC.md index f5cb371..c04b426 100644 --- a/PRODUCT_INTEGRATION_SPEC.md +++ b/PRODUCT_INTEGRATION_SPEC.md @@ -279,7 +279,7 @@ Products that ship custom styling must respect the `theme` attribute and the pre ``` Product publishes a bundle at: - https://cdn.yourplatform.com/products/{name}/{version}/element.js + https://cdn.breakpilot.com/products/{name}/{version}/element.js Portal loads it lazily via dynamic import when the user navigates to /[tenant]/products/{name}. Portal caches the bundle URL per product version (declared in tenant_products.config). @@ -343,12 +343,12 @@ The product ships NO frontend code. The portal renders a generic management UI f │ CODE SAMPLES │ │ ──────────────────────────────────────────────────── │ │ [curl] [JS] [Python] │ -│ curl -X POST https://notetaker-api.yourplatform.com/v1 │ +│ curl -X POST https://notetaker-api.breakpilot.com/v1 │ │ -H "Authorization: ApiKey k_xxx" │ │ -H "X-Tenant: acme" │ │ -d '{...}' │ │ │ -│ DOCS ► developers.yourplatform.com/products/notetaker │ +│ DOCS ► developers.breakpilot.com/products/notetaker │ └──────────────────────────────────────────────────────────┘ ``` @@ -394,7 +394,7 @@ An MCP (Model Context Protocol) server exposes the product's capabilities as too ``` 1. ONE MCP server per product - Endpoint: https://mcp.{product}.yourplatform.com (or unified mcp.yourplatform.com/{product}) + Endpoint: https://mcp.{product}.breakpilot.com (or unified mcp.breakpilot.com/{product}) 2. Authentication via SCOPED API KEY Customer IT Admin generates API key in /[tenant]/settings/api-keys. @@ -438,7 +438,7 @@ Enterprise customers automatically get MCP enabled. Starter/Pro customers see "A ## 7. Documentation Contract -A product ships five required documents. They are published at `developers.yourplatform.com/products/{name}/`. +A product ships five required documents. They are published at `developers.breakpilot.com/products/{name}/`. ``` 1. README What does it do? Value prop in 200 words. @@ -763,16 +763,16 @@ product: vendor: breakpilot # we; future third-parties will use their slug contract_version: "1.0" product_version: "1.4.2" - repo: git.yourplatform.com/sharang/certifai + repo: git.breakpilot.com/sharang/certifai catalog: # Renders in /[tenant]/catalog and /backstage/products category: "AI Infrastructure" # AI Infrastructure | Compliance | Productivity | Security | Data tagline: "GDPR-compliant LLMs without leaving the EU" - hero_image: https://cdn.yourplatform.com/products/certifai/hero.png + hero_image: https://cdn.breakpilot.com/products/certifai/hero.png screenshots: - - https://cdn.yourplatform.com/products/certifai/dashboard.png - - https://cdn.yourplatform.com/products/certifai/agents.png + - https://cdn.breakpilot.com/products/certifai/dashboard.png + - https://cdn.breakpilot.com/products/certifai/agents.png pricing_summary: "From €X/seat/month — included on Professional and Enterprise plans" available_on_plans: [trial, professional, enterprise] # 'trial' opt-in for self-serve trial_days: 14 @@ -784,7 +784,7 @@ catalog: demo: supported: true # MUST be true unless explicitly waived - seed_data_url: https://cdn.yourplatform.com/products/certifai/demo/seed-v3.tar.gz + seed_data_url: https://cdn.breakpilot.com/products/certifai/demo/seed-v3.tar.gz reset_endpoint: /v1/tenants/demo/reset # called nightly by portal cron persona_hints: # for sales rep talk track - "GDPR officer at a 200-person SaaS" @@ -807,7 +807,7 @@ identity: frontend: type: interactive # interactive | widget | headless tag: certifai-dashboard - bundle_url: https://cdn.yourplatform.com/products/certifai/{version}/element.js + bundle_url: https://cdn.breakpilot.com/products/certifai/{version}/element.js bundle_size_kb: 380 routes: - path: / @@ -828,7 +828,7 @@ backend: mcp: enabled: true required_plan: enterprise - endpoint: https://mcp.yourplatform.com/certifai + endpoint: https://mcp.breakpilot.com/certifai tools: - name: list_ai_agents description: "Returns AI agents configured for the tenant" @@ -864,7 +864,7 @@ backup: retention_days: 30 infra: - image: registry.yourplatform.com/certifai-dashboard + image: registry.breakpilot.com/certifai-dashboard vm: vm-certifai replicas: 1 resource_limits: @@ -909,7 +909,7 @@ The example above shows an `interactive` product. Headless and widget products d frontend: type: widget tag: status-monitor-widget - bundle_url: https://cdn.yourplatform.com/products/status/{version}/widget.js + bundle_url: https://cdn.breakpilot.com/products/status/{version}/widget.js bundle_size_kb: 38 dimensions: width: 400 @@ -954,7 +954,7 @@ frontend: - language: curl title: "Create a session" snippet: | - curl -X POST https://notetaker-api.yourplatform.com/v1/sessions \ + curl -X POST https://notetaker-api.breakpilot.com/v1/sessions \ -H "Authorization: ApiKey k_xxx" \ -H "X-Tenant: acme" \ -d '{"audio_url": "...", "language": "en"}' @@ -963,7 +963,7 @@ frontend: snippet: | import requests requests.post( - "https://notetaker-api.yourplatform.com/v1/sessions", + "https://notetaker-api.breakpilot.com/v1/sessions", headers={"Authorization": "ApiKey k_xxx", "X-Tenant": "acme"}, json={"audio_url": "...", "language": "en"}, ) @@ -986,7 +986,7 @@ Products can call each other directly. Auth is via short-lived service tokens is 1. Compliance product needs to list AI agents for an AI Act assessment. 2. Compliance backend requests a service token: - POST https://auth.yourplatform.com/realms/breakpilot-prod/protocol/openid-connect/token + POST https://auth.breakpilot.com/realms/breakpilot-prod/protocol/openid-connect/token Body: grant_type=client_credentials client_id=compliance-svc client_secret= @@ -1135,7 +1135,7 @@ A product is "ready to ship to a customer" when all boxes are ticked. ☐ All tools tenant-scoped and audited ☐ Documentation - ☐ README published at developers.yourplatform.com/products/{name} + ☐ README published at developers.breakpilot.com/products/{name} ☐ API reference auto-generated and live ☐ Integration guide for customer IT ☐ Operational runbook for us @@ -1220,7 +1220,7 @@ Effort estimate: 3-5 weeks of focused work ``` - Design tokens package (@breakpilot/design-tokens) — needs to exist before web components ship - CDN for product bundles — pick provider (Hetzner Object Storage + Cloudflare?) -- MCP gateway — single mcp.yourplatform.com vs. per-product subdomains +- MCP gateway — single mcp.breakpilot.com vs. per-product subdomains - Third-party manifest signing — defer until first real third-party conversation - Inter-product event bus — explicitly deferred; service tokens cover the use cases for now - Contract testing — automate manifest + openapi validation in Gitea Actions diff --git a/README.md b/README.md index d716292..3fa13c7 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,8 @@ For IaC: list the make targets.}} | Env | URL | How | |---|---|---| | dev | `http://localhost:3000` | `make dev` | -| stage | `https://docs.stage.yourplatform.com` | auto on merge to `main` | -| prod | `https://docs.yourplatform.com` | manual: tag `vX.Y.Z` + sign-off | +| stage | `https://docs.stage.breakpilot.com` | auto on merge to `main` | +| prod | `https://docs.breakpilot.com` | manual: tag `vX.Y.Z` + sign-off | Rollback: `orca rollout undo docs --env={{env}}`. @@ -48,7 +48,7 @@ Rollback: `orca rollout undo docs --env={{env}}`. - Traces, logs, metrics: [SigNoz](https://signoz.meghsakha.com) — service name `docs` - Audit events: Tenant Registry `/audit` (Retraced-shape schema) -- On-call: `oncall@yourplatform.com` · runbook at `platform/docs/runbooks/docs.md` +- On-call: `oncall@breakpilot.com` · runbook at `platform/docs/runbooks/docs.md` ## Contributing