From 7c7c478273dcbbd522838ac51ae5d117e4b81e94 Mon Sep 17 00:00:00 2001 From: Ben Stull Date: Thu, 28 May 2026 06:54:22 -0700 Subject: [PATCH] add SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md --- ...RIPT-2026-05-28T05-30--2026-05-28T05-40.md | 460 ++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md diff --git a/SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md b/SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md new file mode 100644 index 0000000..6dde7d6 --- /dev/null +++ b/SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md @@ -0,0 +1,460 @@ +# Session M.1 — Subsession transcript + +> Parent: `SESSION-M-TRANSCRIPT-2026-05-28T05-26--.md` +> Date: 2026-05-28 +> Goal: Draft `rfc-app/CONTRIBUTING.md`, the `rfc-app/SPEC.md` analytics chapter, +> and the `ohm-rfc/CONTRIBUTING.md` roadmap-guide extension — landing roadmap +> items #19 (CONTRIBUTING guides + transcript-linked onboarding) and #21 Part B +> (standing analytics instrumentation discipline). Push feature branches; do +> NOT tag, do NOT bump VERSION, do NOT move the pin, do NOT deploy. +> +> Outcome: **All three deliverables shipped on feature branches; both branches +> pushed to canonical remotes; one open question settled inline.** +> +> - `rfc-app feature/contributing-and-spec-analytics` at `213f686` — +> pushed to `origin` (git.wiggleverse.org) + `benstull` +> (git.benstull.org). One commit: CONTRIBUTING.md (new, ~370 lines) + +> SPEC.md §21 (new chapter, ~470 lines including the new §15 forward- +> pointer to §21). +> - `ohm-rfc feature/contributing-roadmap-guide` at `f26fae4` — pushed +> to `origin` (git.wiggleverse.org, the only remote). One commit: +> CONTRIBUTING.md extended with a new "Proposing a change to the OHM +> roadmap" section (~80 added lines on top of the existing 130-line +> RFC-content guide). +> - Open question on Gitea anonymous-PR posture: **settled inline** — +> `https://git.wiggleverse.org/user/sign_up` returns "Registration is +> disabled. Please contact your site administrator." The +> ohm-rfc CONTRIBUTING text reflects this with two paths (Issue-first +> default + request-account for repeat contributors) and is phrased so +> the operator can update if registration policy changes. + +--- + +## Pre-subsession state + +- **rfc-app**: `main` at `1456c8b` (Release 0.17.0). Tags through + v0.17.0. No CONTRIBUTING.md existed. `SPEC.md` 4302 lines, chapter + sequence §1..§20. +- **ohm-rfc**: `main` at `8cce148`. `.rfc-app-version` = `0.17.0`. + `CONTRIBUTING.md` existed (130 lines, RFC-content guide); no + roadmap-change section. +- **ohm-infra (local)**: most recent transcripts Session L + (`SESSION-L-TRANSCRIPT-2026-05-28T04-22--2026-05-28T05-17.md`) + + Session M's main transcript in-progress + (`SESSION-M-TRANSCRIPT-2026-05-28T05-26--INPROGRESS.md`). +- **Branches at start**: both repos on `main`, both clean working trees. + +--- + +## Turn-by-turn arc + +### Arc 1 — Reconnaissance + +Read in order: `ohm-rfc/ROADMAP.md` (#19 at L405-456, #21 at L549-731, +particularly Part B at L625-655 and Part C at L657-731); +`ohm-rfc/CONTRIBUTING.md` (existing 130-line file — RFC-content +oriented, no roadmap-change section); `ohm-infra/SESSION-PROTOCOL.md` +(§1 naming, §2 transcript shape, §5 subagent-transcript amendment — +binding for this subsession); +`ohm-infra/SESSION-K-TRANSCRIPT-…md` (whole file — clean-small- +release + multi-feature-wave + paused-on-secret patterns; the +Arc-6 hard-rule incident around secret bytes); +`ohm-infra/SESSION-L-TRANSCRIPT-…md` (whole file — squash-merge +integration with #21 Part C identity-lifecycle wiring folded inline +across three releases; the addendum cycles around "transcript is the +LAST step" discipline); +`rfc-app/SPEC.md` selectively (top, §15 around L2259-2732, §16 + §17 +boundaries, §19 around L3183, §20 ending around L4132-4302); the §15 +→ §16 transition was the candidate insertion-point for the new +analytics chapter; +`rfc-app/CHANGELOG.md` opening + the v0.17.0 / v0.16.0 / v0.15.0 +entries (lines 1-413) for the strict-descending convention and +RFC 2119 keyword usage examples; +`rfc-app/frontend/src/lib/analytics.js` end-to-end (the v0.15.0 +wrapper extended in Session L with `{ user_id, properties }` identify +signature, `applyProperties` with `__setOnce__` sentinel, +`setUserProperties`, anonymize-clears-cache); +`rfc-app/frontend/src/App.jsx` lines 40-90 (the App-level identify +call with viewer-derived `set` + `setOnce` property bag); +`rfc-app/frontend/src/components/InviteClaim.jsx` lines 40-90 (the +v0.17.0 identify-BEFORE-track pattern for the admin-create invite +claim). + +### Arc 2 — Placement decision for the SPEC chapter (settled inline) + +The roadmap (and the dispatch brief) said "Place AFTER §15 +notifications" and "numbering becomes §16 or whatever's next +available." The straightforward read is "insert as §16 and renumber +existing §16..§20 to §17..§21." A grep for `§16` through `§20` +references in SPEC.md surfaced 50+ cross-references across the file, +many of them to `§19.2` and `§19.3` specifically. + +§19.2 specifically is a load-bearing project noun: it's the +defer-decisions queue, named that way in CLAUDE.md, in +`SESSION-PROTOCOL.md` §3, in every session transcript ("§19.2 +candidates surfaced"), and in commit messages going back to Slice 5. +Renumbering §19 → §20 would invalidate every external reference and +require coordinated edits across at least: rfc-app CLAUDE.md, +ohm-rfc-app-flotilla CLAUDE.md, ohm-infra SESSION-PROTOCOL.md, all +12 published session transcripts, the auto-memory files. None of +those are within the scope of this subsession's docs-PR. + +The "or whatever's next available" hedge in the brief covers this +case. **Settled inline:** place the new chapter as §21 (after §20 +versioning), with a forward-pointer added at the end of §15's preamble +naming §21 as the peer cross-cutting analytics chapter. The new +chapter's opening explicitly states the placement reasoning so a +future reader knows why §21 isn't between §15 and §16. This is a +deliberate deferral of the "right" numbering to a future cleanup +session that scopes the cross-repo renumber properly — flagged in the +report-back to the driver. + +### Arc 3 — `rfc-app/CONTRIBUTING.md` draft + +Branched `rfc-app` at `feature/contributing-and-spec-analytics` off +`origin/main` at `1456c8b`. Drafted CONTRIBUTING.md (~370 lines) +covering, in order: + +- Project framing — what rfc-app is, what a deployment is, the + difference between framework-PR and content-PR. +- "How the project actually evolves" with explicit + wiggleverse/ohm-session-history pointer + worked-example links + into Sessions E (clean small release), I (recovery from deploy + fault), K (multi-feature wave + paused-on-secret), L (squash-merge + across three parallel features + #21 Part C wiring inline). The + session links are to the repo root rather than specific + transcript filenames so they don't break when transcripts get + renamed via roadmap #23. +- Contribution flow — Issue-first for structural changes, branch + naming convention (matched against the driver session's + `feature/v-` shape), explicit "do not bump VERSION, + do not tag, do not deploy, do not touch any .rfc-app-version pin." +- CHANGELOG strict-descending convention with a worked entry + template (mirroring v0.15.0/v0.16.0/v0.17.0 actual shapes) and + the operator-fills-version-at-merge-time note. +- RFC 2119 keyword discipline per SPEC §20.4 — MUST / MUST NOT / + SHOULD / SHOULD NOT / MAY — with the cross-version-upgrade + composition rule cited. +- §19.2 candidate discipline — explicit "don't scope-creep, name + the deferral." Cited v0.11.0's three new candidates (Session K) + and v0.15.0's two (Session L) as worked examples. +- Test-coverage expectations characterized from the actual + ~250-test backend suite. Named specific vertical files + (`test_admin_create_user_invite_vertical.py`, etc.) and the + `PYTHONPATH=. .venv/bin/pytest -q` ergonomic (still §19.2). Noted + that there is no frontend test runner today — the discipline is + build-clean + backend HTTP contract coverage. +- Analytics instrumentation checklist (the #21 Part B CONTRIBUTING + artifact bullet): (1) named events, (2) autocapture-friendly DOM, + (3) replay masking, (4) PR description discipline. Plus a + pointer to SPEC §21.6 identity-lifecycle contract for any new + claim/sign-in/invite path. +- Operator-only gestures explicitly enumerated, with the hard + no-secret-bytes-in-conversation rule named (Session K Arc 6 + origin cited). +- "When in doubt" closer. + +The CONTRIBUTING file uses MIT License as the rfc-app `LICENSE` +shape; checked `ls rfc-app/LICENSE` showed it exists. + +### Arc 4 — `rfc-app/SPEC.md` §21 chapter draft + +Appended new §21 "Analytics instrumentation and identity" (~440 +lines) at the end of SPEC.md (after §20.7), structured as: + +- §21 preamble — what this chapter codifies, framework-neutral + posture, the placement-as-§21 reasoning (the cross-ref-preservation + rationale from Arc 2). +- §21.1 event-taxonomy conventions — Title Case "Subject Verb", + stability + dashboard-name-match, opaque-ids-only-in-props, + casing consistency. The starting v0.17.0 taxonomy (13 events) + laid out verbatim. +- §21.2 required prop families — navigation / auth-state / authored- + action / admin-action / invite-side / claim-side. The hashed + target_email convention (SHA-256 of normalized lowercased email) + named for the #12 per-RFC invite case where the invitee isn't + yet a user. +- §21.3 autocapture-friendly DOM patterns — stable visible text, + aria-label on icon-only buttons, `data-amp-track-*` for repeated + rows, `data-amp-track-suppress` for noise surfaces, with a worked + HTML example. +- §21.4 session-replay masking — credentials MUST mask, PII SHOULD + mask, privacy-policy alignment MUST hold, selective redaction + preferred over whole-form. The `.amp-mask` / `data-amp-mask` + convention named with the qualifier "whichever the wrapper's SDK + version uses" (acknowledging that the Amplitude SDK's masking + attribute name has varied across versions; the wrapper's bootstrap + comment is the live source of truth). +- §21.5 consent-gate contract — five MUSTs: pre-consent no init/no + network/no recording; denied→granted init at consent moment; + granted→denied setOptOut(true) within one tick; no double-init on + re-grant; build-time env-var resolution with one-warn no-op when + unset. +- §21.6 identity lifecycle (per #21 Part C) — sign-in / + state-change / sign-out / invite-claim / inviter-side + identification, each with MUST language. The User-Signed-Out + track-BEFORE-anonymize ordering called out as load-bearing. +- §21.6.1 set vs setOnce taxonomy — explicit classification rule + with worked examples on each side (role / permission_state / + passcode_set / device_trusted = set; first_sign_in_at / + account_created_at / invited_by_admin_id / invited_at / + claim_method = setOnce). +- §21.7 cohort-shape implications (informative) — four worked + questions the dashboard can now answer with the conventions: + admin-invite vs OTC funnel by week; passcode-set rate in first + session by claim path; per-RFC owner-invited-contributor counts; + invite-send-to-claim gap by inviter. +- §21.8 secret-vs-public framing — overlay binding for the public + Amplitude key, secret binding for the Turnstile siteverify + secret half. The pbpaste-pipe canonical gesture for OHM-shape + deployments named. +- §21.9 §19.2 candidates surfaced — four (session-replay-specific + consent category; bundle-size budget measurement; property-shape + CI lint; centralized email-hash helper). +- §21.10 open question — consent-category split timing tied to the + next privacy-policy revision. + +Then added a forward-pointer paragraph at the end of §15's +preamble (the "section commits the surface..." paragraph) noting +§21 as the peer cross-cutting analytics chapter and explicitly +saying the two surfaces don't overlap (notifications = +signals-of-others-acting; analytics = observability of use). + +The chapter uses RFC 2119 keywords precisely throughout. No +"should probably" / "might want to" weasel-words inside MUST/ +SHOULD steps. Cited frontend/src/lib/analytics.js, App.jsx, +InviteClaim.jsx, AcceptInvitation.jsx as worked-example +references. + +### Arc 5 — `ohm-rfc/CONTRIBUTING.md` extension + +Branched `ohm-rfc` at `feature/contributing-roadmap-guide` off +`origin/main` at `8cce148`. Strategy: extend the existing +130-line RFC-content guide with a new section rather than create a +competing file. The existing sections (RFC discussions, RFC PR +format, RFC numbering, values, license) are preserved verbatim; +the roadmap-change section appends after the License block as a new +"Proposing a change to the OHM roadmap" heading + subsections. + +Section structure: + +- What kinds of roadmap changes are welcome (5 bullets — add, + reshape, claim a version slot, strike-through on ship, + §19.2 candidate at the OHM layer). +- How OHM actually evolves — wiggleverse/ohm-session-history + pointer + worked-example links into Sessions J (mid-build + version-slot reshuffle when docs-feature took v0.14.0), + K (mid-session capture of #16/#17/#18/#19), L (mid-build + capture of #20/#21/#22 + Part C wiring + #23). +- How to submit a roadmap PR — including the now-settled Gitea + registration-disabled question. +- The operator-only gestures — phrased with the operator's "I'm + the only one that gets to yolo" quote. Six bullets: flotilla + deploy, .rfc-app-version pin bump, secret-set, overlay-set on + OHM live, repo rename, Gitea account provisioning, PR merge. + Hard no-secret-bytes-in-conversation rule named. +- The two-layer rule — framework change → upstream rfc-app PR; + OHM-specific change → here. +- "When you're not sure" closer. + +### Arc 6 — Open question on Gitea registration posture, settled + +Per the dispatch brief, probed git.wiggleverse.org: + +- `https://git.wiggleverse.org/api/v1/version` returned + `{"version":"1.26.2"}` — confirming the instance is up. +- `https://git.wiggleverse.org/user/sign_up` returned HTTP 200 but + the body contained `

