Files
session-history/0054/SESSION-0054.0-TRANSCRIPT-2026-06-01T03-24--2026-06-01T03-25.md
T

13 KiB
Raw Blame History

Session 0054.0 — Transcript

Date: 2026-06-01 Goal (as launched): walk the full engineering runbook end-to-end as a test run — fake-build a throwaway app and deploy it for real, then tear it down. Discover whether the runbook actually works for a brand-new app.

Outcome: The runbook's design+build half was walked for real on a throwaway URL-shortener (wiggle-snip): prototype → SPEC v0.0.1 → ROADMAP → standard-stack build with 14 green tests + a building Vite frontend + /api/health. The deploy half was NOT executed — at the deploy gate the operator redirected: don't deploy from this session, instead (a) hand off a reusable prompt for a future operator-driven deploy, and (b) use what we'd learned to scope a new launch-app skill suite that takes an engineer from "I want to build an app" to a verified pre-prod deploy. That suite was spec'd: wiggleverse/engineering/launch-app/SPEC.md v0.0.1 + ROADMAP.md, with flotilla-core extraction as the critical-path Slice 1. No cloud resources, Gitea repos, or deploys were created.

Scope-change / publication note (transcript-honest): this session began off the record. At the deploy gate the operator explicitly chose "don't publish a transcript" — correct for a throwaway deploy test. But the session then pivoted into real org-level tooling design (the launch-app spec), and the operator reversed the call: "the scope of this conversation changed, so let's do a proper transcript." Hence this file. The earlier off-the-record decision is recorded here precisely because it was reversed — the record shows the judgement, not a tidied version of it.

