add SESSION-M.1-TRANSCRIPT-2026-05-28T05-30--2026-05-28T05-40.md
This commit is contained in:
@@ -0,0 +1,460 @@
|
|||||||
|
# Session M.1 — Subsession transcript
|
||||||
|
|
||||||
|
> Parent: `SESSION-M-TRANSCRIPT-2026-05-28T05-26--<end>.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<target>-<slug>` 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 `<p>Registration is disabled. Please contact
|
||||||
|
your site administrator.</p>` — 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 <benstull@mac.lan>` (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)
|
||||||
Reference in New Issue
Block a user