migrate ecomm session transcripts into ecomm/ (folder-per-session) + manifest

This commit is contained in:
2026-06-03 07:16:50 -07:00
parent 3713299f08
commit 31ef3a3be9
12 changed files with 1814 additions and 0 deletions
@@ -0,0 +1,134 @@
# SESSION-0010.0 — R03 Locations + flotilla secret-files + config-onboarding spec + wildcard-TLS wiring
**Date:** 2026-06-02
**Driver:** Ben (ben@wiggleverse.org)
**Repos touched:** `wiggleverse-ecomm` (impl, branch `r01-store-settings`),
`flotilla-core` (`main`), `rfc-app` (`main`), `wiggleverse-ecomm-bdd-release-planner-app`
(`main`), plus Claude memory.
**Outcome:** R03 Locations shipped (committed, unmerged); flotilla-core gained a
`secret-file` feature (v0.4.0, pushed) for TLS-cert delivery; config/secret
onboarding UX spec'd (not built); ohm/planner nginx wired to the wildcard cert
(pushed); the git/secrets working model was clarified across memory.
Transcript-honest per the engineering guide — wrong turns included.
---
## What happened (in order)
1. **"Build R03 — Locations (core)."** Read memory + the impl repo, grounded in OHM
(Location = embodied physical venue of the Commercial Relationship; the
last-active + set-primary invariants = Duty of Care / Dignity in Commerce).
GOTCHA: **OHM was unreachable from the sandbox** (`ohm.wiggleverse.org` DNS
no-answer) — grounded in the concepts already in memory + the SPEC link targets
instead, and flagged it for re-verification. Built the 4 dependency-free
scenarios (`13.07.0001/0002/0003/0006`): migration `0004_locations.sql`
(single-primary as a **partial unique index**), `app/locations.py` (mirrors
staff.py), seed of one primary "Main location", REST BFF + GraphQL
(`Store.locations` + add/update/setPrimary/delete), and a Locations admin UI.
Decision: filed under the existing **`settings`** section (no new section).
**46 tests** green (38 + 8); all four scenarios browser-verified (the OTC 60s
cooldown bit again — a curl smoke-test consumed the owner's code, worked around
by polling for a fresh `dev_code` then verifying via in-page fetch). SPEC → v0.5
(§9 + §5 rows), README + `/api/health`→R03. Commit `5b3e946` (unmerged).
2. **"I have the *.wiggleverse.org cert — command to load the key into the right
secret? It'll impact other apps. Huh, bdd.ecomm works fine."** Corrected two
misconceptions: a single-level wildcard does **NOT** cover the nested
`bdd.ecomm.wiggleverse.org` (two labels) — bdd works because of its *own* certbot
cert, grey-cloud; and **no app reads a cert from a secret today** (all use certbot
on the VM; flotilla had zero TLS code). Gave the safe `gcloud secrets … --data-file`
gesture but flagged there was no consumer.
3. **"Why not put the cert in a secret and have flotilla deploy it to nginx?"** →
honest reassessment: good idea, I'd been over-cautious. Walked the build-vs-buy
shape (renewal ownership turns on Origin-CA-vs-LE; cross-project secret access is
the real wrinkle; security is a wash). **"Build it into flotilla — go for it."**
4. **flotilla-core `secret-file` feature.** Discovered the two apps run *different*
flotilla generations (ohm = thin shim over flotilla-core; planner = bespoke
`planner_flotilla`) → built into **flotilla-core** (shared, future-facing).
Migration `010`, `registry.bind/list/unbind_secret_file`, `[[secret_file]]` in
`deployment.toml`, **phase 6 extended** (atomic root write via sudo, bytes over
stdin, zeroed + redacted, dedup'd reload, fail-stop), plan + a `secret-file` CLI
group (`bind`/`set`/`unbind`/`list`). 366 tests; ohm shim inherits the verb free.
5. **"How is it set up for other apps?"** Confirmed from code: secrets → `.env` only;
TLS entirely out-of-band (certbot). So secret-files is genuinely new flotilla
surface, not a switch-flip.
6. **"Add a UX to manage config + secrets, per app type, with provider instructions.
Stop using a Claude skill — make it deterministic. Spotify open-sourced something
— build or buy?"** Researched (web worked; only internal hosts fail DNS):
Spotify = **Backstage** (IDP framework, Scaffolder; secrets weak, 24 FTEs / 612
mo — too heavy); Infisical/Doppler solve *storage* (GCP SM already covers).
Verdict: **build** — the app-type-aware required-config + provider instructions is
bespoke. **"Spec the manifest schema and two verbs."** Wrote
`flotilla-core/docs/config-onboarding-spec.md` (manifest + `init` + `config
doctor` + seed `cloudflare-proxied-vm`/`wildcard-tls` manifests). Locked
decisions: PEM via **local file path**; `deploy` **gates on doctor by default**
with `--skip-config-check`, doctor also standalone.
7. **nginx wiring.** Rewired ohm (`ohm.wiggleverse.org.conf` — was the pre-certbot
template; now an explicit 80→443 vhost) and planner (`planner.conf` for
`rfc.wiggleverse.org`) to the wildcard at `/etc/ssl/{certs,private}/`. Committed
`34a65e0` (rfc-app) + `ddb27eb` (planner).
8. **/finalize → commit + push.** Committed the flotilla feature (`014c0f3`) + spec
(`cd729f1`). Ben: **"push the unpushed commits."** rfc-app + planner pushed
clean. **flotilla-core push REJECTED** — a parallel **PR #1** had merged a
*different* "v0.3.0" (deployment.toml scaffold + fail-closed `validate`) and
**tagged v0.3.0**.
- ⚠️ **Wrong turn:** rebased onto it; resolved the top-of-file `deployment_toml.py`
conflicts but **missed a third conflict region** (in `sync_to_registry`) and
`git add`+`--continue` committed it **with conflict markers** (broken code).
Caught it immediately (not pushed). Resolved properly (merged my secret-file
binding into their reconciling sync + extended the prune logic), **renumbered my
release 0.3.0 → 0.4.0** (0.3.0 was taken+tagged), back-filled a CHANGELOG stub
for their release, and **rebuilt clean linear history** (`git reset --soft`
no force, no broken intermediate). **394 tests** green (mine + theirs). Pushed
`b77dd7a`. No force-push anywhere; their PR untouched.
9. **"I don't want to push/merge myself — remove that guidance."** Found the rule
was **self-contradictory** in memory (engineering-pattern already said merge was
mine; ecomm files still called it "operator-only for Ben"). Fixed all of them.
Then **"remove that from working-preferences"** (don't duplicate the git rule
there) — removed it; canonical home is `wiggleverse-engineering-pattern`. Then
**"update engineering-pattern to match: operator only wants secrets; otherwise
Claude can do everything but lays out a plan and gets approval."** Settled model
recorded: **operator owns secrets only; everything else is Claude's to do, gated
by plan + approval for consequential actions; local/reversible work needs none.**
10. **"What's next?"** → recommended the **ohm wildcard-TLS cutover** (highest value
+ first real dogfood of secret-files). **"Go with it, but in a new session —
finalize this one."** Verified all repos clean/in-sync; set the ▶NEXT pointer in
memory. Wrote this transcript.
---
## State at wrap
| Repo | Branch | State |
|---|---|---|
| `wiggleverse-ecomm` | `r01-store-settings` | R03 committed `5b3e946`; unmerged (R01+auth+R02+GraphQL+R03 ride together) |
| `flotilla-core` | `main` | `b77dd7a` pushed — **v0.4.0** secret-files + onboarding spec |
| `rfc-app` | `main` | `34a65e0` pushed (ohm nginx → wildcard) |
| `…-bdd-release-planner-app` | `main` | `ddb27eb` pushed (rfc.wiggleverse.org nginx → wildcard) |
## Next session — the ohm wildcard-TLS cutover
1. **Decide cross-project secret access first** — one shared `*.wiggleverse.org`
secret + `secretAccessor` grants to each VM's SA, vs one copy per project.
2. Ben runs `flotilla secret-file set` with the cert key + fullchain (NO SECRETS:
his gesture; bytes never transit Claude).
3. Claude lays out the cutover step plan for approval, then deploys ohm.
4. Ben flips Cloudflare → Full(strict) + orange-cloud on `ohm` (Origin-CA cert only
validates behind the proxy — do cert+proxy together).
5. `certbot delete --cert-name ohm.wiggleverse.org`.
Then back to **R04 — Product create & lifecycle** (next ecomm release).
**Open follow-ups:** teach flotilla `validate` about `[[secret_file]]` refs;
migrate the planner off bespoke `planner_flotilla` onto flotilla-core; re-verify
R03 OHM citations when `ohm.wiggleverse.org` is reachable.