# apollo-cloud/ — the Apollo website (apollo.etcos.ca)

> **This folder is the single source of truth for the Apollo website.**
> Everything served at `apollo.etcos.ca` lives here and nowhere else. It is the
> unit of deployment and the unit of pull-request review — change the site by
> changing this folder, then deploy this folder. (The old standalone `docs/`
> tree was folded into here on 2026-05-28 and deleted to remove duplication.)

The single Firebase Hosting bundle that serves **both** the read-only
opportunity pipeline **and** the explainer / architecture / roadmap docs.
Everything is gated behind Microsoft Entra SSO (per DEC-011, operator's
directive 2026-05-28).

## Managing this folder (deploys & PRs)

- **One folder = the website.** Anything under `apollo-cloud/` is shipped to
  Firebase Hosting. Nothing outside it is.
- **Deploy:** run `./apollo-cloud/deploy.sh` (wraps the scoped Firebase command
  below). Hosting-only — never touches Firestore rules or Cloud Functions.
- **PRs:** a change is "a website change" if and only if it touches this folder.
  `.github/CODEOWNERS` routes review of `apollo-cloud/**` accordingly, so a PR
  scoped to the site is easy to spot and review in isolation.
- **`firebase.json`** (repo root) pins `hosting.public` to `apollo-cloud`, so the
  folder name is load-bearing — rename only by updating that path too.

## Pages

| Path | Purpose | Built from |
|---|---|---|
| `/` | Sign-in gate + opportunity pipeline list + per-OPP detail (SPA) | `index.html` + `apollo-cloud.js` |
| `/about.html` | Apollo overview · architecture · skills · MCPs · Phase-1 punch list | `about.html` |
| `/roadmap.html` | Phase timeline (v0 done, v1 wrap-up, Phase 2 deferred) | `roadmap.html` |
| `/gap-analysis.html` | MCP gap analysis (shipped / Wave-1 / deferred / dropped) | `gap-analysis.html` |
| `/telemetry.html` | Run metrics + cost telemetry (demo data today) | `telemetry.html` |
| `/404.html` | Not-found fallback | static |

## Auth model

Every page enforces sign-in client-side. The hard server-side enforcement is
in `functions/index.js` (blocking functions) + `firestore.rules`.

- **SPA root (`/`)** — `apollo-cloud.js` calls `signInWithPopup(microsoft.com)`
  and only shows `#app` after `onAuthStateChanged` sees a valid
  `@etcorp.ca` + `email_verified` + `provider=microsoft.com` user. The new
  topnav appears alongside.
- **Docs pages** — Each `*.html` other than `/` has `<body style="visibility:
  hidden">` and imports `/auth-gate.js`. The gate initializes Firebase Auth,
  waits for auth state, and either reveals the body (signed in) or redirects
  to `/?from=<current path>` (the SPA then bounces back after sign-in).
- **`auth-gate.js`** also mounts a user chip + Sign-out button into any
  element with `id="auth-slot"` (we put one in every docs-page topbar).
- **Localhost** — All auth checks are relaxed when `hostname === localhost`
  so the bundle renders during local development without Firebase.

## Local preview

```bash
# Serve the static bundle (no auth, just rendering check)
cd apollo-cloud && python3 -m http.server 8080
open http://localhost:8080/about.html
```

This is the only preview server now — the old `docs/` tree (served on :8090)
was deleted when its pages were folded into this folder.

The `LiveDoc` viewer/editor inside `/about.html` will look for the Apollo
workbench BFF on `localhost:8000` for the live skill/MCP content. Start it
with `PORT=8000 apollo-web` in a separate terminal. On `localhost` the Edit
buttons are live; on the deployed site they're visible but disabled with a
"run locally to edit" tooltip. Without the BFF the cards still render — they
just show a "run locally to load" placeholder.

## Deploy to Firebase Hosting

```bash
# One command — from anywhere in the repo
./apollo-cloud/deploy.sh

# …which is just the scoped Firebase command:
firebase deploy --only hosting:apollo --project etc-pinnacle-os
```

That alone is enough to push the new bundle to the existing
`https://apollo-etcos.web.app` hosting site. To serve at the custom domain
`apollo.etcos.ca`:

1. **Firebase Console → Hosting → Add custom domain** on the `apollo-etcos`
   site. Enter `apollo.etcos.ca`.
2. Add the verification TXT and CNAME records Firebase shows you to the
   `etcos.ca` zone (Cloud DNS or wherever the zone is hosted). Wait for
   propagation (5–30 min).
3. The first request to `apollo.etcos.ca` may show a brief Firebase landing
   page while the cert provisions (~15 min).

For sign-in to actually work, the **manual Firebase Console steps from
DEC-011** must be done first. See `functions/README.md` in the repo root for
the step-by-step list. They are unchanged by this merge.

## Files in this directory

- `index.html` — SPA shell (sign-in gate + topbar w/ topnav + pipeline render)
- `apollo-cloud.js` — Firebase Auth + Firestore reads + opportunity rendering
- `firebase-config.js` — public Firebase config + Entra tenant ID + scopes
- `auth-gate.js` — client-side sign-in enforcement for the docs pages
- `about.html` — docs index (architecture, skills, MCPs, Phase-1 punch list)
- `roadmap.html`, `gap-analysis.html`, `telemetry.html` — supporting docs
- `404.html` — SPA fallback (rewrites in `firebase.json` ensure deep links work)
- `deploy.sh` — one-command scoped hosting deploy
- `brand/` — logo + topo-pattern assets

## What is NOT served from this bundle

- Skill SKILL.md content + local MCP READMEs — those live in the repo and
  are only readable when the workbench BFF is running locally. The
  `/about.html` page renders a "run locally" placeholder in cloud mode.
- The workbench UI (`prototypes/ui/06-analyst-workbench.html`) — that's a
  development tool, not for sharing externally. Run it via `apollo-web`.
