d5125190ae
- Rewrite every legacy `Session L` / `Session M.1` etc. reference inside
transcript bodies to the numeric form (`Session 0012.0` / `Session 0013.1`),
via a mechanical Python sed pass scoped to canonical-filename transcripts
only (502 replacements across 39 files; 21 files in this published repo +
18 sibling files in `~/git/ohm-infra/`). The §23 rename was originally
filename-only — session 0018.0 reverses that and rewrites the bodies too,
so cross-references inside a transcript match the filename you'd browse
to. The mapping table (`A → 0001` … `N → 0014`) lives in
`SESSION-PROTOCOL.md` §1 (also amended this session) for anyone hitting
an old external link.
- Amend README.md:
- New "Where the record begins" section noting OHM started with two
vibe-coded prototypes (no transcripts; the discipline that produced this
record didn't exist yet). The transcripts here begin at the
spec-driven-development phase — not at the literal beginning of OHM.
- Update the existing "Sessions 0001 through 0013 originally shipped
under a letter-form naming" paragraph to reflect that body refs are
now also in numeric form.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
804 lines
42 KiB
Markdown
804 lines
42 KiB
Markdown
# Session 0013.0 — Transcript
|
||
|
||
> Date: 2026-05-28
|
||
> Goal: Drive Wave 6 — three Track Ω inventory / draft subsessions in
|
||
> parallel. No rfc-app feature releases this wave; the wave's job is
|
||
> to surface the operator-led gestures that the post-Wave-5 plate
|
||
> needs (DNS edits, repo renames, counsel-reviewed copy) and to land
|
||
> docs that make OHM's contribution surface honest.
|
||
>
|
||
> Outcome: **All three subsessions produced their deliverables.**
|
||
> M.1 wrote docs feature branches in rfc-app + ohm-rfc (CONTRIBUTING
|
||
> + SPEC §21 analytics chapter) — pushed, awaiting operator PR
|
||
> review. M.2 wrote a 33 KB repo-naming inventory + move proposal
|
||
> with six open questions for the operator. M.3 wrote a deliverability
|
||
> + webhook hardening runbook + a rfc-app v0.18.0 framework-hygiene
|
||
> proposal — and surfaced one potentially-load-bearing finding:
|
||
> SMTP_HOST may be missing from the live flotilla overlay (every OHM
|
||
> email path silently broken if so). M.1 hit a stream-watchdog stall
|
||
> on the report-back step AFTER writing its transcript + pushing both
|
||
> feature branches — recovery was driver-reads-transcript-direct, no
|
||
> re-dispatch.
|
||
>
|
||
> First session running under the §5 subsession-transcript amendment
|
||
> (Session-L addition to SESSION-PROTOCOL.md). Three forked
|
||
> subagents pre-assigned M.1 / M.2 / M.3; each writes its own
|
||
> `SESSION-M.<n>-TRANSCRIPT-…md` before returning a tight report to
|
||
> the driver. Driver had to extend the publish script's filename +
|
||
> header validators mid-session — Session 0012.0 documented the §5
|
||
> validator extension but never landed it in the script (Arc 7).
|
||
> 14 §19.2 candidates surfaced across the three subs + driver.
|
||
|
||
---
|
||
|
||
## Pre-session state
|
||
|
||
**Time**: opened 2026-05-28T05-26 PST (Thursday, just-pre-dawn —
|
||
operator handed off the wheel after Session 0012.0's three-deploy
|
||
Wave 5 finish at 05:17 PST and is sleeping). Session 0012.0's main
|
||
transcript is at
|
||
`~/git/ohm-infra/SESSION-0012.0-TRANSCRIPT-2026-05-28T04-22--2026-05-28T05-17.md`.
|
||
|
||
**Repos at session open:**
|
||
|
||
| Repo | State at open |
|
||
| --- | --- |
|
||
| `rfc-app` (`~/git/rfc-app`, branch `main`) | clean tree, HEAD at `1456c8b` (Release 0.17.0: admin-create user + invite email + #21 Part C). Tags through `v0.17.0`. |
|
||
| `ohm-rfc` (`~/projects/wiggleverse/ohm-rfc`, branch `main`) | clean tree, HEAD at `47cb2f9` (ROADMAP strike of #12 / #13 / #16). `.rfc-app-version` = `0.17.0`. |
|
||
| `ohm-rfc-app-flotilla` (`~/projects/wiggleverse/ohm-rfc-app-flotilla`, branch `main`) | clean tree, HEAD at `65c0e55` (CLAUDE.md: correct the secret-set gesture). v1.0.1. |
|
||
| `ohm-infra` (`~/git/ohm-infra/`) | Plain directory (not a local git repo). Transcripts A–L published to `wiggleverse/ohm-session-history` via `scripts/publish-transcript.sh`. SESSION-PROTOCOL.md at the §5-amended version. |
|
||
|
||
**OHM live state**: `ohm.wiggleverse.org` serves rfc-app v0.17.0,
|
||
deploys.id=21 (last deploy from Session 0012.0). v0.13.0 cookie banner +
|
||
v0.14.0 /docs route + v0.15.0 Amplitude analytics & session replay +
|
||
v0.16.0 per-RFC owner invites + v0.17.0 admin-create user invites
|
||
all live in production for the first time. #21 Part C identity-
|
||
lifecycle wiring (identify-with-properties on sign-in,
|
||
setUserProperties on mid-session changes, amplitude.reset on
|
||
sign-out, identify-BEFORE-track on invite-claim paths) shipped
|
||
inline with the v0.15.0 / v0.16.0 / v0.17.0 release commits.
|
||
|
||
**Roadmap state**: #2–#16 + #21 Part C all shipped (struck through
|
||
in `~/projects/wiggleverse/ohm-rfc/ROADMAP.md`). Wave 6 candidates
|
||
open:
|
||
- #20 Email deliverability (HIGH priority — invites are now the
|
||
recipient's first contact with OHM, spam-foldering is silent
|
||
invite failure)
|
||
- #18 Secure SMTP relay + Gitea webhook (bundles with #20 — shared
|
||
DNS edits)
|
||
- #19 CONTRIBUTING guides + transcript-linked onboarding
|
||
- #21 Part B — SPEC analytics chapter + CONTRIBUTING checklist
|
||
(rides #19)
|
||
- #17 Repo naming + location alignment (operator-led; subagent
|
||
inventories + proposes)
|
||
- #1 VM rename (operator-led)
|
||
- #22 Pro-analytics-consent copy (BLOCKED — waiting on operator-
|
||
drafted + counsel-reviewed copy)
|
||
- #21 Part A — deep audit of v0.15.0 taxonomy + autocapture +
|
||
replay quality (BLOCKED — needs ~1 week of Amplitude data; v0.17.0
|
||
is <12 hours old)
|
||
|
||
**Housekeeping noticed at open**:
|
||
- A stale `SESSION-0012.0-TRANSCRIPT-2026-05-28T04-22--INPROGRESS.md`
|
||
(4.3 KB) sits next to Session 0012.0's final transcript at
|
||
`~/git/ohm-infra/`. The final transcript is the load-bearing one
|
||
(was published). The INPROGRESS placeholder is leftover.
|
||
Recommend the operator delete it (or driver deletes at the end
|
||
of M); not load-bearing for Session 0013.0's work.
|
||
- Three rfc-app worktrees from Session 0012.0 still on disk under
|
||
`~/git/`:
|
||
- `rfc-app-v0.15.0-amplitude/`
|
||
- `rfc-app-v0.16.0-owner-invite/`
|
||
- `rfc-app-v0.17.0-admin-create-user/`
|
||
Each release has shipped and merged to `main`; the worktrees are
|
||
no longer load-bearing. Could be cleaned up via
|
||
`git worktree remove` when the operator next runs through housekeeping.
|
||
|
||
---
|
||
|
||
## Dispatch plan
|
||
|
||
**Wave 6** runs as three forked subagents, each in its own subsession,
|
||
each writing its own transcript per §5 of the protocol. All three
|
||
are Track Ω (docs + ops inventory / proposal) — they touch
|
||
non-overlapping files in non-overlapping repos, so they run safely
|
||
in parallel without merge-conflict risk. None ship code that
|
||
runs on OHM in this wave; each produces a feature branch with a
|
||
draft + a recommendation block for the operator to review.
|
||
|
||
| Sub | Brief | Repo(s) touched | Output |
|
||
| --- | --- | --- | --- |
|
||
| **M.1** | #19 CONTRIBUTING guides bundled with #21 Part B (SPEC.md analytics chapter + CONTRIBUTING analytics checklist) | `rfc-app` (CONTRIBUTING.md + SPEC.md) + `ohm-rfc` (CONTRIBUTING.md) | Feature branches in both repos with drafts; ready for operator PR review |
|
||
| **M.2** | #17 inventory of every repo under `git.wiggleverse.org` + `git.benstull.org` with current name, canonical location, mirror status, and proposed name. Drafts a move-proposal doc. No renames executed. | `ohm-infra` (write proposal here) + read-only across all Wiggleverse / benstull repos | A `REPO-NAMING-PROPOSAL.md` (or similar) for operator to approve |
|
||
| **M.3** | #20 deliverability + #18 SMTP/webhook hardening combined inventory. Reads current DNS posture, rfc-app `backend/app/email_*.py`, ohm-infra SMTP/webhook config, Gitea webhook auth surfaces. Drafts a hardened-shape runbook + a rfc-app template-hygiene minor proposal. | `ohm-infra` (runbook) + read-only on `rfc-app` (drafts the proposal as a doc, NOT as code changes) | A hardening runbook + an rfc-app template-hygiene proposal doc |
|
||
|
||
**Why no rfc-app code release this wave**: every Wave 6 candidate
|
||
either (a) is docs / inventory / proposal that lands as a PR the
|
||
operator merges, no version bump, or (b) requires operator-led
|
||
gestures (DNS edits, counsel review, rename execution) that can't
|
||
happen autonomously. Wave 6 is the "set up Wave 7" wave —
|
||
deliverables here become the operator's plate, and Wave 7 picks up
|
||
the rfc-app minors (template hygiene, pro-consent copy) and the
|
||
ops moves (DNS, renames) that fall out.
|
||
|
||
**Dispatch contract for each subagent** (per §5.2):
|
||
1. Pre-assigned subsession ID named in the dispatch prompt.
|
||
2. Subagent MUST write `~/git/ohm-infra/SESSION-M.<n>-TRANSCRIPT-<start>--<end>.md`
|
||
before returning a report.
|
||
3. Subagent does NOT push code that ships on OHM. Branches only;
|
||
operator merges.
|
||
4. Subagent does NOT execute operator-led gestures (no DNS edits,
|
||
no repo renames, no SMTP provider config changes).
|
||
5. Subagent reports back with: branch + commit SHAs, the draft's
|
||
one-paragraph PR description, any §19.2 candidates surfaced.
|
||
|
||
---
|
||
|
||
## Turn-by-turn arc
|
||
|
||
### Arc 1 — Opening + Wave 6 plan + parallel dispatch
|
||
|
||
Operator handed off the wheel at 05:20 PST with a thorough brief
|
||
explicitly listing Wave 6 candidates and the new §5 subsession-
|
||
transcript dispatch shape. Read SESSION-PROTOCOL.md and ROADMAP.md
|
||
end-to-end. Identified six Wave-6-eligible items; three blocked
|
||
or operator-only (#22 / #21 Part A / #1), three dispatchable now
|
||
(#19 + #21B / #17 / #20+#18). Bundling rationale: #21 Part B
|
||
explicitly rides #19's CONTRIBUTING PRs per the roadmap; #18 and
|
||
#20 explicitly ship together because the same DNS edits serve both.
|
||
|
||
Pre-state snapshot above. Then opened this transcript at
|
||
`SESSION-0013.0-TRANSCRIPT-2026-05-28T05-26--INPROGRESS.md` and
|
||
dispatched the three subagents in parallel at 2026-05-28T05-30 PST.
|
||
|
||
Each subagent's dispatch prompt named:
|
||
- the subsession ID (M.1 / M.2 / M.3)
|
||
- the transcript filename to write at session end
|
||
- the binding constraints (never-secret-bytes; no-operator-led-
|
||
gestures; no force-push / `--amend` / `git config`)
|
||
- the read-only inventory boundary (no DNS edits, no repo
|
||
renames, no flotilla deploy, no SMTP provider changes)
|
||
- the deliverable shape and the report-back format
|
||
|
||
Dispatch summary:
|
||
|
||
| Sub | agent state | Scope |
|
||
| --- | --- | --- |
|
||
| **M.1** | running (background) | `rfc-app/CONTRIBUTING.md` + `rfc-app/SPEC.md` analytics chapter + `ohm-rfc/CONTRIBUTING.md`. Feature branches in both repos. |
|
||
| **M.2** | running (background) | `REPO-NAMING-PROPOSAL.md` — inventory + move proposal across `git.wiggleverse.org` + `git.benstull.org`. No renames executed. |
|
||
| **M.3** | running (background) | `EMAIL-AND-WEBHOOK-HARDENING-RUNBOOK.md` + `RFC-APP-EMAIL-HYGIENE-PROPOSAL.md`. Read-only DNS / flotilla-overlay / rfc-app code inventory. No DNS or SMTP changes. |
|
||
|
||
Driver waits for each completion notification, folds the report
|
||
+ subsession-transcript reference into Arc 2 / Arc 3 / Arc 4 as
|
||
they return. Cut-state table written after all three are in.
|
||
|
||
### Arc 2 — M.2 returns: #17 repo naming inventory
|
||
|
||
M.2 completed at 2026-05-28T05-37 PST (~7 min). Full detail:
|
||
`SESSION-0013.2-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-37.md`.
|
||
|
||
**Inventory totals:** 9 repos on `git.wiggleverse.org` (4 under
|
||
`ben.stull/`, 5 under `wiggleverse/`); 3 on `git.benstull.org`
|
||
(under `benstull/`: 1 real sha-synced mirror, 1 stub, 1 empty);
|
||
9 local-only working dirs catalogued in the proposal.
|
||
|
||
**Surfaced friction not in roadmap #17:**
|
||
- Three-meta-repos collision (`wiggleverse/meta` +
|
||
`wiggleverse/ohm-meta` + `wiggleverse/rfc-0001-human` —
|
||
the monorepo `ohm-rfc` has won in practice; three repos for
|
||
one job).
|
||
- Push-mirror description drift between `ben.stull/rfc-app` and
|
||
`benstull/rfc-app`.
|
||
- A `ben` username alias on git.wiggleverse.org creating a
|
||
1-hop redirect chain alongside the canonical `ben.stull`.
|
||
- `~/git/ohm-infra/` is a plain directory, not a git repo —
|
||
matches what the driver caught at session open. M.2 surfaces
|
||
it as a §19.2 candidate (see below).
|
||
|
||
**Top moves proposed (execution order from the proposal doc):**
|
||
1. Archive `wiggleverse/meta` (vestigial; zero-risk warmup).
|
||
2. Archive `wiggleverse/ohm-meta` + `wiggleverse/rfc-0001-human`
|
||
(requires Q1 operator confirm — per-RFC repos vs. monorepo).
|
||
3. Transfer `ben.stull/ohm-rfc` → `wiggleverse/ohm-rfc` — medium
|
||
risk; affects flotilla SPEC (~10 places), 4 test files
|
||
hardcode `ben/ohm-rfc`, and flotilla's SQLite registry stores
|
||
it as `pin_source_repo` + `corpus_repo` — **operator must run a
|
||
flotilla update post-move or the next deploy chases a 2-hop
|
||
Gitea redirect.**
|
||
4. Transfer `ben.stull/rfc-app` → `wiggleverse/rfc-app` — largest
|
||
blast radius. Flotilla SPEC §3.1 has a *conceptual* paragraph
|
||
explaining why rfc-app gets a benstull mirror — that rationale
|
||
dissolves under org-namespace and needs rewriting. Good news:
|
||
no shipped frontend artifacts reference these URLs, so end-
|
||
users see nothing.
|
||
5. Archive `benstull/rfc-app-flotilla` stub (empty placeholder
|
||
that contradicts SPEC §3.1's "no benstull mirror for flotilla"
|
||
rule).
|
||
|
||
**§19.2 candidates surfaced by M.2:**
|
||
1. Stop relying on Gitea path aliases — resolve canonical paths
|
||
at registry-update time so flotilla's SQLite registry doesn't
|
||
silently chase Gitea redirects after a transfer.
|
||
2. Concrete `flotilla-core` reservation slot (the
|
||
`benstull/rfc-app-flotilla` stub repo is an accidental artifact
|
||
of this need).
|
||
3. Promote `~/git/ohm-infra/` to a real git repo — currently a
|
||
plain directory; transcripts publish to the remote
|
||
`wiggleverse/ohm-session-history` but the runbooks, proposals,
|
||
and protocol doc that live in ohm-infra have no version
|
||
control.
|
||
|
||
**Open questions for the operator** (the proposal lists six;
|
||
the load-bearing ones):
|
||
- **Q1**: per-RFC repos vs monorepo — settles whether step 2 above
|
||
happens at all, and may reshape the proposal entirely.
|
||
- **Q2**: mirror destination after rfc-app moves.
|
||
- **Q3**: fate of the `benstull/rfc-app-flotilla` stub (the
|
||
proposal recommends archive; operator confirm).
|
||
- **Q4**: promote ohm-infra/ to a real repo (yes? then where?).
|
||
- **Q5**: remove the `ben` username alias.
|
||
- **Q6**: backup ohm-infra/ before execution session begins.
|
||
|
||
**Artifacts written by M.2:**
|
||
- `~/git/ohm-infra/REPO-NAMING-PROPOSAL.md` (~33 KB).
|
||
- `~/git/ohm-infra/SESSION-0013.2-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-37.md`.
|
||
|
||
Zero remote git operations. No Gitea admin actions. Clean
|
||
inventory + proposal pass per scope.
|
||
|
||
### Arc 3 — M.3 returns: #20 + #18 deliverability & webhook hardening
|
||
|
||
M.3 completed at 2026-05-28T05-58 PST (~28 min). Full detail:
|
||
`SESSION-0013.3-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-58.md`.
|
||
|
||
**Load-bearing finding (top of operator's plate)**: `SMTP_HOST`
|
||
and `SMTP_USER` are MISSING from the live flotilla overlay. Only
|
||
`SMTP_PORT=587`, `SMTP_STARTTLS=1`, `EMAIL_FROM`, `EMAIL_FROM_NAME`
|
||
are present. Either the bootstrap was reshaped post-run and these
|
||
dropped, OR they live on the VM out-of-band via systemd override.
|
||
**If neither holds, every OHM email path is silently failing
|
||
right now** (OTC, beta-access notifications, per-RFC owner invites,
|
||
admin-create user invites — all four paths added across v0.7.0 →
|
||
v0.17.0). Operator disambiguates next session via
|
||
`gcloud ssh ohm-app` + `systemctl show ohm-app.service | grep Environment`.
|
||
|
||
**Current DNS posture (`wiggleverse.org`, literal values):**
|
||
- SPF: `v=spf1 include:_spf.google.com ~all` (soft-fail)
|
||
- DMARC: `v=DMARC1; p=none; rua=mailto:ben@wiggleverse.org`
|
||
(monitoring-only, no enforcement)
|
||
- DKIM: present at `google._domainkey.wiggleverse.org`
|
||
(2048-bit Workspace key)
|
||
- MX: standard Google Workspace `aspmx.l.google.com` family
|
||
|
||
**SMTP provider identified:** Google Workspace SMTP relay
|
||
(`smtp-relay.gmail.com`) — inferred from bootstrap + DKIM + MX
|
||
(no direct confirmation since `SMTP_HOST` is missing from the
|
||
overlay).
|
||
|
||
**Top 3 deployment-side hardening gestures (priority order):**
|
||
1. **Delete stale `wiggleverse/meta` Gitea hook** — still active,
|
||
points at `http://rfc.wiggleverse.org/api/webhooks/gitea`
|
||
(host was deprovisioned 2026-05-27, plain HTTP). 5-second
|
||
`curl DELETE`. Trivial cleanup.
|
||
2. **Disambiguate the SMTP_HOST gap** (see load-bearing finding
|
||
above). Highest user impact if email is actually silently
|
||
broken.
|
||
3. **DMARC Phase A** — extend the existing `p=none` record with
|
||
`pct=100; sp=quarantine; adkim=s; aspf=s`, collect `rua` data
|
||
for 1 week, flip to `p=quarantine`. Conservative enforcement
|
||
ramp.
|
||
|
||
**Top 3 framework-side changes (target rfc-app v0.18.0):**
|
||
1. **`build_envelope` shared helper** — adds `Date`, `Message-ID`,
|
||
`Auto-Submitted: auto-generated`, `List-Unsubscribe` +
|
||
`List-Unsubscribe-Post` (per RFC 8058), and
|
||
`multipart/alternative` text+html to all four email paths
|
||
(`email_otc.py`, `email_invite.py`, `email.py:_deliver`,
|
||
`email.py:_send_bundle`). Today: NONE of these headers are
|
||
set; bodies are plain-text-only; Gmail's one-click-unsubscribe
|
||
enforcement is unsatisfied for bulk-adjacent watcher
|
||
notifications.
|
||
2. **Make `GITEA_WEBHOOK_SECRET` required, not optional.**
|
||
`config.py:75` is `_optional`; `webhooks.py:43` silently
|
||
accepts unsigned POSTs when empty. Insecure-by-default for any
|
||
deployment that forgets the binding. Add `RFC_APP_INSECURE_WEBHOOKS=1`
|
||
dev-bypass for local dev only.
|
||
3. **`outbound_emails` audit table + write on every send.**
|
||
Today failures log-and-forget; operator has zero visibility
|
||
without grepping VM logs. The audit table seam doubles as a
|
||
place to wire bounce-handling later.
|
||
|
||
**Webhook posture audit:** signature verification is correct
|
||
(`hmac.compare_digest`, HMAC-SHA-256 over raw body) **when the
|
||
secret is set** — and on OHM it is. Two structural issues:
|
||
(a) silent-accept-when-unset default; (b) no replay-window
|
||
(currently mitigated by idempotent cache refreshes, so not yet
|
||
exploited but worth a §19.2 candidate or follow-up rfc-app minor).
|
||
|
||
M.3 also noted: `wiggleverse/rfc-0001-human` has NO Gitea webhook
|
||
configured (the only published RFC's content changes only reach
|
||
OHM via the reconciler). Operator confirms whether this is
|
||
intentional. Bot lacks admin on `ben.stull/ohm-rfc` (the pin
|
||
source), so M.3 couldn't self-check that one.
|
||
|
||
**§19.2 candidates surfaced by M.3 (5):**
|
||
1. rfc-app: `GITEA_WEBHOOK_SECRET` should be required.
|
||
2. rfc-app: outbound-email observability seam (audit table).
|
||
3. flotilla: `overlay show` doesn't surface expected-but-missing
|
||
keys; needs `overlay validate` verb.
|
||
4. flotilla: lacks a `webhook list/check` verb (generic, would
|
||
land in `flotilla-core` after extraction per §19.2).
|
||
5. rfc-app: From-identity spec to bind `EMAIL_FROM` consumers +
|
||
DMARC + Workspace allowed-senders to one source.
|
||
|
||
**Artifacts written by M.3:**
|
||
- `~/git/ohm-infra/EMAIL-AND-WEBHOOK-HARDENING-RUNBOOK.md` (~21 KB).
|
||
- `~/git/ohm-infra/RFC-APP-EMAIL-HYGIENE-PROPOSAL.md` (~9 KB).
|
||
- `~/git/ohm-infra/SESSION-0013.3-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-58.md`.
|
||
|
||
Read-only DNS / flotilla-overlay / rfc-app code inventory. Zero
|
||
DNS edits, zero overlay set, zero code commits. Clean per scope.
|
||
|
||
### Arc 4 — M.1 returns (with a stall): #19 + #21B docs landed
|
||
|
||
M.1 hit the stream watchdog at 600s-no-progress and the agent was
|
||
killed before it could return its report. Its own transcript says
|
||
end-time 05:40 PST — meaning it wrote the transcript ~10 minutes
|
||
into its run, then spent another ~50 minutes in a "sanity check
|
||
before reporting back" phase that produced no streamable output and
|
||
got watchdog-killed.
|
||
|
||
Per protocol §5.5 the driver MAY write a stub if a subagent fails to
|
||
produce a transcript. M.1 did produce a transcript (full 460-line
|
||
detailed shape, all the synthesis the driver needs); the stall was
|
||
on the report-back-to-driver step. Driver chose **no re-dispatch**:
|
||
all deliverables landed cleanly on disk, both feature branches
|
||
pushed to canonical (rfc-app to origin + benstull, ohm-rfc to
|
||
origin), tree clean. Recovery was: read M.1's transcript directly
|
||
+ switch the two repos back to `main` (M.1 left them on the feature
|
||
branches) + fold synthesis into this transcript.
|
||
|
||
**Pre-state addendum surfaced by M.1's own pre-state**: ohm-rfc
|
||
`main` was at `8cce148` when M.1 opened at 05:30, but this
|
||
driver's pre-state at 05:26 (above) recorded ohm-rfc `main` at
|
||
`47cb2f9`. The operator pushed `8cce148 ROADMAP: +#23 (rename
|
||
transcripts SESSION-<letter> → SESSION-NNNN.M)` to ohm-rfc/main in
|
||
the 4-minute gap between session-open and M.1 dispatch. Recorded
|
||
honestly here per the protocol's no-curation rule — this is the
|
||
Session-L "don't batch roadmap captures to end-of-session" lesson
|
||
applied in real time. **Roadmap item #23 now exists** (transcript-
|
||
filename rename) and is captured on ohm-rfc/main outside of any
|
||
Session-M subagent's scope.
|
||
|
||
**M.1 deliverables (all on feature branches, none merged):**
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| `rfc-app` `feature/contributing-and-spec-analytics` | `213f686 docs: CONTRIBUTING.md + SPEC.md §21 analytics chapter`. Pushed to `origin` + `benstull`. |
|
||
| `ohm-rfc` `feature/contributing-roadmap-guide` | `f26fae4 CONTRIBUTING: add roadmap-change guide + operator-only boundary`. Pushed to `origin`. |
|
||
|
||
`rfc-app/CONTRIBUTING.md` is new, ~370 lines, covering: PR shape,
|
||
strict-descending CHANGELOG convention, RFC 2119 `Upgrade steps:`
|
||
discipline, §19.2 candidate practice, test-coverage expectations
|
||
characterized from the real ~250-test backend suite, the operator-
|
||
only-gestures boundary (with the hard no-secret-bytes rule cited
|
||
from Session 0011.0 Arc 6), and the #21 Part B analytics-instrumentation
|
||
checklist as a dedicated section. Worked-example links to Sessions
|
||
E (clean small release), I (deploy-fault recovery), K (multi-feature
|
||
wave + paused-on-secret), L (squash-merge across three parallel
|
||
features + #21 Part C inline). Links to the repo root not specific
|
||
transcript filenames — anticipating the #23 rename.
|
||
|
||
`rfc-app/SPEC.md` gets new §21 "Analytics instrumentation and
|
||
identity", ~440 lines, structured §21.1 event-taxonomy → §21.2
|
||
required prop families → §21.3 autocapture-friendly DOM patterns
|
||
→ §21.4 session-replay masking → §21.5 consent-gate contract →
|
||
§21.6 identity lifecycle (#21 Part C) → §21.6.1 set vs setOnce
|
||
taxonomy → §21.7 cohort-shape implications → §21.8 secret-vs-public
|
||
framing → §21.9 §19.2 candidates → §21.10 open question. RFC 2119
|
||
keywords used precisely throughout. The starting v0.17.0 taxonomy
|
||
(13 events) laid out verbatim.
|
||
|
||
**Placement decision the driver should weigh in on:** M.1 settled
|
||
inline on placing the new chapter as §21 (after §20 versioning)
|
||
rather than §16 (the naively-correct insertion-after-§15
|
||
notifications). Rationale: §19.2 is a load-bearing project noun
|
||
(in CLAUDE.md, SESSION-PROTOCOL.md §3, 12 published transcripts,
|
||
historical commit messages) — renumbering would cascade across all
|
||
of those. §15 now carries a forward-pointer naming §21 as the peer
|
||
cross-cutting analytics chapter. The driver agrees with M.1's call:
|
||
the right §16 numbering belongs to a future cross-repo cleanup
|
||
session, NOT a docs-PR. Flagged as §19.2 candidate #1 from M.1
|
||
(see below).
|
||
|
||
`ohm-rfc/CONTRIBUTING.md` extends the existing 130-line RFC-content
|
||
guide (preserved verbatim) with a new "Proposing a change to the
|
||
OHM roadmap" section (~80 added lines). Covers: roadmap-change
|
||
kinds, ohm-session-history pointer + worked-example links into
|
||
Sessions J/K/L roadmap reshuffles, PR-submission gesture with the
|
||
**anonymous-PR open question SETTLED inline** (see Arc 5 below),
|
||
the operator-only-gestures boundary phrased with the "I'm the only
|
||
one that gets to yolo" quote, the two-layer rule.
|
||
|
||
### Arc 5 — Anonymous-PR question settlement (M.1 inline)
|
||
|
||
M.1 probed `https://git.wiggleverse.org/user/sign_up` and got HTTP
|
||
200 with body containing `<p>Registration is disabled. Please
|
||
contact your site administrator.</p>`. Definitive answer.
|
||
|
||
The ohm-rfc CONTRIBUTING text settles on two contributor paths:
|
||
Issue-first (default; the operator or next driver session turns it
|
||
into a roadmap entry or opens discussion in the issue thread), or
|
||
request-account-from-operator (for repeat contributors). Phrased so
|
||
the operator can edit down to one path if registration policy
|
||
flips later.
|
||
|
||
### Arc 6 — Recovery + finalize
|
||
|
||
Driver switched rfc-app + ohm-rfc back to `main` (M.1 left them on
|
||
feature branches; `git checkout main` on each — clean, "up to date
|
||
with origin/main"). Marked M.1 task completed with a description
|
||
recording the stall + recovery decision. Wrote this turn-by-turn,
|
||
cut state, §19.2 ledger, operator plate, next-session prompt.
|
||
Renamed transcript INPROGRESS → final timestamp. About to publish
|
||
all four transcripts (M + M.1 + M.2 + M.3) via
|
||
`~/git/ohm-infra/scripts/publish-transcript.sh` per §5.6.
|
||
|
||
### Arc 7 — Publish-script validator extension (in-scope plumbing)
|
||
|
||
First attempt to publish M.1 failed:
|
||
`filename does not match SESSION-<letter>-TRANSCRIPT[-<start>--<end>].md`.
|
||
Investigation revealed a **protocol-vs-reality discrepancy**: both
|
||
the operator's brief ("the publish script's filename validator was
|
||
extended in Session 0012.0 to accept `SESSION-<letter>.<n>-TRANSCRIPT-…md`")
|
||
and SESSION-PROTOCOL.md §5.6 ("The publish script's filename
|
||
validator accepts the `SESSION-<letter>.<n>-TRANSCRIPT-…md` form
|
||
(extended Session-L, see `scripts/publish-transcript.sh`)") said
|
||
the extension was already in place — but the actual regex in
|
||
`scripts/publish-transcript.sh` at L127 was still
|
||
`^SESSION-[A-Za-z]+-TRANSCRIPT(-${_TS}--${_TS})?\.md$`, and the
|
||
header check at L140 only accepted `Transcript` / `transcript`
|
||
endings, not `Subsession transcript`. The extension was documented
|
||
in Session 0012.0's protocol amendment but never landed in the script.
|
||
|
||
Driver made minimal-scope edits to fix:
|
||
- Filename regex: extended to `^SESSION-[A-Za-z]+(\.[0-9]+)*-TRANSCRIPT(-${_TS}--${_TS})?\.md$` (accepts `.N` and `.N.N` for hypothetical sub-subagents per §5.2's nested convention).
|
||
- Header regex: extended to accept `Subsession transcript` and `— Subsession transcript` forms; allow `.N` after the session letter.
|
||
- Updated the comment block at L123 and L131-135 to document the subsession form.
|
||
- Updated the error message at L128 to name `[.<n>]` explicitly.
|
||
|
||
Dry-ran M.1 to verify both validators pass against
|
||
`# Session 0013.1 — Subsession transcript`. Header OK. Then published
|
||
M.1 → M.2 → M.3 → M serially.
|
||
|
||
**Note on scope**: this script edit is in-scope plumbing for §5 being
|
||
operational at all — Session 0013.0 is the first session under §5, so the
|
||
validator gap had to be fixed before the wave could complete. The
|
||
change is small (regex extensions + comment/message updates only,
|
||
no logic changes), commented in the script, and the dry-run gesture
|
||
confirmed correctness before the real push. The script lives in
|
||
`~/git/ohm-infra/`, which is **not under version control** per M.2's
|
||
§19.2 candidate #7 — so this script change is on local disk only
|
||
with no history. That candidate is now more salient.
|
||
|
||
This driver-surfaced issue is captured below as §19.2 candidate #14
|
||
(reconcile protocol amendments with actual code changes — the
|
||
amendment should fail review if the code change isn't also present).
|
||
|
||
### Arc 8 — Post-publish close (operator-confirmed at ~07:00 PST)
|
||
|
||
After Arc 7's validator extension + serial publish of all four
|
||
transcripts (M.1 @ `7c7c478` → M.2 @ `5dad1b2` → M.3 @ `2007cf3`
|
||
→ M @ `61698af`), driver re-published M with the Arc 7 + §19.2
|
||
candidate #14 + script-edit-disclosure additions (final commit
|
||
`6248f88` on `wiggleverse/ohm-session-history` `main`).
|
||
|
||
Operator (returned ~07:00 PST, not asleep) confirmed close and
|
||
asked for: (1) the next-session prompt surfaced verbatim in chat
|
||
for easy copy, (2) the transcript updated with this final
|
||
exchange. Driver replied with the prompt printed in full (no
|
||
substantive change from the version embedded in this transcript
|
||
below in the "Prompt the operator can paste…" section; reproduced
|
||
verbatim for ergonomics), then added this Arc 8 + re-published
|
||
per the Session-L "transcript is the final session step" feedback
|
||
memory ("re-finalize if more work happens after").
|
||
|
||
Final state of this session matches the cut-state table below.
|
||
No code shipped to OHM. Two docs feature branches and three
|
||
ohm-infra/-local proposal/runbook docs are the deliverables that
|
||
become Wave 7's plate.
|
||
|
||
---
|
||
|
||
## Cut state (end of session, 2026-05-28T06-50 PST)
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| `rfc-app` | `main` unchanged at `1456c8b` (Release 0.17.0). New branch `feature/contributing-and-spec-analytics` at `213f686` pushed to `origin` + `benstull` — awaiting operator PR review. Local tree on `main`, clean. |
|
||
| `ohm-rfc` | `main` advanced from `47cb2f9` → `8cce148` mid-session (operator pushed #23). New branch `feature/contributing-roadmap-guide` at `f26fae4` pushed to `origin` — awaiting operator PR review. `.rfc-app-version` unchanged at `0.17.0`. Local tree on `main`, clean. |
|
||
| `ohm-rfc-app-flotilla` | unchanged at `65c0e55`. v1.0.1. |
|
||
| OHM live | unchanged from Session 0012.0 cut — `deploys.id=21`, v0.17.0. No deploy gesture this session. |
|
||
| `ohm-infra` (local dir) | 4 new files this session: this transcript + M.1/M.2/M.3 subsessions. Plus 2 inventory/runbook docs from M.2 (`REPO-NAMING-PROPOSAL.md`) and 2 from M.3 (`EMAIL-AND-WEBHOOK-HARDENING-RUNBOOK.md`, `RFC-APP-EMAIL-HYGIENE-PROPOSAL.md`). |
|
||
|
||
| Wave 6 ledger | Status |
|
||
| --- | --- |
|
||
| #19 CONTRIBUTING guides (rfc-app + ohm-rfc) | 🟡 drafts pushed on feature branches; awaiting operator PR review + merge |
|
||
| #21 Part B SPEC.md §21 chapter + CONTRIBUTING checklist | 🟡 drafted on rfc-app feature branch (rides #19's commit); awaiting operator review |
|
||
| #17 Repo naming + location alignment (inventory + proposal) | 🟡 proposal doc written at `~/git/ohm-infra/REPO-NAMING-PROPOSAL.md`; six open questions for operator; execution session deferred |
|
||
| #20 Email deliverability inventory | 🟡 runbook written; one load-bearing finding (SMTP_HOST possibly missing from overlay); awaiting operator disambiguation + DNS edits |
|
||
| #18 SMTP relay + Gitea webhook hardening inventory | 🟡 runbook same as #20 (bundled); webhook code-side proposal in `RFC-APP-EMAIL-HYGIENE-PROPOSAL.md`; awaiting future rfc-app v0.18.0 minor + ops gestures |
|
||
| #21 Part A audit | ⏸ blocked — needs ~1 week of Amplitude data; v0.17.0 is <12h old |
|
||
| #22 Pro-analytics-consent copy | ⏸ blocked — waiting on operator-drafted + counsel-reviewed copy |
|
||
| #1 VM rename | ⏸ operator-led ops gesture |
|
||
| #23 Transcript filename rename (`SESSION-<letter>` → `SESSION-NNNN.M`) | ✅ added to ROADMAP (ohm-rfc/main `8cce148`, operator pushed mid-session) |
|
||
|
||
No rfc-app release shipped this wave; that's Wave 6's intended shape
|
||
(set-up wave — deliverables become Wave 7's plate). The plate is
|
||
heavy and clearly-named.
|
||
|
||
---
|
||
|
||
## §19.2 candidates surfaced this session
|
||
|
||
From **M.1**:
|
||
1. **SPEC.md §16..§20 renumbering vs. §21-at-end placement.** The
|
||
chapter went in as §21 not §16 to preserve the §19.2 / §19.3
|
||
cross-reference graph; a future cleanup session can do the
|
||
numerically-clean §16 insertion + cascade across CLAUDE.md
|
||
files + SESSION-PROTOCOL.md + 12 transcripts + auto-memory.
|
||
2. **Centralized email-hash helper** (SHA-256 of normalized lower-
|
||
cased email for #12-style per-RFC `target_email` hashing).
|
||
3. **Property-shape CI lint** for `track(` / `identify(` callsites
|
||
(allowlist of prop keys, denylist of PII names).
|
||
4. **Frontend test runner** (no `vitest`/`jest`/`playwright` today;
|
||
the CONTRIBUTING file documents the gap honestly).
|
||
|
||
From **M.2**:
|
||
5. **Stop relying on Gitea path aliases** — resolve canonical paths
|
||
at registry-update time so flotilla's SQLite registry doesn't
|
||
silently chase Gitea redirects after a transfer.
|
||
6. **Concrete `flotilla-core` reservation slot** — the
|
||
`benstull/rfc-app-flotilla` stub is an accidental artifact of
|
||
this latent need.
|
||
7. **Promote `~/git/ohm-infra/` to a real git repo** — currently a
|
||
plain directory; transcripts publish to the remote but runbooks,
|
||
proposals, and the protocol doc have no local version control.
|
||
|
||
From **M.3**:
|
||
8. rfc-app: `GITEA_WEBHOOK_SECRET` should be **required**, not
|
||
`_optional`. Insecure-by-default for any deployment that forgets
|
||
the binding.
|
||
9. rfc-app: **outbound-email observability seam** (`outbound_emails`
|
||
audit table + write on every send). Today failures log-and-
|
||
forget; doubles as bounce-handling hook later.
|
||
10. flotilla: `overlay show` doesn't surface expected-but-missing
|
||
keys; needs an `overlay validate` verb. (The session's own
|
||
headline finding — possibly-missing SMTP_HOST — would have been
|
||
a one-command detection if this existed.)
|
||
11. flotilla: lacks a `webhook list/check` verb (generic — would
|
||
land in `flotilla-core` after §19.2 extraction).
|
||
12. rfc-app: **From-identity spec** to bind `EMAIL_FROM` consumers
|
||
+ DMARC + Workspace allowed-senders to one source.
|
||
|
||
Driver-surfaced (this transcript):
|
||
13. **Subagent stream-watchdog stall pattern.** M.1 finished its
|
||
work + transcript at minute ~10 but spent ~50 more minutes in a
|
||
quiet "sanity check" phase before the watchdog killed it. The
|
||
session-protocol §5.3 instruction says transcript-write happens
|
||
BEFORE report-back — that's load-bearing, since the report-back
|
||
is where the agent dies. Worth a protocol clarification:
|
||
"transcript first; report-back is the only thing after; do NOT
|
||
add a 'final sanity check' phase between — sanity-check
|
||
findings go into the transcript." Or alternatively, a
|
||
documented expectation that the driver always re-verifies
|
||
deliverables on disk and doesn't depend on the report-back text
|
||
alone.
|
||
14. **Protocol amendments must land with the code change.** Session 0012.0
|
||
documented in SESSION-PROTOCOL.md §5.6 that the publish script's
|
||
validator was extended to accept `SESSION-<letter>.<n>-TRANSCRIPT-…md`,
|
||
and the Session 0013.0 brief repeated the claim. Reality at session
|
||
open: the script's regex hadn't been modified. Driver had to
|
||
extend it mid-Session-M to publish the subsession transcripts at
|
||
all (see Arc 7). Worth a discipline: an amendment to the
|
||
protocol that claims a code change MUST also include the code
|
||
change in the same merge (or be marked "pending implementation"
|
||
in the protocol text). Plus: amendment review should diff the
|
||
protocol claim against the named code surface and reject if
|
||
they don't match. This is a Session 0013.0 lesson; would land in
|
||
SESSION-PROTOCOL.md §6 ("when the protocol is unclear") as a
|
||
sub-paragraph.
|
||
|
||
---
|
||
|
||
## What lands on the operator's plate
|
||
|
||
In rough priority order (driver's read):
|
||
|
||
### URGENT — investigate before any further Wave 7 work
|
||
|
||
1. **Disambiguate the SMTP_HOST / SMTP_USER overlay gap** (M.3
|
||
finding). Run `gcloud ssh ohm-app` + `systemctl show
|
||
ohm-app.service | grep Environment` to check whether they're set
|
||
via systemd override. If not, OHM has been silently dropping
|
||
every email (OTC, beta-access notifications, per-RFC invites,
|
||
admin-create invites) — meaning v0.7.0 / v0.9.0 / v0.16.0 /
|
||
v0.17.0's user-facing email features are degraded since deploy.
|
||
Send a manual test through the admin "Create user + invite"
|
||
flow as a probe.
|
||
|
||
### HIGH — review + merge the docs PRs
|
||
|
||
2. **rfc-app PR** for `feature/contributing-and-spec-analytics` at
|
||
`213f686`. Suggested PR description in
|
||
`SESSION-0013.1-TRANSCRIPT-…md` What-the-driver-needs-to-know #6.
|
||
Open on:
|
||
- `https://git.wiggleverse.org/ben.stull/rfc-app/pulls/new/feature/contributing-and-spec-analytics`
|
||
- `https://git.benstull.org/benstull/rfc-app/pulls/new/feature/contributing-and-spec-analytics`
|
||
Operator decides §21-vs-§16 placement — driver concurs with M.1's
|
||
§21 call (don't break the §19.2 cross-reference graph).
|
||
|
||
3. **ohm-rfc PR** for `feature/contributing-roadmap-guide` at
|
||
`f26fae4`. Description also in M.1's transcript. Open on:
|
||
- `https://git.wiggleverse.org/ben.stull/ohm-rfc/pulls/new/feature/contributing-roadmap-guide`
|
||
|
||
### MEDIUM — schedule + decide
|
||
|
||
4. **#17 repo naming proposal** at `~/git/ohm-infra/REPO-NAMING-PROPOSAL.md`.
|
||
Six open questions in the proposal that need operator input
|
||
before the execution session can be scoped. Q1 (per-RFC repos
|
||
vs monorepo) may reshape the proposal entirely; resolve first.
|
||
|
||
5. **#20 + #18 deliverability runbook** at
|
||
`~/git/ohm-infra/EMAIL-AND-WEBHOOK-HARDENING-RUNBOOK.md`.
|
||
Once #1 above is settled, this is the priority-ordered list of
|
||
operator gestures. Top three:
|
||
(a) `curl DELETE` the stale `wiggleverse/meta` Gitea webhook
|
||
pointing at deprovisioned `http://rfc.wiggleverse.org`;
|
||
(b) DMARC Phase A (`pct=100; sp=quarantine; adkim=s; aspf=s`);
|
||
(c) confirm `wiggleverse/rfc-0001-human` has no webhook (M.3
|
||
noted absence — intentional or oversight?).
|
||
|
||
6. **rfc-app v0.18.0 minor** is now the natural next release —
|
||
carries the framework-side hardening from M.3:
|
||
`build_envelope` shared helper (Date/Message-ID/Auto-Submitted/
|
||
List-Unsubscribe headers + multipart text+html); required
|
||
`GITEA_WEBHOOK_SECRET`; `outbound_emails` audit table.
|
||
Proposal doc at `~/git/ohm-infra/RFC-APP-EMAIL-HYGIENE-PROPOSAL.md`.
|
||
|
||
### LOW / informational
|
||
|
||
7. **#23 transcript filename rename** is on ROADMAP now (operator
|
||
pushed `8cce148`). This session is the last to use the
|
||
`SESSION-<letter>` convention before #23 ships; future sessions
|
||
will name as `SESSION-NNNN.M` per the new spec.
|
||
|
||
8. **Stale Session-L INPROGRESS file** at
|
||
`~/git/ohm-infra/SESSION-0012.0-TRANSCRIPT-2026-05-28T04-22--INPROGRESS.md`
|
||
(4.3 KB). Final L transcript is published; this is a placeholder
|
||
that can be deleted. Driver did NOT delete (operator's call).
|
||
|
||
9. **Three rfc-app worktrees from Session 0012.0** still on disk:
|
||
`~/git/rfc-app-v0.15.0-amplitude/`, `~/git/rfc-app-v0.16.0-owner-invite/`,
|
||
`~/git/rfc-app-v0.17.0-admin-create-user/`. All shipped + merged.
|
||
Cleanup via `git worktree remove` at the operator's convenience.
|
||
|
||
10. **§19.2 candidate #13** (subagent stream-watchdog stall pattern)
|
||
is a candidate protocol clarification for SESSION-PROTOCOL.md §5
|
||
— see the candidates list above.
|
||
|
||
11. **`scripts/publish-transcript.sh` was edited mid-session** to
|
||
actually extend the filename + header validators for the §5
|
||
subsession form (Session 0012.0 documented the extension but never
|
||
landed it). The script lives in `~/git/ohm-infra/` which is
|
||
not version-controlled, so the change has no commit history.
|
||
Driver-applied diff: regex `^SESSION-[A-Za-z]+-TRANSCRIPT…`
|
||
→ `^SESSION-[A-Za-z]+(\.[0-9]+)*-TRANSCRIPT…`; header regex
|
||
extended to accept `Subsession transcript` and `— Subsession
|
||
transcript` endings plus `.N` after the letter. Worked
|
||
correctly for all three subsession transcripts. Captured as
|
||
§19.2 candidate #14 (protocol amendments must land with the
|
||
code change). M.2's §19.2 candidate #7 (promote ohm-infra/ to
|
||
a real git repo) becomes more salient — this script change is
|
||
not under version control.
|
||
|
||
---
|
||
|
||
## Prompt the operator can paste into the next Claude Code session
|
||
|
||
```
|
||
You are the OHM roadmap driver. The previous session (Session 0013.0)
|
||
ran Wave 6 as three Track Ω inventory/draft subsessions in parallel
|
||
(M.1 / M.2 / M.3) under the new §5 subsession-transcript convention.
|
||
|
||
**What Session 0013.0 produced:**
|
||
- Two docs feature branches awaiting your PR review:
|
||
- rfc-app `feature/contributing-and-spec-analytics` at `213f686`
|
||
(CONTRIBUTING.md + SPEC.md §21 analytics chapter, lands #19 +
|
||
#21 Part B; placed §21 not §16 to preserve the §19.2 cross-
|
||
reference graph — driver concurs with M.1's call)
|
||
- ohm-rfc `feature/contributing-roadmap-guide` at `f26fae4`
|
||
(CONTRIBUTING extension covering roadmap changes + operator-
|
||
only boundary)
|
||
- Three new docs on disk at `~/git/ohm-infra/`:
|
||
- `REPO-NAMING-PROPOSAL.md` (#17 inventory + proposal; six open
|
||
questions need your input)
|
||
- `EMAIL-AND-WEBHOOK-HARDENING-RUNBOOK.md` (#18 + #20 deployment-
|
||
side gestures, prioritized)
|
||
- `RFC-APP-EMAIL-HYGIENE-PROPOSAL.md` (#18 + #20 framework-side
|
||
minor proposal — target rfc-app v0.18.0)
|
||
|
||
**URGENT to investigate FIRST**: M.3 found `SMTP_HOST` + `SMTP_USER`
|
||
missing from the live flotilla overlay. If they aren't being set
|
||
via systemd override on the VM, every OHM email path (OTC,
|
||
beta-access notifications, per-RFC invites, admin-create invites
|
||
— v0.7.0/v0.9.0/v0.16.0/v0.17.0) has been silently dropping mail
|
||
since the relevant deploy. First gesture: `gcloud ssh ohm-app` +
|
||
`systemctl show ohm-app.service | grep Environment` to check. If
|
||
broken, send a probe through the "admin create user + invite"
|
||
flow.
|
||
|
||
**Wave 7 candidates (priority order):**
|
||
1. **Investigate + fix SMTP gap** (above) — possibly an ops-only
|
||
gesture if systemd override is sufficient; possibly an rfc-app
|
||
minor if the email-send code needs a defensive change.
|
||
2. **Operator reviews + merges the two docs PRs from Session 0013.0**
|
||
(no version bump for either; lands as no-bump docs commits).
|
||
3. **rfc-app v0.18.0** — framework-side hardening from
|
||
`RFC-APP-EMAIL-HYGIENE-PROPOSAL.md`: `build_envelope` shared
|
||
helper (Date/Message-ID/Auto-Submitted/List-Unsubscribe headers
|
||
+ multipart text+html for all four email paths); make
|
||
`GITEA_WEBHOOK_SECRET` required (no longer `_optional`);
|
||
`outbound_emails` audit table. Add `RFC_APP_INSECURE_WEBHOOKS=1`
|
||
dev-bypass for local dev only.
|
||
4. **#17 execution session** — needs Q1 (per-RFC repos vs monorepo)
|
||
answered first; then operator runs the moves per
|
||
`REPO-NAMING-PROPOSAL.md`.
|
||
5. **#20 deployment-side gestures** — DMARC Phase A (`pct=100;
|
||
sp=quarantine; adkim=s; aspf=s`), then ramp to `p=quarantine`
|
||
after a week of `rua` data; delete stale `wiggleverse/meta`
|
||
Gitea hook pointing at deprovisioned rfc.wiggleverse.org.
|
||
6. **#22** — operator drafts + counsel-reviews the pro-analytics-
|
||
consent copy; subagent wires it in once approved.
|
||
7. **#21 Part A** — earliest reasonable target ~2026-06-04 (one
|
||
week of Amplitude data post-v0.17.0). Defer until then.
|
||
8. **#1 VM rename** — operator-led ops gesture, schedule a
|
||
maintenance window.
|
||
9. **#23 transcript filename rename** — on ROADMAP at `8cce148`;
|
||
pick a session to execute the rename across all 13 published
|
||
transcripts + the publish script's filename validator.
|
||
|
||
**Hard rules carried forward from Sessions K + L + M:**
|
||
- Never EVER ask the operator to paste secret bytes into the
|
||
conversation. Always give the operator-run gesture (`pbpaste |
|
||
flotilla secret set <deployment> <KEY>`). Public bundle-embedded
|
||
values (VITE_AMPLITUDE_API_KEY, VITE_TURNSTILE_SITE_KEY) are fine
|
||
in-conversation via `flotilla overlay set`.
|
||
- Subagent stream-watchdog stalls (Session 0013.0 new): subagents
|
||
MUST write their transcript BEFORE returning a report (already
|
||
in §5.3) — and SHOULD NOT add a "final sanity check" phase
|
||
between transcript-write and report-back (where M.1 died).
|
||
Driver should always re-verify deliverables on disk rather
|
||
than depend on the report-back text alone.
|
||
- §5 subsession-transcript convention is binding from Session 0013.0
|
||
onward.
|
||
|
||
**Cut state at handoff:**
|
||
- rfc-app `main` at `1456c8b` (v0.17.0)
|
||
- ohm-rfc `main` at `8cce148` (#23 added by operator mid-Session-M)
|
||
- ohm-rfc-app-flotilla `main` at `65c0e55` (v1.0.1)
|
||
- ohm-rfc `.rfc-app-version` = `0.17.0`
|
||
- OHM live: deploys.id=21, v0.17.0
|
||
- Two feature branches awaiting your PR review (above)
|
||
- Next session letter: **N**
|
||
|
||
Read `~/git/ohm-infra/SESSION-PROTOCOL.md` and
|
||
`/Users/benstull/projects/wiggleverse/ohm-rfc/ROADMAP.md`
|
||
end-to-end. Then pick Wave 7's shippable scope.
|
||
```
|
||
|
||
|
||
---
|
||
|
||
(Cut state, §19.2 candidates, operator plate, and next-session
|
||
prompt all written at session-end.)
|