# Session 0004.0 — Transcript

> Date: 2026-05-27
> Goal: Write `flotilla/SPEC.md` (binding architectural contract for
> flotilla v1) and clean up the stale `rfc.wiggleverse.org` GCP
> instance. No code in this session — only spec and the irreversible
> GCP gesture. The spec includes a slicing plan that drives subsequent
> build sessions.
>
> Outcome: `rfc.wiggleverse.org` fully deprovisioned (VM, IP, firewall
> rules, DNS, GCP project). New repo `ohm-rfc-app-flotilla` created at
> v0.0.1 with binding SPEC, README, CHANGELOG, VERSION, LICENSE.
> Canonical-only at `git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla`
> (HEAD `a9a9aaa`, `v0.0.1` tag `43158a8`). No personal-Gitea mirror —
> this is a Wiggleverse-organizational asset; the future generic
> flotilla library, when extracted, would inherit the rfc-app
> mirror pattern.
>
> The session worked through five naming iterations
> (`flotilla` → `rfc-app-flotilla` → `ohm-rfc-flotilla` →
> `ohm-rfc-app-flotilla`), one substantive architectural reconsideration
> (flotilla-as-library-inside-rfc-app, rejected for v1 because it would
> require putting GCP credentials onto the deployed VM), and one
> post-spec correction (dropping the benstull mirror after recognizing
> the wiggleverse-vs-benstull split is organizational-vs-personal,
> not redundant-mirror).

---

## Turn 1 — User (the session prompt)

> Goal of this session: write flotilla/SPEC.md (the binding
> architectural contract for flotilla v1) and clean up the stale
> rfc.wiggleverse.org GCP instance. No code in this session — only
> spec and the irreversible GCP gesture. The spec includes a slicing
> plan that drives subsequent build sessions.
>
> [The full session prompt followed: architecture committed in advance
> (rfc-app as open-source framework with canonical at
> git.wiggleverse.org/ben.stull/rfc-app, ohm-app as the GCP infra name
> for the OHM deployment, ohm-rfc as the OHM corpus repo currently
> carrying .rfc-app-version=0.3.0, flotilla as the operator control
> panel holding non-secret config + Secret Manager references); out of
> scope for v1 (private-branch deploys, multi-deployment beyond OHM,
> Cloud Build, auto-deploy on merge); required reading list
> (rfc-app/CLAUDE.md, rfc-app/SPEC.md §17/§19.2/§19.3/§20,
> ohm-infra/SESSION-0003.0-TRANSCRIPT.md Turn 22/29/33, deploy/RUNBOOK.md
> and DEPLOY-NEW-SESSION-PROMPT.md, ohm-rfc/.rfc-app-version,
> flotilla/ currently empty); the session-step plan (cleanup first,
> then spec with 14 required sections, then don't migrate secrets in
> this session, then write VERSION/CHANGELOG/README, then git init);
> constraints (no code, cleanup is irreversible, spec is binding,
> private branches stay out); after-session expectations.]

## Turn 1 — Assistant

The assistant began by reading the required context in parallel:
`rfc-app/SPEC.md` for §17 (the `/api/health` contract), §19.2/§19.3
(candidate topics + working agreement shape), §20 (versioning policy);
`ohm-infra/SESSION-0003.0-TRANSCRIPT.md` Turns 22, 29, 33 (the Option 2
secret-store commitment and the `ohm-app` naming convention);
`rfc-app/deploy/RUNBOOK.md` (the manual upgrade sequence flotilla
would automate); the current `.rfc-app-version` pin (`0.3.0`); the
current state of `/Users/benstull/git/flotilla/` (empty); the
`/Users/benstull/git/rfc-app/` git remotes.

A task list was created tracking seven items: gather GCP state, execute
GCP teardown step-by-step, verify rfc.wiggleverse.org gone, settle open
questions for flotilla/SPEC.md, write flotilla/SPEC.md, write
VERSION/CHANGELOG/README, git init + commit + push + tag.

GCP state gathered:

```
wiggleverse-rfc project contents:
- VM `rfc-app` (us-central1-a, e2-small, RUNNING, IP 34.132.29.41)
- Static IP `rfc-app-ip` = 34.132.29.41 (IN_USE)
- Disk `rfc-app` (20GB, us-central1-a)
- Firewall rules: rfc-app-http, rfc-app-https, rfc-app-ssh
  (plus 3 default-allow-* rules)
```

Cross-use check confirmed nothing in `wiggleverse-rfc` was referenced
by `wiggleverse-ohm` (the live OHM deployment) or `wiggleverse` (the
Gitea VM). DNS `dig +short rfc.wiggleverse.org` resolved to
`34.132.29.41`.

