docs(phase10): canonical state audit, secrets inventory, production/security/launch readiness

Gate 1 — canonical state audit: this workstation's HEAD/origin/main and every claimed milestone
SHA (Phase 2A through 9.1) verified consistent; no stranded branches/tags on Gitea; full-history
secret scan clean (no rotation required); Phase 9.5 confirmed absent from canonical history
(pricing was given directly by Chase and used without it); second-PC reconciliation commands
provided since this session cannot see that machine.

Gate 3 — secrets: real inventory derived from process.env greps across every service (not
guessed); Infisical auth fixed (wrong domain was the actual root cause of Phase 9.1's failures —
the identity belongs to infisical.cedshomelab.com, not app.infisical.com) but no RootNode
Academy project exists there yet, contradicting this phase's own authorization — flagged for
Chase to create.

Gates 4-9/15-16 — production: verified, not assumed, that no dedicated server/Proxmox VM has
been provisioned (empty terraform.tfvars, no state file, placeholder group_vars/production.yml)
— IaC validated (tofu validate, ansible --syntax-check both clean) and left unexecuted per this
phase's own 'do not fake production deployment' instruction. rootnodeacademy.com confirmed live
(Cloudflare, real HTTPS) — the separate, not-RootNode-owned website; no Platform API subdomain
exists yet.

Gate 18 — security audit: full review against every regression suite rerun this phase; no
launch-critical defect found.

Gates 19/20 — full regression (131 checks: e2e-phase5b/5c/6f/7/8/9, content validation,
migrations, frontend build) and the Winter Break commerce rehearsal, both rerun clean against
current main.

Gates 10-14/21 — website integration, Winter Break pricing (99/49, real, Stripe-validated),
agreements/legal, tax, and refund policy all reviewed; legal text/tax/refund policy/dates/venue/
capacity correctly left as open owner decisions, not invented.