Timestamp caveat: the start-gesture claim (SESSION-PROTOCOL §"session start") was NOT run at the true session start — the session opened in the ecomm working dir as an off-the-record test and was elevated to a published transcript only at the end (the protocol's "claims its ID at publish time" path). The 03-24/03-25 stamps are the claim/finalize window; the actual work spanned roughly the preceding hour.


Pre-session state

  • No wiggle-snip anything existed. Working dir was ~/projects/wiggleverse/ecomm (an unrelated project); this session never touched ecomm.
  • The runbook of record: ~/projects/wiggleverse/engineering/README.md (the canonical handbook; ~/projects/wiggleverse/ENGINEERING-GUIDE.md is the now-superseded draft). Read in full this session.
  • scaffold-gcp-project skill present at ~/.claude/skills/scaffold-gcp-project/SKILL.md — the one existing cloud-foundation skill.
  • ohm-rfc-app-flotilla present — OHM's operator CLI, the template any new deployment's flotilla would fork from.

Plan

Walk the guide §1 lifecycle for a deliberately trivial app: idea → prototype (§2) → SPEC (§3) → ROADMAP (§7) → build on the standard stack (§4, §8) → deploy via flotilla (§8, §9) → verify /api/health → tear down. The app is a vehicle to exercise the pipeline, so it was chosen for minimal domain complexity and maximal stack coverage.

Turn-by-turn arc

Arc 1 — Choose the test app

Grounded in the guide first (read the engineering-pattern memory + handbook §1–§9). Proposed four candidates via AskUserQuestion (guestbook, deploy counter, link shortener, quote board), framed around which best exercises every layer (a migration + WAL write, an API, a Vite build, a health check) with least domain noise. Operator chose the link shortener — it earns a redirect route + slug generation without real complexity.

Arc 2 — Reconnaissance: is the runbook even tractable for a new app?

Before building, inspected ohm-rfc-app-flotilla. Key finding: flotilla is OHM-specific, not generic — its README says each deployment forks its own <deployment>-flotilla, and a generic library is a §19.2 candidate "once a second deployment exists." Confirmed the deploy shape matches the standard stack (plan.py/deploy.py run backend/.venv/bin/pip install + cd frontend && npm ci && npm run buildsystemctl restart → verify /api/health), but it is OHM-coupled in two spots: the pin.py hard rfc-app >= 0.2.3 floor and the audit.py rfc-app-lockfile target. Noted that this test run is itself the "second deployment" the guide predicted would justify extracting a generic flotilla.

Arc 3 — Prototype (guide §2)

Vibe-coded ~/projects/wiggleverse/wiggle-snip-prototype/prototype.py (stdlib-only http.server + sqlite). Wrong turn: left a nonsense expression for _ in rangeate(10) if False else range(10) in the slug minter; caught and cleaned to range(10) before running. Ran it and exercised every endpoint: health, shorten (201), redirect (302 + Location), unknown slug (404), bad URL (400), bad JSON (400), hit-counter increment. The proto's job was done the moment the contracts were describable (§2).

Arc 4 — SPEC + ROADMAP (guide §3, §7)

Matched the house style (numbered §, citable invariants, deferred-topics section) by reading rfc-app/SPEC.md first. Wrote wiggle-snip/SPEC.md v0.0.1 — invariants: opaque slugs (§3.1), no slug reuse (§3.3), fail-loud collision (§3.4), validate-before-store (§4.1), unknown-slug-is-404 (§5.1), health-reports-version (§6.1), forward-only schema (§2.1). Then ROADMAP.md, 5 slices with a next-session brief.

Arc 5 — Build on the standard stack (guide §4, §8)

Mirrored rfc-app/backend layout. Built backend/ (FastAPI, db.py migration runner cloned from rfc-app's shape, 001_init.sql, slug minter with an injected randomness seam for testability, main.py routes) + frontend/ (vanilla Vite). Wrong turns / friction:

  • A cd-in-compound Bash call and an rm -rf … & background call were both permission-denied; reworked to absolute paths + foreground.
  • FastAPI rejected the redirect route's RedirectResponse | JSONResponse union return type; fixed with response_model=None. 14 backend tests pass (incl. the collision-retry-then-fail-loud path and a slug-opacity check). Frontend npm run build produces dist/; lockfile committed (flotilla's npm ci needs it). Verified the full stack on one origin via curl: health reports version, homepage + assets served from dist/, shorten → 201, redirect → 302, unknown → 404. Added .gitea/ workflows/test.yml, README, .gitignore, VERSION.

Arc 6 — The deploy gate, and the first pivot

Presented the deploy gate honestly: a real deploy creates a billable GCP project + VM, real Gitea repos, and (per guide §6) a public transcript. Operator had earlier chosen "full real deploy," but at the trigger redirected: do NOT deploy from this session. Instead, produce a self-contained prompt for a fresh operator-driven session that uses scaffold-gcp-project + the runbook to deploy wiggle-snip and capture skill-improvement feedback. Also chose "don't publish" a transcript (off-the-record test). Delivered that prompt. Teardown (the planned final step) became moot — nothing was provisioned.

Arc 7 — Skill-scope question → the second pivot

Operator asked whether scaffold-gcp-project currently covers (a) asking about the app, (b) defining+validating topology, (c) all resource names/locations. Read the SKILL.md and answered precisely: it asks only for repo-name/org/billing/region/profile; it is explicitly "cloud foundation only," stops before the VM, validates only the project-id regex, and leaves topology + most resource names to the operator/flotilla. Identified the gap: the middle band between "cloud foundation scaffolded" and "app deployed" has no skill.

Arc 8 — Scope the launch-app suite, and decide its shape

Explored the full scope of a suite that takes "I want to build an app" → deployed (≥ pre-prod), for a technical-but-not-GCP-expert engineer. Read guide §10–§12 + the register-ohm.sh deployment record to ground the target topology and the full resource-name set. Surfaced two genuine forks via AskUserQuestion. Operator decided:

  • Milestone = PRE-PROD ONLY (no prod, no Stage-2 blue/green/canary). This collapses the target to a single disposable pre-prod env = topologically the §8 single-VM shape, and drops all of §10.6 from v1.
  • Extract flotilla-core (not fork-per-app) — the real fix the guide's §19.2/§11 "second deployment" trigger predicts.

Arc 9 — Write the suite's SPEC + ROADMAP, and the build prompt

Wrote wiggleverse/engineering/launch-app/SPEC.md v0.0.1 (orchestrator state machine, deployment.toml schema + fail-closed validation rules, per-phase-skill responsibilities, the flotilla-core extraction contract incl. its §7.3 "OHM still deploys" regression oracle, and the teaching/ safety invariants incl. the hard-secrets rule §8.3) + ROADMAP.md (5 slices, flotilla-core first, wiggle-snip as the dogfood fixture). Delivered a paste-ready prompt to kick off the Slice-1 build session. Updated agent memory (project notes for the suite + the fixture).

Arc 10 — Scope changed → produce this transcript

Operator: "the scope of this conversation changed, so let's do a proper transcript." Reversed the Arc-6 off-the-record call. Read SESSION-PROTOCOL, claimed 0054 via claim-session-id.sh, finalized + published this file.

Cut state (end of session)

  • ~/projects/wiggleverse/wiggle-snip — built + tested, NOT deployed. backend (FastAPI/SQLite-WAL/migration 0001_init//api/health), frontend (Vite→dist), 14 tests green, CI defined, SPEC.md v0.0.1, ROADMAP.md.
  • ~/projects/wiggleverse/wiggle-snip-prototype — throwaway proto.
  • ~/projects/wiggleverse/engineering/launch-app/SPEC.md v0.0.1 + ROADMAP.md (NEW; local working copies, not yet committed/PR'd into the wiggleverse/engineering repo — that's an operator gesture).
  • No GCP project, VM, Gitea repos, ADC change, or deploy. Nothing to tear down.
  • Two paste-ready prompts handed to the operator in-chat: (1) deploy wiggle-snip via scaffold-gcp-project + runbook; (2) build launch-app Slice 1 (flotilla-core extraction).

§19.2 / process candidates surfaced

  • flotilla-core extraction — the headline. flotilla is OHM-coupled (pin.py rfc-app floor, audit.py lockfile target, OHM names). This test run is the literal "second deployment" that justifies pulling the generic 9-phase engine into a reusable package + thin deployment.toml. Decided: do it (launch-app ROADMAP Slice 1). Regression oracle = OHM still deploys through the core (launch-app SPEC §7.3).
  • The scaffold-gcp-project → deploy gap — no skill owns topology definition/validation or the full resource-name set; launch-app SPEC §6.6 (define-deployment) + §6.7 (provision-vm) are the proposed fill.
  • scaffold-gcp-project should confirm, not assume, the standard stack (launch-app SPEC §6.5) — it currently has no app-intake interview.

What lands on the operator's plate

  • Decide whether to commit/PR the new engineering/launch-app/ SPEC+ROADMAP into wiggleverse/engineering (operator gesture).
  • When ready, run either handed-off prompt: deploy wiggle-snip to validate the runbook, or start the flotilla-core extraction (Slice 1).
  • Optional: fold a pointer to launch-app into the engineering guide's table of contents / §12 so it's discoverable.

Prompt the operator can paste into the next Claude Code session

Build the launch-app skill suite — Slice 1: extract flotilla-core.

Read first:
- Suite spec:    ~/projects/wiggleverse/engineering/launch-app/SPEC.md  (esp. §7 flotilla-core, §9 invariants, §10 out-of-scope)
- Suite roadmap: ~/projects/wiggleverse/engineering/launch-app/ROADMAP.md (Slice 1 is the task)
- Rulebook:      ~/projects/wiggleverse/engineering/README.md  (§8 stack, §8.4 cloud profile)
- Extract FROM:  ~/projects/wiggleverse/ohm-rfc-app-flotilla (note pin.py, audit.py, deploy.py, registry.py)
- Dogfood fixture (built + tested): ~/projects/wiggleverse/wiggle-snip

Task: pull the generic 9-phase deploy engine out of ohm-rfc-app-flotilla into
an installable flotilla-core consuming a deployment.toml (schema = SPEC §5.1),
carrying NO app-specific defaults. De-OHM it (SPEC §7.2): remove the pin.py
rfc-app >=0.2.3 floor (pin floor → optional per-app config, default none);
generalize audit.py off rfc-app lockfiles; parameterize the OHM data-dir /
DB-filename / user-agent names.

DEFINITION OF DONE (SPEC §7.3 — do not skip): repoint OHM's flotilla to consume
flotilla-core as a thin shim and PROVE OHM STILL DEPLOYS through it unchanged.
The existing OHM deployment is the regression oracle; new tests alone are NOT done.

Scope guard (SPEC §10): pre-prod, single-environment only. NO slots / ramp /
promote / rollback / compat-gate / watcher (that's guide §10). If you start
adding any, stop.

Process: spec-driven (cite SPEC/guide § in commits; branch → PR, not straight to
main). Hard secrets rule (guide §6 / SPEC §8.3): never put a secret byte in the
session; hand the operator stdin-piped commands. At the end, hand over the
Slice-2 prompt, and note anything in the SPEC that turned out wrong/underspecified
against the real code so we can correct it before Slices 25.