The assistant also flagged a concerning side observation: `curl
https://ohm.wiggleverse.org/api/health` returned `{"detail":"Not
Found"}` — a 404 suggesting OHM may not actually be running 0.3.0 (or
nginx wasn't routing `/api/health` to uvicorn). Not in this session's
scope; flagged for a later session.

The assistant then presented three questions before any destructive
step: VM teardown method, project-deletion bias, and DNS-deletion
path.

## Turn 2 — User

User selected:
- VM teardown: "Yes — delete the VM" (delete VM and its disk in one shot via `--delete-disks=all`)
- Project deletion bias: "Delete the project (cleaner)"
- DNS deletion: "I'll do it manually in the Cloudflare UI"

## Turn 2 — Assistant

Executed VM deletion:

```
$ gcloud compute instances delete rfc-app \
    --zone=us-central1-a --project=wiggleverse-rfc \
    --delete-disks=all --quiet
Deleted [.../instances/rfc-app].
```

Verified: instances list returned 0, disks list returned 0, IP
`rfc-app-ip` moved from `IN_USE` to `RESERVED`. Asked next about
releasing the IP.

## Turn 3 — User

> Yes — release.

## Turn 3 — Assistant

```
$ gcloud compute addresses delete rfc-app-ip \
    --region=us-central1 --project=wiggleverse-rfc --quiet
Deleted [.../addresses/rfc-app-ip].
```

Verified the addresses list returned 0. Asked next about firewall
rules.

## Turn 4 — User

> Yes — delete the three rfc-app rules

## Turn 4 — Assistant

```
$ gcloud compute firewall-rules delete \
    rfc-app-http rfc-app-https rfc-app-ssh \
    --project=wiggleverse-rfc --quiet
Deleted [.../rfc-app-http].
Deleted [.../rfc-app-https].
Deleted [.../rfc-app-ssh].
```

Verified only the three default-allow-* rules remained. Asked the
user to delete the Cloudflare A record manually and then ping back.

## Turn 5 — User

> DNS is done

## Turn 5 — Assistant

Verified DNS gone:

```
$ dig +short rfc.wiggleverse.org
(empty)
$ dig +short rfc.wiggleverse.org @1.1.1.1
(empty)
$ curl -s --connect-timeout 5 https://rfc.wiggleverse.org
(http_code=000, connection failed)
```

Both verification criteria from the session prompt satisfied. Asked
the final destructive question: delete the `wiggleverse-rfc` GCP
project entirely?

## Turn 6 — User

> Yes — delete the project

## Turn 6 — Assistant

```
$ gcloud projects delete wiggleverse-rfc --quiet
Deleted [.../wiggleverse-rfc].

You can undo this operation for a limited period by running:
    $ gcloud projects undelete wiggleverse-rfc

$ gcloud projects describe wiggleverse-rfc \
    --format="value(lifecycleState)"
DELETE_REQUESTED
```

Project in 30-day soft-delete window. GCP cleanup complete.

The assistant then transitioned to the spec phase, opening with the
first cluster of open questions inline in the prompt's §2/§4/§6/§5
(hosting, storage, overlay home, pin source).

## Turn 7 — User

For the spec open questions, user selected all recommendations:

| Question | Choice |
|---|---|
| §2 hosting | Laptop only |
| §4 storage | SQLite file in flotilla repo's local clone |
| §6 overlay home | Inside flotilla's own state |
| §5 pin source | Stays in `ohm-rfc/.rfc-app-version` |

## Turn 7 — Assistant

Asked the next four open questions: §7 secret project, §7 naming
convention, §12 surface (CLI/web/both), §11 GCP auth.

## Turn 8 — User

All recommendations again:

| Question | Choice |
|---|---|
| §7 secret project | Same as the deployment — `wiggleverse-ohm` |
| §7 naming | `<deployment>-<env-key>` |
| §12 surface | CLI only |
| §11 GCP auth | ADC via gcloud login |

## Turn 8 — Assistant

Asked the final three open questions: §11 operator auth, §8 SSH auth,
§19 multi-deploy framing for v1.

## Turn 9 — User

All recommendations:

| Question | Choice |
|---|---|
| §11 operator auth | OS-level only (file ownership) |
| §8 SSH auth | `gcloud compute ssh` under the hood |
| §19 multi-deploy | Hard-code `ohm` as only registered deployment in v1 |

## Turn 9 — Assistant

Wrote `flotilla/SPEC.md` — 14 required sections plus §19 (Slice 0
status, candidate topics, working agreement) and §20 (the five-slice
build plan). The spec committed:

- Local-first laptop CLI (§2)
- SQLite state at `~/.flotilla/flotilla.db` (§4)
- Six architectural invariants (§3): never holds secret bytes;
  verifies via `/api/health` version-match; is the deploy actuator;
  depends on framework only through versioned contracts; operator-
  triggered only; framework knows nothing about flotilla
- Overlay inside flotilla state (§6); secret references in
  `wiggleverse-ohm` Secret Manager with `ohm-<env-key>` naming (§7)
- The deploy gesture's 9-phase sequence (§8): validate → preflight →
  fetch/checkout → pip → npm build → write .env → systemctl restart →
  /api/health probe loop → finalize
- Fail-stop behavior (§8.2): no auto-rollback in v1
- The /api/health probe loop with 5-minute budget, exponential
  backoff, version-match verdict (§9)
- Five §20 slices: registry+overlay (v0.1.0) → secrets bootstrap
  (v0.2.0) → dry-run deploy (v0.3.0) → full deploy + verify (v0.4.0)
  → hardening + first real upgrade (v1.0.0)

Then wrote VERSION (`0.0.1`), CHANGELOG.md (single `0.0.1 —
2026-05-27` entry), README.md (one paragraph + link to SPEC.md). Did
`git init -b main`, staged all four files, made an initial commit
with the rfc-app commit-message style, tagged `v0.0.1` annotated.

Probed both remote targets:

```
$ git ls-remote https://git.wiggleverse.org/ben.stull/flotilla.git
remote: Repository not found
$ git ls-remote git@git.benstull.org:benstull/flotilla.git
Permission denied (publickey)
```

Neither remote existed yet. Asked the user how to proceed with
remote creation + push.

## Turn 10 — User

> I'll create both repos in the UI, then ping you

## Turn 10 — Assistant

Standing by. While waiting, updated the auto-memory: refreshed
`project_ohm_deployment_host.md` to reflect the deprovisioning;
created `project_flotilla.md` describing the new project; updated
`MEMORY.md` index with both entries.

## Turn 11 — User

> Let's actually name all of this rfc-app-flotilla

## Turn 11 — Assistant

Pivoted: this is a bigger scope-check than a simple rename. Asked
two questions: how thoroughly should the rename apply (everywhere
vs partial vs repo-only)? And: since v0.0.1 hadn't been pushed yet,
should the existing commit be amended or stacked-on-top?

## Turn 12 — User

> "Everywhere — hard rename" + "Amend the v0.0.1 commit + re-tag"
>
> [And during the work, additional message:] "And are we sure that
> the flotilla in the wiggleverse should be under ben.stull? I think
> it should be under wiggleverse"

## Turn 12 — Assistant

Noted that rfc-app is currently under `ben.stull`, so flotilla under
`wiggleverse` introduces a small but real inconsistency. Three
options offered: flotilla under `wiggleverse` (leave rfc-app where
it is, file as follow-up); or move rfc-app too (bigger scope); or
flotilla under `ben.stull` for consistency.

## Turn 13 — User

> Flotilla under `wiggleverse`; leave rfc-app where it is for now

## Turn 13 — Assistant

Started the rename. Moved directory `/Users/benstull/git/flotilla`
→ `/Users/benstull/git/rfc-app-flotilla`. Began file edits with a
chained sequence of replace_all operations:

1. `ben.stull/flotilla` → `wiggleverse/rfc-app-flotilla` (canonical URL)
2. `flotilla` → `rfc-app-flotilla` (lowercase)
3. `Flotilla` → `rfc-app-flotilla` (capitalized → lowercased)
4. `FLOTILLA` → `RFC_APP_FLOTILLA` (env vars)
5. Python identifier underscores: `rfc-app-flotilla/__init__.py` →
   `rfc_app_flotilla/__init__.py` (etc.)

Read line 74 of the updated SPEC and caught a bug: the canonical URL
had been double-prefixed to `git.wiggleverse.org/wiggleverse/ohm-rfc-ohm-rfc-flotilla`
because the order of operations left a trailing "flotilla" that the
second replace_all then converted again. Fixed with a targeted edit.

While preparing further file edits, the user sent two more rename
messages in rapid succession.

## Turn 14 — User

> And should the repo be called ohm-app-flotilla?
>
> [immediately followed by] Oh, it should be ohm-rfc-flotilla and
> ohm-app should be ohm-rfc-app (we can change that later)

## Turn 14 — Assistant

Paused the rename mid-flight. The shift from `rfc-app-flotilla` to
`ohm-rfc-flotilla` was a framing change, not just a name change —
it implied the tool was tied to a specific deployment, breaking
the multi-deployment-shape framing in the current draft. Asked the
user to confirm one of three architectural framings: per-deployment
repos (each deployment gets its own); single generic flotilla with
a deployment-flavored name; or tighten further to hardcode OHM.

## Turn 15 — User

> Per-deployment repos — each deployment gets its own flotilla checkout

## Turn 15 — Assistant

Renamed the directory once more (`rfc-app-flotilla` →
`ohm-rfc-flotilla`). Then did the chained replace_all sequence on
SPEC.md, README.md, CHANGELOG.md to flip every identifier. Updated
§1 to introduce the per-deployment-repo convention explicitly.
Updated §19.2: the previous "Multi-deployment support" candidate
became "Extract generic flotilla library" (since the framing now
treats each deployment as having its own repo; library extraction
is the deduplication path). Added a §19.2 candidate "VM rename:
ohm-app → ohm-rfc-app" reflecting the user's note that the VM
rename is pending and out of scope this session.

Renamed the memory file `project_flotilla.md` →
`project_ohm_rfc_flotilla.md`; updated the body and MEMORY.md
index entry. Amended the v0.0.1 commit and re-tagged.

State: directory `/Users/benstull/git/ohm-rfc-flotilla/`, v0.0.1
tag pointing at the amended commit, ready to push when remotes
exist (still pending — user had committed to creating them in the
UI).

## Turn 16 — User

> What licence for ohm-rfc-flotilla?

## Turn 16 — Assistant

Checked sibling licenses:
- `rfc-app/LICENSE`: MIT, copyright Ben Stull 2026
- `ohm-rfc/LICENSE`: CC BY 4.0 (correct for content/corpus)

For ohm-rfc-flotilla (code, not content), MIT was the obvious
sibling. Asked which license + which copyright holder.

## Turn 17 — User

> "MIT (matches rfc-app)" + "Ben Stull (matches rfc-app exactly)"
>
> [followed by] public or private?

## Turn 17 — Assistant

Checked sibling visibility via unauthenticated `git ls-remote`:

```
$ git ls-remote https://git.wiggleverse.org/ben.stull/rfc-app.git
1a9374... HEAD
1a9374... refs/heads/main
[...]
$ git ls-remote https://git.wiggleverse.org/ben/ohm-rfc.git
warning: redirecting to .../ben.stull/ohm-rfc.git/
ed5e20... HEAD
[...]
```

Both siblings readable without auth → both public.

## Turn 18 — User

> Realizing that ohm-rfc-flotilla should be ohm-rfc-app-flotilla

## Turn 18 — Assistant

Asked two consolidated questions: visibility (public vs private),
and whether the registered deployment NAME inside flotilla §13.1
should also become `ohm-rfc-app` (matching the new repo prefix and
the eventual VM name).

## Turn 19 — User

> "Public (matches rfc-app + ohm-rfc)" + "`ohm-rfc-app` — match the
> repo and the eventual VM name"

## Turn 19 — Assistant

Started the next rename. Moved directory `/Users/benstull/git/ohm-rfc-flotilla`
→ `/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla`. Began the chained
replace_all sequence:

1. `ohm-rfc-flotilla` → `ohm-rfc-app-flotilla`
2. `ohm_rfc_flotilla` → `ohm_rfc_app_flotilla` (Python)
3. `OHM_RFC_FLOTILLA` → `OHM_RFC_APP_FLOTILLA` (env)
4. `` `ohm` `` → `` `ohm-rfc-app` `` (deployment name in backticks)

Used targeted edits for the few CLI examples with bare `ohm` not
flanked by backticks, plus the path-style rejected example in §7.2.

Started the secret-ID renames (`ohm-gitea-bot-token` →
`ohm-rfc-app-gitea-bot-token`, etc.) — got through 4 of 6 before
the user sent another message.

## Turn 20 — User

> What is the difference between the rfc-app-flotilla vs the
> ohm-rfc-app-flotilla at this point?

## Turn 20 — Assistant

Paused the file edits to answer. Built a table comparing the two
framings:

| | `rfc-app-flotilla` (earlier draft) | `ohm-rfc-app-flotilla` (current) |
|---|---|---|
| What is it? | Framework's companion tool, configured for OHM | OHM's deployment-specific operator tool |
| Naming convention | One tool, multi-deployment-shaped | Per-deployment repos |
| §19.2 candidate | "Multi-deployment support" | "Extract generic library" |
| CLI shape | `rfc-app-flotilla deploy <deployment>` | `ohm-rfc-app-flotilla deploy ohm-rfc-app` |

At the code/behavior level, almost nothing different — same §3
invariants, same §4 schema, same §8 deploy gesture. The differences
were in identity and architectural framing.

The assistant also raised a third option not yet on the table: a
generic `flotilla` library + thin per-deployment config repos.
Asked which framing to commit to.

## Turn 21 — User

> Stay the course — `ohm-rfc-app-flotilla` is OHM's tool

## Turn 21 — Assistant

Continued the rename. Picked up where it left off in the
secret-ID prefix updates (`ohm-smtp-password`,
`ohm-webhook-email-bounce-secret` → their `ohm-rfc-app-` forms).
Cleaned up the path-style rejected example in §7.2 (replaced with
the cleaner illustrative `flotilla/ohm-rfc-app/gitea-bot-token`).

Continued on with: README.md replace_all, CHANGELOG.md replace_all.

While doing this, the user sent another message.

## Turn 22 — User

> Where would philosophy.md and other non-config value configurations
> go in the different proposals?

## Turn 22 — Assistant

Paused again. Answered:

- `PHILOSOPHY.md` and similar content (the deployment's
  hand-authored RFC system content) lives in the **meta repo on
  Gitea** per `rfc-app/SPEC.md` §2. The framework reads it at
  runtime. Flotilla never touches it.
- Other "non-config value configurations" — branding assets,
  custom CSS, pre-deploy hooks, custom SYSTEM_PROMPT prose — would
  need a home; the current SPEC §6 only covers env-var key/value
  overlay, not richer config.

Asked where the spec should commit on rich config: meta repo first
with flotilla repo as escape hatch (recommended); flotilla repo
holds it all; or defer entirely as a §19.2 candidate.

## Turn 23 — User

> Ok so the rfc-app config would have a url to the philosophy blob
> that's in the meta repo

The user picked "Other" with this clarifying observation — a
distillation of the framework→meta-repo content-fetch relationship
they had just been told about.

## Turn 23 — Assistant

Confirmed: yes — `GITEA_URL`, `GITEA_ORG`, `META_REPO` are env vars
in the overlay; the framework uses them to find the meta repo and
reads `PHILOSOPHY.md`, the README header, and future content blobs
from there at runtime. **Flotilla's overlay holds the pointer; the
meta repo holds the content.** Rich content never lives in flotilla.

Added §6.3 to SPEC.md committing to exactly this principle: the
overlay scopes to env-var key/value only; rich content lives in the
meta repo; deploy-mechanics rich config (hooks, deploy notes,
custom systemd overrides) lives in *this repo* alongside SPEC.md
when needed. (Renumbered the old §6.3 "Why this shape is
load-bearing" to §6.4.)

## Turn 24 — User

> ok so the flotilla could be a library in the rfc-app and then
> configured to use e.g. GCP or Azure or whatever to deploy

## Turn 24 — Assistant

A meaningful architectural pivot — bigger than the naming churn.
The user was proposing: flotilla becomes a library inside `rfc-app`
(probably `rfc_app.flotilla`), shipped with the framework,
cloud-provider-abstracted. A per-deployment thin repo imports the
library and supplies configuration.

Spelled out the differences:

| Concern | Standalone (current) | Library in rfc-app (proposed) |
|---|---|---|
| Where engine code lives | This repo | rfc-app adds `flotilla/` package |
| Cloud-provider scope | GCP-only, no abstraction | GCP-only-in-v1, abstraction at library level |
| rfc-app §3 invariant 6 | Holds | Flips |
| Spec scope here | ~1500 lines | Much shorter |
| Release coupling | Independent | Tied to framework |
| First implementation session | Builds tool in this repo | Builds library in rfc-app |

Recommended: if pivoting, pause v0.0.1 as-is, write a new
rfc-app-side library spec (probably `rfc-app/SPEC.md §21`), and let
this repo's SPEC become thin (just OHM's deployment record).

Asked: pivot, or stick with the current direction?

## Turn 25 — User

> Do you liek this directional change?

The user asked directly for an opinion.

## Turn 25 — Assistant

Gave an honest analysis arguing **against** the pivot for v1:

Three reasons against:

1. **Cloud abstraction with one cloud and one deployment is a
   design exercise with no validating constraint.** Designing for
   GCP+Azure+AWS with only OHM-on-GCP as a real consumer means
   designing against hypotheticals. The first real Azure deployment
   is what tells us where GCP-specific bits leaked through; that
   evidence doesn't exist yet.
2. **Scope creep on `rfc-app` during a period when the framework's
   own §19.2 queue is long.** rfc-app has its own backlog;
   bundling operator tooling dilutes the framework's focus.
3. **The library-extraction path is already explicit and
   triggered.** §19.2 "extract generic library" earns its session
   when a second deployment exists — a concrete trigger.

Two reasons the assistant might be wrong:

- If line of sight to a second deployment soon (especially
  on a different cloud), pre-investing avoids a more painful
  migration later.
- If the mental model is "rfc-app should be a complete platform
  an operator clones and runs," bundling matters for
  discoverability.

Vote: finish the rename, ship the standalone v0.0.1, let library
extraction earn its session when a real second deployment surfaces
it. Asked the user if there were factors tipping toward the pivot.

## Turn 26 — User

> It would mean an extension to the web admin interface or
> something since it wouldn't run locally on my machine

The user surfaced the strongest argument *against* the pivot
themselves: putting flotilla inside the framework process means
the operator can't drive it from their laptop — they'd need a web
UI on the running framework instance.

## Turn 26 — Assistant

Confirmed that was exactly the deciding argument. The current
architecture has a clean property worth naming: **the running app
cannot redeploy itself.** Your laptop has credentials; the VM does
not. Putting flotilla in the framework flips that:

- **Self-deploy bootstrap problem.** Framework down → can't deploy.
  Today, you deploy *because* the framework is down.
- **Credential blast radius.** Framework process now holds GCP
  credentials. Compromise upgrades to "attacker deploys arbitrary
  code."
- **New attack surface.** A "trigger deploy" web endpoint is a
  high-value target.
- **Multi-deployment awkwardness.** Either each deployment embeds
  its own flotilla (each needing SSH-to-self) or one flotilla
  manages many (centralized control plane co-hosted with one
  deployment).

The local-CLI shape gets all this for free. Asked if the user
wanted to finish the rename and ship v0.0.1 as the standalone
`ohm-rfc-app-flotilla`.

## Turn 27 — User

> yes, finish the rename and ship v0.0.1

## Turn 27 — Assistant

Finished the rename. Completed the remaining replace_alls on SPEC.md
(secret-ID prefixes), fixed the path-style example in §7.2, and
fixed the remaining bare-`ohm` CLI examples (`overlay set ohm` →
`overlay set ohm-rfc-app`; `overlay export ohm > ohm-overlay.json`
→ `overlay export ohm-rfc-app > ohm-rfc-app-overlay.json`;
`Alice can deploy ohm; Bob can deploy ohm but not` →
`deploy ohm-rfc-app`; etc.).

Did the README.md and CHANGELOG.md replace_alls.

Added the §6.3 clarifying paragraph (rich content lives in the meta
repo; overlay holds pointers only; deploy-mechanics rich content
lives in this repo when needed).

Created LICENSE matching rfc-app's MIT/Ben Stull 2026 verbatim.

Renamed the memory file `project_ohm_rfc_flotilla.md` →
`project_ohm_rfc_app_flotilla.md`, rewrote it with the
standalone-tool framing decision included, updated MEMORY.md index
entry.

Amended the v0.0.1 commit (now SHA `97237d2`) with an expanded
message naming the standalone-tool framing decision and the
library-pivot deferral. Deleted and re-created the v0.0.1 tag
at the amended commit.

Confirmed final state: 5 files at HEAD (`SPEC.md`, `README.md`,
`CHANGELOG.md`, `VERSION`, `LICENSE`), v0.0.1 tag pointing at
`97237d2`. Asked the user to create the two empty remote repos:

- Canonical: `git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla`
- Mirror: `git.benstull.org/benstull/ohm-rfc-app-flotilla`

## Turn 28 — User

> ok, they're ready

## Turn 28 — Assistant

Added the remotes:

```
$ git remote add origin \
    https://git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla.git
$ git remote add benstull \
    git@git.benstull.org:benstull/ohm-rfc-app-flotilla.git
```

Tried to push:

```
$ git push -u origin main
! [rejected]  main -> main (fetch first)
error: failed to push some refs
hint: Updates were rejected because the remote contains work that
hint: you do not have locally.
```

The canonical wasn't fully empty — Gitea's auto-init had created
an "Initial commit" with `LICENSE` + `README.md`. Asked the user
how to resolve: force-push (overwrite the auto-init), rebase onto
it, or recreate the repo without auto-init.

## Turn 29 — User

> Force push — overwrite the auto-init

## Turn 29 — Assistant

```
$ git push --force origin main
+ 324dc2f...97237d2 main -> main (forced update)

$ git push origin v0.0.1
* [new tag] v0.0.1 -> v0.0.1
```

Canonical pushed.

Tried mirror:

```
$ git push -u benstull main
git@git.benstull.org: Permission denied (publickey).
```

Diagnosed: `ssh-add -l` showed "The agent has no identities."
`~/.ssh/config` had a `git.benstull.org` entry pointing at
`~/.ssh/id_benstull_gitea`. The key file existed (mode 0600,
ed25519, comment `benstull@git.benstull.org 2026-05-25`). Verbose
SSH probe showed the key being offered but the server rejecting it:
`Permission denied (publickey)`.

Cross-checked rfc-app's existing benstull remote — same failure
mode. Conclusion: the SSH agent isn't reachable from this Bash
subshell (the user's normal terminal has it set up but the
session's shell context doesn't). Not a key issue with
ohm-rfc-app-flotilla specifically; an environment issue affecting
all `git.benstull.org` access from the session.

Suggested the user run the mirror push from their own terminal
(or via `!` prefix in this session) using:

```
git -C /Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla push -u benstull main
git -C /Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla push benstull v0.0.1
```

Confirmed canonical state via `git ls-remote`: HEAD `97237d2`,
v0.0.1 tag landed.

## Turn 30 — User

> ok what's next?

## Turn 30 — Assistant

Session recap and pointed at the next session — Slice 1 per
`ohm-rfc-app-flotilla/SPEC.md` §20.1.

The Slice 1 brief:

> Implement Slice 1 of `ohm-rfc-app-flotilla` per `SPEC.md` §20.1.
> Scope: Python project skeleton (`pyproject.toml`,
> `ohm_rfc_app_flotilla/__init__.py`, Click entrypoint at
> `ohm_rfc_app_flotilla.cli:main`), pytest runner, CI scaffold;
> SQLite schema for `deployments`, `overlay_entries`,
> `schema_migrations` per §4.3 with a migration file in
> `ohm_rfc_app_flotilla/migrations/`; CLI verbs:
> `deployment add/list/show/remove`, `overlay set/unset/show`;
> register the OHM deployment per §13.1–§13.6 (non-secret values;
> secrets are Slice 2); tests round-tripping every verb against a
> temp SQLite — no GCP, no network.
> Exit criteria: `ohm-rfc-app-flotilla deployment show ohm-rfc-app`
> and `ohm-rfc-app-flotilla overlay show ohm-rfc-app` render the
> registered record. Ships as v0.1.0.

Adjacent follow-ups filed for later sessions:

- Dirty rfc-app working tree (rfc.wiggleverse.org → ohm.wiggleverse.org
  swap; rfc-app → ohm-app deploy-doc rename)
- VM rename ohm-app → ohm-rfc-app
- `{"detail":"Not Found"}` on ohm.wiggleverse.org/api/health
  (likely surfaces during Slice 4 verify)

## Turn 31 — User

> what dirs are needed for the next session?

## Turn 31 — Assistant

Listed:

- **Primary working directory:**
  `/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`
- **Additional working directory:**
  `/Users/benstull/git/rfc-app/` (read-only reference for
  `SPEC.md` §17 and §20)

Not needed for Slice 1 (per §20.1 "no GCP, no network"):
`ohm-rfc`, GCP access, the OHM VM, Secret Manager.

Raised the memory question: if primary cwd switches to
`ohm-rfc-app-flotilla/`, Claude Code spins up a fresh project
memory dir; the memories written this session live under the
rfc-app project dir. Asked which option.

## Turn 32 — User

> Copy relevant memories to the new project

## Turn 32 — Assistant

Copied four memory files into a fresh
`/Users/benstull/.claude/projects/-Users-benstull-git-ohm-rfc-app-flotilla/memory/`:

- `project_ohm_rfc_app_flotilla.md`
- `project_ohm_deployment_host.md`
- `project_open_human_model.md`
- `project_wiggleverse.md`

Wrote a corresponding `MEMORY.md` index pointing at the four.

## Turn 33 — User

> oh, write a full transcript of this session (EVERYTHING) to ~/git/ohm-infra

## Turn 33 — Assistant

This file. The assistant inspected the existing
`SESSION-0003.0-TRANSCRIPT.md` for naming convention and style, then
wrote this `SESSION-0004.0-TRANSCRIPT.md` reproducing every turn of the
session.

## Turn 34 — User

> Why is ohm-rfc-app-flotilla in benstull? Shouldn't that just be
> rfc-app-flotilla and ohm-rfc-app-flotilla is in wiggleverse?

The user raised an inconsistency the session had baked in: the
`benstull` mirror was set up matching the rfc-app pattern (every
repo mirrored), but the *pattern itself* distinguishes generic
open-source artifacts (Ben-personal-shape, mirrored to
`git.benstull.org/benstull/`) from organization assets
(Wiggleverse-shape, only on `git.wiggleverse.org/wiggleverse/`).
`ohm-rfc-app-flotilla` is OHM-specific — a Wiggleverse asset, not
a Ben-personal one — so it shouldn't have a benstull-side mirror.

## Turn 34 — Assistant

Confirmed the read. The mirror pattern works like this:

- `git.benstull.org/benstull/...` — generic / open-source / Ben-
  personal artifacts (e.g., `rfc-app`, framework code Ben authored)
- `git.wiggleverse.org/wiggleverse/...` — Wiggleverse organization
  assets (e.g., `ohm-rfc` the OHM corpus, `ohm-rfc-app-flotilla`
  the OHM operator tool)

The future generic `rfc-app-flotilla` library — the §19.2 "extract
generic library" candidate — would, when extracted, fit the
Ben-personal-shape and earn the `git.benstull.org/benstull/`
mirror. The current OHM-specific repo does not.

Proposed: drop the benstull mirror entirely for v0.0.1; ship
canonical-only. Asked the user to confirm.

## Turn 35 — User

> Yes — drop it. Canonical-only at wiggleverse

## Turn 35 — Assistant

Executed:

1. Removed the `benstull` git remote from the local config.
2. Edited `SPEC.md` §2 to drop the mirror line. Replaced the
   "Both remotes track main on every push" prose with a paragraph
   explaining the mirror pattern (generic-vs-organizational) and
   committing that `ohm-rfc-app-flotilla` is canonical-only.
3. Updated both copies of `project_ohm_rfc_app_flotilla.md` (the
   rfc-app-project memory dir and the new
   ohm-rfc-app-flotilla-project memory dir) to drop the mirror URL.
4. Amended the v0.0.1 commit with an expanded message naming the
   canonical-only decision. New commit SHA `a9a9aaa`.
5. Deleted and re-created the `v0.0.1` tag at the amended commit.
6. Force-pushed both `main` and `v0.0.1` to canonical.

Final state:

```
$ git ls-remote https://git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla.git
a9a9aaa... HEAD
a9a9aaa... refs/heads/main
43158a8... refs/tags/v0.0.1
a9a9aaa... refs/tags/v0.0.1^{}
```

The mirror push that was pending the operator's terminal is no
longer needed — there's no mirror to push to.

## Turn 36 — User

> ok, what now?

## Turn 36 — Assistant

Treated as the session-close moment. Gave a recap of what landed
(GCP cleanup; v0.0.1 spec at canonical-only `a9a9aaa`; memory
synced; full transcript exists) and three options:

1. Start Session 0005.0 — Slice 1 now (primary cwd
   `/Users/benstull/git/ohm-rfc-app-flotilla/`, additional dir
   `/Users/benstull/git/rfc-app/`, the §20.1 brief).
2. Step away — Session 0004.0 is a complete unit of work.
3. One more small thing in this session — investigate the
   `{"detail":"Not Found"}` on ohm.wiggleverse.org/api/health, or
   clean up rfc-app's dirty working tree, or move rfc-app's
   canonical from `ben.stull/` to `wiggleverse/` for consistency.

Voted (1) or (2); flagged (3) as fine but breaking the clean
handoff to Slice 1.

## Turn 37 — User

> arg...I thought /Users/benstull/git/ohm-rfc-app-flotilla/ wouldn't
> exist now

The user expected the local directory to track the
wiggleverse-vs-personal organizational split that the just-landed
mirror-drop decision had spelled out. The operator's convention:
- `/Users/benstull/git/` holds Ben-personal projects (e.g.,
  `rfc-app` itself)
- `/Users/benstull/projects/wiggleverse/` holds Wiggleverse
  organizational projects (`ohm-rfc` already lives here)

ohm-rfc-app-flotilla, being a Wiggleverse asset (per the mirror-drop
rationale in Turn 34/35), should sit alongside ohm-rfc at
`/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`, not
under `/Users/benstull/git/`.

The session had started at `/Users/benstull/git/flotilla/` per the
initial prompt's wording; the framing-driven location shift didn't
follow the naming-driven rename.

## Turn 37 — Assistant

Acknowledged the miss. Asked the user to confirm the move to
`/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`.

## Turn 38 — User

> Yes — move to `/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`

## Turn 38 — Assistant

Executed:

1. `mv /Users/benstull/git/ohm-rfc-app-flotilla
       /Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla`
   — the `.git` dir moved with the parent directory; the origin
   remote URL is unaffected (it's just a string in `.git/config`).
2. Moved the auto-memory dir:
   `/Users/benstull/.claude/projects/-Users-benstull-git-ohm-rfc-app-flotilla`
   →
   `/Users/benstull/.claude/projects/-Users-benstull-projects-wiggleverse-ohm-rfc-app-flotilla`
   so that the next session at the new cwd auto-loads the memory.
3. Updated path references in both copies of
   `project_ohm_rfc_app_flotilla.md` (the rfc-app project memory
   and the moved memory dir) plus both `MEMORY.md` indexes.
4. Updated this transcript's path references via replace_all.

Verified `git -C <new path> status` clean and `git remote -v` still
points at `git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla.git`.

The next session's primary cwd is therefore
`/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`, with
`/Users/benstull/git/rfc-app/` as an additional read-only working
dir.

## Turn 39 — User

> ok, update the transcript

The user noticed that the transcript had been written before the
final move and post-move turns happened, and asked for it to be
brought current.

## Turn 39 — Assistant

This update. Inserted the missing Turn 36 ("ok, what now?" — the
intended session-close moment, before the user surfaced the
directory-location miss), renumbered the subsequent turns to
preserve sequence, and appended Turn 39 itself. The transcript now
ends at the actual end of the session.

## Turn 40 — User

> ok, so I just start a claude session at
> /Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/?
> Also, why is the auto-memory dir
> /Users/benstull/.claude/projects/-Users-benstull-projects-wiggleverse-ohm-rfc-app-flotilla/memory/?

## Turn 40 — Assistant

Confirmed yes — `cd` to that dir and run `claude` and the session
auto-loads the matching project memory.

Explained the auto-memory dir naming as a Claude Code internal
convention: take the absolute project path, replace every `/`
with `-`, place the result under the global `~/.claude/projects/`
dir. So `/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`
becomes the dir
`/Users/benstull/.claude/projects/-Users-benstull-projects-wiggleverse-ohm-rfc-app-flotilla/`.
The leading `-` is just the leading `/` of the absolute path under
the replacement rule. It's a filesystem-safe encoding so each
project gets a unique-by-path memory dir.

Verified the dir contents: `MEMORY.md` + four memory files
(`project_ohm_rfc_app_flotilla.md`,
`project_ohm_deployment_host.md`, `project_open_human_model.md`,
`project_wiggleverse.md`).

## Turn 41 — User

> ok, update the transcript and I'll exit

## Turn 41 — Assistant

This update. Captures Turns 40 and 41 themselves and confirms the
session genuinely closes here. The operator's next move is to
`cd /Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`
and start a fresh `claude` session for Session 0005.0 — Slice 1.

Final task list at session close (now actually final):

| # | Subject | Status |
|---|---|---|
| 1 | Gather GCP state for wiggleverse-rfc cleanup | completed |
| 2 | Confirm + execute GCP teardown step-by-step | completed |
| 3 | Verify rfc.wiggleverse.org is gone | completed |
| 4 | Settle open questions for flotilla/SPEC.md | completed |
| 5 | Write flotilla/SPEC.md | completed |
| 6 | Write VERSION, CHANGELOG.md, README.md | completed |
| 7 | Push to canonical + mirror, tag v0.0.1 | completed (canonical only; mirror dropped in Turn 35) |
| 8 | Hard rename flotilla → ohm-rfc-flotilla | completed |
| 9 | Rename to ohm-rfc-app-flotilla + add LICENSE + deployment name shift | completed |
| 10 | Drop benstull mirror; canonical-only v0.0.1 | completed |
| 11 | Move repo to /Users/benstull/projects/wiggleverse/ | completed |

---

## Appendix A — Session artifacts shipped to the ohm-rfc-app-flotilla repo

**v0.0.1 commit (final, after Turn 35's mirror-drop amend):**

```
commit a9a9aaacb5e314445a96cd379777df57a4187460
Author: Ben Stull <benstull@mac.lan>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

    Release 0.0.1: initial spec

    ohm-rfc-app-flotilla v1 binding contract — SPEC.md §1–§14 plus §19
    (Slice 0 status, candidate topics, working agreement) and §20 (the
    five-slice build plan). No implementation yet; the slicing plan in
    §20 names the subsequent build sessions that ship Slices 1 through 5
    (v0.1.0 → v1.0.0).

    Architectural commitments:
    - Standalone-tool framing: ohm-rfc-app-flotilla is OHM's operator
      CLI, NOT a library inside rfc-app. The deployed app cannot
      redeploy itself; GCP credentials live on the operator's laptop,
      not on the VM.
    - Local-first (laptop CLI; no server, no web UI).
    - SQLite state at ~/.ohm-rfc-app-flotilla/ohm-rfc-app-flotilla.db.
    - Secret bytes never live in flotilla — GCP Secret Manager holds
      bytes, flotilla holds references (Option 2 from the rfc-app/OHM
      Session 0003.0 transcript).
    - Deploy verification via the rfc-app/SPEC.md §17 /api/health
      endpoint (version-match check).
    - Operator-triggered only; no auto-deploy in v1.
    - Per-deployment-repo naming convention: this repo is OHM's. The
      deployment is named ohm-rfc-app. A future deployment would have
      its own <deployment>-flotilla repo. The §19.2 "extract generic
      library" candidate covers eventual deduplication.
    - §6.3 commits: deployment-side rich content (PHILOSOPHY.md,
      README header, future landing.json) lives in the meta repo on
      Gitea per rfc-app/SPEC.md §2. The overlay holds pointers only.
    - Canonical-only at git.wiggleverse.org/wiggleverse — no personal-
      Gitea mirror, because this is a Wiggleverse-organizational asset,
      not a Ben-personal one. The future generic flotilla library would
      follow the rfc-app pattern and earn a benstull-side mirror;
      this OHM-specific repo does not.

    Supporting files: VERSION (0.0.1), CHANGELOG.md, README.md, LICENSE
    (MIT, matching rfc-app).
```

**Tag**: `v0.0.1` annotated, SHA `43158a8`, message
`Release 0.0.1: initial spec`.

**Files at HEAD:** `SPEC.md` (~1500 lines), `README.md`, `CHANGELOG.md`,
`VERSION` (`0.0.1`), `LICENSE` (MIT).

**Canonical:** `git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla` —
HEAD `a9a9aaa`, `refs/tags/v0.0.1` at `43158a8` (force-pushed in Turn 35
after the mirror-drop amend; the original `97237d2` HEAD is no longer
referenced).

**Mirror:** none. The session initially set up a `benstull` mirror
remote and force-pushed to canonical with a SPEC §2 line naming
`git.benstull.org/benstull/ohm-rfc-app-flotilla` as the mirror; Turn 34
recognized this as an organizational-vs-personal mismatch and Turn 35
dropped it. The future generic flotilla library, if extracted, would be
where the `benstull/` mirror lives.

---

## Appendix B — GCP cleanup record

Resources deleted from `wiggleverse-rfc` project this session
(2026-05-27), in order:

1. VM `rfc-app` (us-central1-a, e2-small) — `gcloud compute
   instances delete --delete-disks=all` so the attached 20GB
   `rfc-app` disk was deleted in the same operation.
2. Static IP `rfc-app-ip` = `34.132.29.41` (us-central1) — released
   to GCP's pool.
3. Firewall rules `rfc-app-http`, `rfc-app-https`, `rfc-app-ssh`.
4. Cloudflare DNS A record for `rfc.wiggleverse.org` (deleted
   manually by operator).
5. GCP project `wiggleverse-rfc` — `gcloud projects delete`. In
   `DELETE_REQUESTED` state, 30-day soft-delete window
   (undeletable until ~2026-06-26 via `gcloud projects undelete`).

Post-cleanup verification:

```
$ dig +short rfc.wiggleverse.org
(empty)
$ curl -s --connect-timeout 5 -o /dev/null \
    -w "exit=%{exit_code} http=%{http_code}\n" \
    https://rfc.wiggleverse.org
exit= http=000
```

The deprovisioning is irreversible for practical purposes (the
project will fully delete in ~30 days; the DNS record is gone; the
IP has been returned to the GCP pool and may be reassigned to
someone else).

---

## Appendix C — Naming iterations through the session

The repo went through four names before landing on the v0.0.1
identity:

| Phase | Repo name | Canonical URL | Why moved |
|---|---|---|---|
| 1 | `flotilla` | `git.wiggleverse.org/ben.stull/flotilla` | (initial draft) |
| 2 | `rfc-app-flotilla` | `git.wiggleverse.org/ben.stull/rfc-app-flotilla` | User: "name all of this rfc-app-flotilla" |
| 3a | `rfc-app-flotilla` | `git.wiggleverse.org/wiggleverse/rfc-app-flotilla` | User: should be under wiggleverse org, not ben.stull |
| 3b | `ohm-rfc-flotilla` | `git.wiggleverse.org/wiggleverse/ohm-rfc-flotilla` | User: per-deployment-repo convention; this is OHM's |
| 4 | `ohm-rfc-app-flotilla` | `git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla` | User: deployment is `ohm-rfc-app` (mirroring `rfc-app`); flotilla repo matches |

Final state at v0.0.1:

| Identifier | Form |
|---|---|
| Repo name | `ohm-rfc-app-flotilla` |
| Canonical URL | `git.wiggleverse.org/wiggleverse/ohm-rfc-app-flotilla` |
| Mirror URL | (none — canonical-only; see Turn 34/35) |
| Directory | `/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/` |
| Python package | `ohm_rfc_app_flotilla` (underscores) |
| CLI binary | `ohm-rfc-app-flotilla` |
| State dir | `~/.ohm-rfc-app-flotilla/` |
| Env var prefix | `OHM_RFC_APP_FLOTILLA_*` |
| Registered deployment name | `ohm-rfc-app` |
| Secret ID prefix | `ohm-rfc-app-<env-key>` (in `wiggleverse-ohm` project) |

The VM/user/install/unit on the OHM host remain `ohm-app` for now —
their rename to `ohm-rfc-app` is a §19.2 candidate, scoped to its
own session.

---

## Appendix D — Architectural decisions that emerged during this session

In addition to the spec content itself, this session settled
several architectural questions that were not on the table when the
session opened:

1. **Per-deployment-repo convention.** Each rfc-app deployment is
   intended to have its own `<deployment>-flotilla` repo. This one,
   `ohm-rfc-app-flotilla`, is OHM's. The code inside is structurally
   generic; the repo's identity is the deployment's. Sharing code
   across deployments is the §19.2 "extract generic library"
   candidate, earning its session when a second deployment exists.

2. **Standalone-tool framing (not a library in rfc-app).** The
   pivot to "flotilla as a library inside rfc-app" was considered
   substantively and rejected for v1, on three grounds: cloud
   abstraction is premature with one cloud; framework scope creep;
   the library extraction is already an explicit §19.2 trigger.
   The user surfaced the strongest argument: an in-framework
   flotilla would need a web admin UI on the deployed framework,
   which means putting GCP credentials on the deployed VM —
   breaking the property that "the deployed app cannot redeploy
   itself."

3. **Rich content lives in the meta repo.** §6.3 of the SPEC
   commits: the overlay scopes to env-var key/value pairs only.
   Deployment-side rich content (PHILOSOPHY.md, README header,
   future landing.json) lives in the meta repo on Gitea per
   `rfc-app/SPEC.md` §2. The overlay holds *configuration values*
   including the pointers (`GITEA_URL`, `META_REPO`) that tell the
   framework where to read content from. Flotilla never holds
   content, not even cached copies.

4. **rfc-app stays under `ben.stull`; flotilla goes under
   `wiggleverse`.** The inconsistency is real but moving rfc-app is
   its own scope; filed as a follow-up.

---

## Appendix E — Memory writes during this session

The assistant created or updated these memory files under
`/Users/benstull/.claude/projects/-Users-benstull-git-rfc-app/memory/`:

- `project_ohm_deployment_host.md` — updated: rfc.wiggleverse.org
  marked as deprovisioned (was "pending deprovisioning"), added the
  deprovisioning date (2026-05-27), recorded the 30-day GCP
  soft-delete window, added cross-link to `[[project-flotilla]]`
  (later updated to `[[project-ohm-rfc-app-flotilla]]`).
- `project_flotilla.md` (created, later renamed twice):
  - First created as `project_flotilla.md`.
  - Renamed to `project_ohm_rfc_flotilla.md` mid-session.
  - Renamed again to `project_ohm_rfc_app_flotilla.md` at the
    end.
  - Final content names the repo, the standalone-tool framing
    decision, the per-deployment-repo convention, the §20 slicing
    plan reference, the §6.3 rich-content principle, the pending
    VM rename §19.2 candidate.
- `MEMORY.md` — index entry added for the new project, entry
  updated for the deprovisioning, names kept current through the
  renames.

At end of session, those four memory files plus
`project_open_human_model.md` and `project_wiggleverse.md` were
copied into a fresh
`/Users/benstull/.claude/projects/-Users-benstull-git-ohm-rfc-app-flotilla/memory/`
directory with a corresponding `MEMORY.md` index, so the next
session (Session 0005.0 — Slice 1, with primary cwd
`/Users/benstull/projects/wiggleverse/ohm-rfc-app-flotilla/`) auto-loads them
without manual setup.