Registration is disabled. Please contact + your site administrator.

` — definitive answer. + +Registration is **disabled**, meaning outside contributors without a +Gitea account cannot directly open PRs. The ohm-rfc CONTRIBUTING +text settles on two 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). The text is phrased so the operator can +edit it down to one path if they choose to flip registration policy +later. + +The rfc-app CONTRIBUTING file doesn't carry this question +explicitly — its operator-gestures section already covers +"contributors do not have direct push access," and the Issue-first +path is the default mode for PRs the operator hasn't expected. + +### Arc 7 — Commits + push + +`rfc-app`: +- Staged CONTRIBUTING.md (new) + SPEC.md (modified). +- Committed `213f686` "docs: CONTRIBUTING.md + SPEC.md §21 analytics + chapter" with a HEREDOC commit body naming the deliverables and + the placement-as-§21 reasoning. Identity defaulted to + `Ben Stull ` (matches the operator's prior + commits on this repo; no git config edit). Pushed to both remotes: + `origin` (git.wiggleverse.org) and `benstull` (git.benstull.org) + with `-u` flag; both succeeded. + +`ohm-rfc`: +- Staged CONTRIBUTING.md (modified). +- Committed `f26fae4` "CONTRIBUTING: add roadmap-change guide + + operator-only boundary" with a HEREDOC commit body. Same + operator identity. Pushed to `origin` (the only remote on this + repo) with `-u`; succeeded. + +No tags, no VERSION bump, no `.rfc-app-version` pin move, no +`flotilla deploy`. All operator-only gestures untouched. + +### Arc 8 — Transcript + +Wrote this subsession transcript at +`~/git/ohm-infra/SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md` +per the §5 subagent-transcript convention. Parent reference in the +header. The driver publishes this alongside its own Session-M +transcript via `~/git/ohm-infra/scripts/publish-transcript.sh`. + +--- + +## Cut state (end of subsession) + +| | | +| --- | --- | +| `rfc-app` | `feature/contributing-and-spec-analytics` at `213f686`; pushed to `origin` + `benstull`. `main` unchanged at `1456c8b`. Nothing tagged. | +| `ohm-rfc` | `feature/contributing-roadmap-guide` at `f26fae4`; pushed to `origin`. `main` unchanged at `8cce148`. `.rfc-app-version` unchanged at `0.17.0`. | +| OHM live | unchanged — `deploys.id=21`, v0.17.0. No deploy gesture performed. | +| `ohm-rfc-app-flotilla` | unchanged at `65c0e55`. | +| Operator-only gestures | none touched (no tag, no version bump, no pin move, no deploy, no secret-set). | + +| Subsession M.1 ledger | Status | +| --- | --- | +| #19 rfc-app CONTRIBUTING.md | drafted on feature branch, pushed (origin + benstull) | +| #19 ohm-rfc CONTRIBUTING.md (extension) | drafted on feature branch, pushed (origin) | +| #21 Part B SPEC.md §21 analytics chapter | drafted on feature branch, pushed (origin + benstull); rides the rfc-app CONTRIBUTING commit | +| #19 anonymous-PR open question | settled — registration disabled on the Gitea instance; documented inline with two contributor paths | + +--- + +## §19.2 candidates surfaced + +1. **SPEC.md §16..§20 renumbering vs. §21-at-end placement.** + The roadmap brief's "place AFTER §15" naturally implies insert- + as-§16-and-shift-§16..§20-down, but renumbering would cascade + through 50+ cross-references, including `§19.2` (the project's + defer-decisions noun, used in CLAUDE.md, the session protocol, + 12 published transcripts, and historical commit messages). This + subsession chose the lower-risk placement-as-§21 with a §15 + forward-pointer, and documented the choice in the new chapter's + preamble. A future cleanup session that wants to do the + numerically-clean §16 placement needs to scope: rfc-app SPEC + renumber + rfc-app CLAUDE.md update + ohm-rfc-app-flotilla + CLAUDE.md cross-ref update + ohm-infra SESSION-PROTOCOL.md + reference sweep + all 12 published transcript header notes (in + wiggleverse/ohm-session-history) + the auto-memory + feedback files. None of those are within this subsession's + docs-PR scope; flagged for operator's call. + +2. **Centralized email-hash helper.** §21.2 specifies SHA-256 of + the normalized lower-cased email as the hashing function for + the per-RFC `target_email` fingerprint, but no helper exists in + the framework today. A small `frontend/src/lib/hash.js` or + `backend/app/hash.py` that centralizes normalization + hashing + would make the contract enforceable rather than relying on + per-callsite re-implementation. Captured in SPEC §21.9 as well. + +3. **Property-shape CI lint.** The conventions in SPEC §21.1 / + §21.2 are review-enforced today. A small lint (grep `track(` / + `identify(` callsites with a property-key allowlist + a PII-name + denylist) would catch drift mechanically. Captured in SPEC + §21.9. + +4. **Frontend test runner.** rfc-app/frontend has no test runner + today (no `vitest`, no `jest`, no `playwright` — only `dev` / + `build` / `preview` scripts). The discipline that the + CONTRIBUTING file documents (backend vertical tests carry the + regression boundary; frontend ships build-clean) is honest about + the current state but is itself a §19.2 candidate worth flagging + for a future session — a small `vitest` setup + a few smoke + tests against the wrapper modules (analytics.js, consent.js, api.js) + would catch the kind of structural breakage a frontend-only + release would otherwise discover at deploy time. + +--- + +## What the driver needs to know + +1. **Both branches are pushed and ready for PR.** The driver/operator can + open PRs by visiting: + - `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` + (the mirror; merge here too if the operator's release flow + normally syncs both — Session K/L precedent is that operator + pushes tags to both but PR-opens on one and merges the merge- + commit to both. The operator's call.) + - `https://git.wiggleverse.org/ben.stull/ohm-rfc/pulls/new/feature/contributing-roadmap-guide` +2. **The SPEC chapter is §21, not §16.** This is a deliberate + docs-PR-scope-only choice (Arc 2 / §19.2 candidate #1 above). + The new chapter's preamble explains the placement to readers. + If the operator prefers the §16 insertion with full renumber, + that's a separate larger PR that touches CLAUDE.md files and + transcript headers across multiple repos — too large for this + subsession. +3. **Anonymous-PR question settled inline.** Registration is + disabled on git.wiggleverse.org (confirmed via the sign-up + page). The ohm-rfc CONTRIBUTING text is phrased to update + easily if the operator changes that posture later. +4. **No operator gestures were performed.** No tag, no VERSION + bump, no pin move, no deploy, no secret-set, no overlay-set. + Both branches are drafts ready for operator review + merge at + the operator's chosen cadence. +5. **No secret bytes in either commit body or in this transcript.** + The hard rule was honored throughout. The SPEC chapter and both + CONTRIBUTING files reference secrets by name only + (`SMTP_PASSWORD`, `AMPLITUDE_API_KEY`, `CLOUDFLARE_TURNSTILE_SECRET`). +6. **Suggested PR descriptions** (operator can paste verbatim into + the new-PR form): + - `rfc-app` PR: "Lands roadmap item #19 (CONTRIBUTING + + transcript-linked onboarding) and #21 Part B (standing analytics + instrumentation discipline) as a single docs commit. Adds + CONTRIBUTING.md (~370 lines) covering PR shape, CHANGELOG + strict-descending convention, RFC 2119 upgrade-steps discipline, + §19.2 candidate practice, test-coverage expectations from the + real ~250-test backend suite, the operator-only-gestures + boundary, and the #21 Part B analytics-instrumentation checklist + (named events / autocapture-friendly DOM / replay masking / + PR-description discipline). Adds SPEC.md §21 'Analytics + instrumentation and identity' (~440 lines) codifying event + taxonomy, required prop families, autocapture DOM patterns, + session-replay masking conventions, the consent-gate contract, + the #21 Part C identity lifecycle (identify-with-properties on + sign-in; setUserProperties on state change; reset on sign-out; + identify-BEFORE-track on invite-claim), the set-vs-setOnce + taxonomy with classification rule, cohort-shape implications, + and four new §19.2 candidates. Placed as §21 rather than §16 to + preserve the load-bearing §19.2 / §19.3 cross-reference graph; + reasoning in the chapter preamble. §15 carries a new forward- + pointer naming §21 as the peer cross-cutting analytics chapter. + No code change; no VERSION bump; rides a future release or + lands as a no-bump docs commit at operator discretion." + - `ohm-rfc` PR: "Lands roadmap item #19's OHM-side artifact. + Extends the existing 130-line RFC-content CONTRIBUTING.md with + a new 'Proposing a change to the OHM roadmap' section (~80 + lines) covering roadmap-change kinds, the + wiggleverse/ohm-session-history pointer with worked-example + links into Sessions J/K/L, the PR-submission gesture (with the + open question on Gitea registration settled inline: + git.wiggleverse.org currently has registration disabled, so + contributors choose between Issue-first and request-account + paths), the explicit operator-only-gestures boundary with the + 'I'm the only one that gets to yolo' quote, and the two-layer + rule. No version target." + +--- + +## Files written + +- `/Users/benstull/git/rfc-app/CONTRIBUTING.md` (new) +- `/Users/benstull/git/rfc-app/SPEC.md` (modified — new §21 chapter + + §15 forward-pointer paragraph) +- `/Users/benstull/projects/wiggleverse/ohm-rfc/CONTRIBUTING.md` + (modified — new "Proposing a change to the OHM roadmap" + section appended after the License block) +- `/Users/benstull/git/ohm-infra/SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md` + (this file)