No application code changed this phase — audit/launch-prep only.
This commit is contained in:
2026-08-28 12:07:25 -05:00
parent a4c0058f8c
commit 0b2303a3e2
6 changed files with 634 additions and 80 deletions
+92 -80
View File
@@ -1,89 +1,101 @@
# Winter Break Camp — Launch Checklist
The single go/no-go list for opening the Winter Break Linux & Systems Foundations Camp
(`docs/WINTER_BREAK_CAMP_CURRICULUM_OPTIONS.md` Option A) to real public registration. Combines
`docs/WINTER_BREAK_CAMP_OPERATIONS.md`'s operational sequence with Phase 9's commerce
requirements into one checklist Chase can walk top to bottom. Nothing on this list is invented by
the platform — every unchecked item is a real decision or asset that has to come from Chase, the
legal reviewer, or Stripe, not from more code.
(`docs/WINTER_BREAK_CAMP_CURRICULUM_OPTIONS.md` Option A) to real public registration. Every
item is tagged **COMPLETE**, **BLOCKED**, **DECISION REQUIRED**, or **MANUAL OWNER ACTION** —
see `docs/PHASE10_LAUNCH_READINESS.md` for the full evidence matrix behind each tag. Nothing on
this list is invented by the platform — every non-COMPLETE item is a real decision, asset, or
piece of hardware that has to come from Chase, a legal reviewer, or Stripe, not from more code.
## Platform readiness — done, verified, ready whenever the business inputs below land
- [x] Offering, capacity, registration lifecycle, agreements — built and tested (Phase 7/8).
- [x] Offering pricing field, payment-provider abstraction, hosted checkout, verified webhook,
refund recording, abandoned-reservation reaper — built and tested against the deterministic
test provider (Phase 9).
- [x] Website registration + checkout + agreement + status-lookup contract — documented and
tested (`docs/WEBSITE_REGISTRATION_AND_CHECKOUT.md`).
- [x] Admin UI for offering pricing and per-registration payment/refund status.
- [x] `GET /api/admin/offerings/:id/readiness` reflects real configuration state, including the
new `price` and `payment_provider` checks.
- [x] Full Winter Break commerce rehearsal green end to end against a real, freshly-built stack
(`infra/scripts/drills/test-phase9-winter-camp-commerce.js`, 13/13): admin configuration,
minor and adult registration, checkout, payment success, webhook, enrollment activation, a
real classroom session, a real Lab task, failed payment, duplicate webhook, abandoned
checkout, and a last-seat race.
## Business decisions — Chase's call, not invented by this phase
- [ ] Real camp dates and duration.
- [ ] Real venue/location (or confirm fully online/remote).
- [ ] Real capacity (seat count).
- [x] Price and currency — **$399.00 USD launch tuition ("Founding Cohort"), $449.00 standard
retail, paid in full, no deposit/payment plan** — founder-approved per Chase directly
(Phase 9.1). Validated against real Stripe TEST mode at this exact amount. Not yet
reflected in a committed pricing document in this canonical repo (referenced but not found
— see `docs/PHASE9_1_STRIPE_TEST_VALIDATION.md` §1/§33); set directly on the real Winter
Break offering via `PATCH /api/admin/offerings/:id` when ready to open registration.
- [ ] Whether registration opens ahead of, or alongside, a specific marketing push.
- [ ] Refund policy in plain terms (the platform can RECORD any refund decision; it does not
decide policy — see `docs/OFFERING_AND_REGISTRATION_MODEL.md`'s "Payment and the commerce
boundary" section for what "record, never auto-cascade" means operationally).
## Legal review — required before any real family sees the agreement
- [ ] The actual participation/media/liability agreement text, reviewed by a real attorney
(`agreement_definitions.body_summary` is currently a plain-language placeholder only — see
`docs/STUDENT_GUARDIAN_DATA_MODEL.md`'s legal-review list).
- [ ] Jurisdiction-specific minor-consent requirements confirmed.
- [ ] Data-retention/deletion policy decided and, if needed, reflected in the agreement text.
- [ ] A decision on whether emergency-contact fields need additional encryption at rest.
## Payments
- [x] **Stripe TEST-mode validation** — a real Stripe TEST Checkout Session, a real TEST payment
at the actual $399.00 founding-cohort price, a genuine signed webhook, the existing
- [x] **Canonical repo reconciled** — COMPLETE. `docs/PHASE10_CANONICAL_STATE_AUDIT.md`: this
workstation's HEAD, Gitea's `origin/main`, and every claimed milestone SHA all verified
consistent. No stranded branches/tags on the remote.
- [ ] **Second-PC state reconciled** — DECISION REQUIRED (verification only, not a code
blocker). Gitea shows no evidence of stranded work, but this session cannot see the other
workstation directly — run the commands in `docs/PHASE10_CANONICAL_STATE_AUDIT.md` §1.3
there to positively confirm.
- [ ] **Secrets centralized (Infisical)** — MANUAL OWNER ACTION. No "RootNode Academy" project
exists yet in `infisical.cedshomelab.com` (verified, contradicts this being already
done) — create it with Development/Staging/Production environments. See `docs/
SECRETS_AND_INFISICAL.md` for the full secret inventory ready to migrate in.
- [ ] **Production server** — BLOCKED. Not purchased/provisioned — verified via empty
`terraform.tfvars`/no state file and placeholder `group_vars/production.yml`. See `docs/
PHASE10_PRODUCTION_DEPLOYMENT.md`.
- [ ] **Production VMs (rn-platform-01 / rn-lab-host-01)** — BLOCKED. Depends on the server above.
- [x] **Firewall/isolation (code)** — COMPLETE. `docs/PHASE10_SECURITY_AUDIT.md` — RFC1918
egress denial, mTLS wiring, firewall Ansible role all present and unchanged from Phase 4/
4.1; cannot be verified against a live host until one exists.
- [ ] **Production database** — BLOCKED. Depends on the server above. Migrations themselves
reconfirmed idempotent this phase (37/37, both a fresh apply and a same-DB restart).
- [x] **DNS (marketing site)** / [ ] **DNS (Platform API)** — PARTIAL. `rootnodeacademy.com` is
live and real (Cloudflare-fronted, confirmed this phase); no subdomain exists yet for the
Platform API itself — needs a real server first.
- [x] **HTTPS (marketing site)** / [ ] **HTTPS (Platform API)** — PARTIAL, same split as DNS.
- [x] **Monitoring (code)** — COMPLETE. `/healthz`/`/metrics` live and exercised in every
regression run this phase; deployment itself needs the production server.
- [x] **Backups (code)** / [ ] **Backups (executed)** — PARTIAL. Ansible `backup` role exists,
never run against a real host.
- [ ] **Restore test** — BLOCKED. Never executed — no target exists. A backup that has never
been restore-tested does not count as launch-ready.
- [x] **Stripe TEST validation** — COMPLETE. A real Stripe TEST Checkout Session, a real TEST
payment at the actual $399.00 price, a genuine signed webhook, the existing
registration→enrollment conversion, a real duplicate-delivery proof, a real automated
abandoned-checkout proof, and a real refund with the non-cascade rule reconfirmed — all
proven end to end in Phase 9.1. One real defect (webhook-event correlation) was found and
fixed as a direct result. See `docs/PHASE9_1_STRIPE_TEST_VALIDATION.md` for the full
evidence and reconciliation IDs. **This is TEST mode only — it does not authorize or imply
LIVE-mode readiness**, see the unchecked items below.
- [ ] Real Stripe account created/available (live mode).
- [ ] `STRIPE_SECRET_KEY`/`STRIPE_WEBHOOK_SECRET` (live values) provisioned into production
configuration only — see `docs/STRIPE_INTEGRATION_RUNBOOK.md`'s "Going live" section.
- [ ] At least one real, small, refundable test transaction run end to end in production before
opening registration publicly, then refunded.
- [ ] Recommended (not required — the test provider already validates the application logic):
one full rehearsal against Stripe's own TEST mode (fake cards, no real money) before
flipping to live credentials, per `docs/STRIPE_INTEGRATION_RUNBOOK.md`'s test-mode section.
## Website (separate repo, not RootNode-owned)
- [ ] rootnodeacademy.com's own registration/checkout form built against
`docs/WEBSITE_REGISTRATION_AND_CHECKOUT.md`. Not tracked or built in this repository — if
that repo becomes available to RootNode's own engineering effort, say so explicitly before
any code changes are made against it.
- [ ] The website's `INTEGRATION_SHARED_SECRET` provisioned into its OWN backend configuration
(never browser-reachable) — see `docs/WEBSITE_ENROLLMENT_INTEGRATION.md`'s "Production
secret handling."
- [ ] The website's success page built against the status-lookup polling pattern in
`docs/WEBSITE_REGISTRATION_AND_CHECKOUT.md` §6 — never derived from the redirect URL alone.
proven end to end in Phase 9.1 (`docs/PHASE9_1_STRIPE_TEST_VALIDATION.md`). One real
defect (webhook-event correlation) was found and fixed as a direct result.
- [ ] **Stripe LIVE configuration** — BLOCKED. Not configured, not attempted — requires Chase's
own Stripe account business/identity verification (only Chase can do this) plus real LIVE
credentials placed in Infisical (blocked on the missing project above), never invented or
substituted by this phase.
- [ ] **Live webhook configuration** — BLOCKED. Depends on LIVE credentials and a real HTTPS
Platform API endpoint, neither of which exist yet.
- [x] **Google Workspace** — COMPLETE. `[email protected]`, `gmail.send` scope,
domain-wide delegation — validated in Phase 5C (`docs/
RUNBOOK_GOOGLE_WORKSPACE_EMAIL.md`); deployment to production needs the real server.
- [x] **Website integration** — COMPLETE. Full contract tested end to end, including against
real Stripe. The website itself (separate repo, not RootNode-owned) is live and real;
this phase did not access or modify it.
- [x] **Winter Break price** — COMPLETE. **$399.00 launch ("Founding Cohort") / $449.00
standard reference, paid in full, no deposit, no payment plan** — founder-approved by
Chase directly, validated against real Stripe TEST mode at this exact amount.
- [ ] **Winter Break dates** — DECISION REQUIRED. Chase's call, not invented.
- [ ] **Venue** — DECISION REQUIRED. Chase's call (or confirm fully online/remote), not invented.
- [ ] **Capacity** — DECISION REQUIRED. Chase's call, not invented.
- [ ] **Agreements (legal text)** — BLOCKED. `agreement_definitions.body_summary` remains a
plain-language placeholder; no attorney-approved text exists for any required category
(program terms, guardian consent, participation waiver, acceptable-use/lab rules,
cancellation acknowledgment, privacy notice). See `docs/PHASE10_LAUNCH_READINESS.md` Gate
12 for the full taxonomy — none of it was authored or treated as approved by this phase.
- [ ] **Refund/cancellation policy** — DECISION REQUIRED. The platform's mechanical behavior
(record, never auto-cascade into registration/enrollment status) is real and proven
against actual Stripe money movement; the customer-facing POLICY text is Chase's decision.
- [ ] **Tax decision** — DECISION REQUIRED. No tax treatment is configured anywhere in this
codebase (Phase 9's own explicit "no complex tax automation" boundary) — this is not an
implicit "no tax owed" determination, it requires Chase or a professional to actually
decide.
- [ ] **Production offering** — BLOCKED. Cannot legitimately open registration until dates/
venue/capacity/agreements/refund policy/tax are all resolved — the mechanism itself
(`PATCH /api/admin/offerings/:id`, transition to `enrollment_open`) is ready the moment
they are.
- [ ] **Instructor assignment** — MANUAL OWNER ACTION. Mechanism ready
(`instructor_offerings`); Chase assigns the real instructor once the real offering exists.
- [x] **Roster process** — COMPLETE. Rehearsed end to end (classroom session, real Lab task,
instructor visibility) in this phase's dress rehearsal, 13/13.
- [x] **Student activation** — COMPLETE. Proven real twice — Phase 9.1's real-Stripe run and
this phase's deterministic rehearsal.
- [x] **Lab capacity (mechanism)** / [ ] **Lab capacity (real sizing)** — PARTIAL. Race-safe
capacity logic is proven; real-world capacity planning for actual concurrent students
needs the real server's actual specs, unknown until Gate "production server" resolves.
- [x] **Complete dress rehearsal** — COMPLETE (deterministic). 13/13 this phase, against
current `main`. Cannot yet be repeated against the REAL Winter Break offering because that
offering cannot legitimately open (dates/venue/capacity/agreements/policy/tax all pending).
## Final go/no-go
Registration should not open to the public until every box above is checked. The platform side
(first section) has been true since this phase shipped; everything else is a business, legal, or
external-team dependency this phase deliberately did not — and should not — invent on Chase's
behalf.
## PHASE 10 PARTIAL / WINTER BREAK LAUNCH BLOCKED
Registration must not open to the public until every BLOCKED and DECISION REQUIRED item above
is resolved. Every COMPLETE item has real evidence behind it, not a self-assessment — see
`docs/PHASE10_LAUNCH_READINESS.md`'s full matrix. **Even once every gate above passes, this
platform will not open registration on its own — that action requires Chase's explicit,
separate authorization, given directly, not inferred from a checklist being green.**