174 lines
9.5 KiB
Markdown
174 lines
9.5 KiB
Markdown
# SESSION-0006.0 — User-flow BDD: first-run experience (new flows/ domain)
|
||
|
||
**Date:** 2026-05-31
|
||
**Driver:** Ben Stull + Claude (Opus 4.8)
|
||
**Repos touched:** wiggleverse-ecomm-meta (corpus + session record)
|
||
|
||
> **Honesty note on this artifact.** This is a *session record* authored by
|
||
> the assistant from the conversation — faithful as to decisions, sequence,
|
||
> and wrong turns, but **not** the raw byte-for-byte transcript.
|
||
|
||
---
|
||
|
||
## Purpose
|
||
|
||
Extend the Shopify research corpus with a new kind of artifact: **end-to-end
|
||
user-flow journeys** that cross domains, as distinct from the existing
|
||
per-feature docs (which are each backgrounded with "authenticated as a Store
|
||
Owner"). Ben narrated the experience verbally so we could skip the live
|
||
login/OTC dance. First flow: the **first-run experience** (onboarding from
|
||
landing page to admin).
|
||
|
||
## What happened, in order
|
||
|
||
1. **Oriented in the corpus.** Confirmed structure: 1135 scenarios, 13 domains,
|
||
62 feature files under `research/shopify/`, with stable `DD.FF.NNNN-slug` ids
|
||
assigned by `assign_ids.py` (sibling app repo `tools/`), registry at
|
||
`.id-registry.json`, ingested by the BDD release planner.
|
||
|
||
2. **Two structural decisions locked (via AskUserQuestion):**
|
||
- **Home for flows** → a new `flows/` folder as its own corpus domain.
|
||
Verified the id assigner allocates domain numbers as `max+1`, so `flows`
|
||
becomes **domain 14** with no renumbering of the 1135 frozen ids.
|
||
- **Format** → each flow is a `# Feature:` with a `Background:`, `###`
|
||
groupings, and one `Scenario:` per step/branch (raw Gherkin in markdown,
|
||
matching the dominant clean shape like `orders/orders.md`).
|
||
|
||
3. **Read the id machinery before writing** (`assign_ids.py`, `pre-commit`
|
||
hook) to confirm the append-only behavior and that un-id'd scenarios get
|
||
ids assigned + blocked at commit for review.
|
||
|
||
4. **Ben narrated the first-run experience.** Key content and the deliberate
|
||
divergences from Shopify (see Decisions). Asides: marketing site / branding
|
||
declared out of scope; migration ("Move existing store") explicitly to be
|
||
BDD, **not** a roadmap item.
|
||
|
||
5. **Wrote `research/shopify/flows/first-run-experience.md`** — 27 scenarios
|
||
across 7 phases (entry point, sign-up & auth, store selection, "what can we
|
||
help you do?" goals, POS, store naming, landing in admin). Each Shopify
|
||
divergence written as its own explicit scenario.
|
||
|
||
6. **Validated then assigned ids.** `--dry-run` first (parsed clean, confirmed
|
||
domain 14 / feature 01), then a real run froze `14.01.0001`–`14.01.0027`.
|
||
Registry + `scenarios.json` regenerated; corpus **1135 → 1162**.
|
||
|
||
7. **Committed in two passes.** `a93fe3c` (corpus: the flow + registry +
|
||
manifest), then `27722a9` (sessions transcripts). Both pushed to
|
||
`origin/main`.
|
||
|
||
8. **WRONG TURN — clobbered an existing transcript.** When committing "session
|
||
transcripts," I overwrote the existing `SESSION-0004.0` (the content /
|
||
online-store record) with this session's notes instead of creating a new
|
||
file. Caught it immediately after the push, restored the original 0004 from
|
||
the version I had Read into context, and moved this session's record to its
|
||
correct slot, `SESSION-0006.0` (this file). Lesson: never reuse an existing
|
||
session filename — always allocate the next free number.
|
||
|
||
## Decisions citable later
|
||
|
||
- **`flows/` is corpus domain 14.** A new top-level category for cross-domain
|
||
user-flow journeys, separate from per-feature docs. Append-only numbering
|
||
means it sorts last numerically even though "flows" is alphabetically
|
||
mid-list — by design; existing ids never move.
|
||
- **Flow scenarios describe OUR target behavior, not a Shopify mirror.** Every
|
||
intentional divergence is its own explicit, testable scenario. Divergences
|
||
captured in first-run: no time-limited trial / no SaaS fee; no credit card at
|
||
store creation; no plan tiers (just the platform); auth limited to email-OTC
|
||
+ Google + Apple (no Facebook); all auth methods resolve to one account by
|
||
email; free POS (no subscription, free app downloads).
|
||
- **Migration is BDD, not roadmap.** Ben corrected an initial impulse to add
|
||
migration to the roadmap. "Move existing store" → its own future feature
|
||
`flows/migration.md` (`14.02`), narrated later.
|
||
- **Account identity is keyed to resolved primary email.** The auth mechanism
|
||
(email/Google/Apple) is an implementation detail; same email → same single
|
||
account. Captured as `14.01.0010`.
|
||
|
||
## Open / carried forward
|
||
|
||
- **Migration flow** — Ben will narrate "Move existing store" later; build as
|
||
`flows/migration.md` = `14.02.NNNN`.
|
||
- **Default store name** — pin `14.01.0026` to the literal `"My store"` vs.
|
||
keep generic? Left generic for now.
|
||
- **Goal selection** — single-select vs. multi-select for `14.01.0017`–`0021`?
|
||
Modeled as pick-one-or-skip for now.
|
||
- **Marketing site / branding / "Why we built Shopify"** — Ben flagged for a
|
||
future discussion; out of scope this session.
|
||
|
||
## Addendum — release plan landed
|
||
|
||
After the session record was first written, `roadmap/RELEASE-PLAN.md` appeared in
|
||
the tree (a proposed seed clustering of the corpus into session-sized releases,
|
||
generated from `scenarios.json` and hand-tunable in the planner). Committed it
|
||
alongside this transcript update. Notes for continuity:
|
||
|
||
- **26 MVP-path releases** (R01–R26 enumerated) across milestones M0–M5;
|
||
**MVP finish line = R22** (POS sale & cash drawer). Ordering is anchored to the
|
||
first two merchants — Hasan (catalog + in-person POS) and Connie (catalog online
|
||
+ storefront). Spine: store exists → catalog → sell online → orders → sell in
|
||
person. 358 of 1162 scenarios are clustered into the MVP path; the rest sit in
|
||
themed BACKLOG / GATED sections.
|
||
- **Our new first-run flow is parked in BACKLOG · Flows / first-run** (`14.01`,
|
||
27 scenarios, "onboarding automation", ~2 releases) — not on the MVP path.
|
||
- **GATED section** keeps the ecosystem-credit / "Load & Reward" differentiator,
|
||
gift cards, and finance/float features out of any buildable release: hard legal
|
||
gate (money transmission), needs the OHM concept→operational RFCs and a payments
|
||
attorney first. R14 (payments) is deliberately scoped to provider config +
|
||
manual + test mode only, to stay clear of that line.
|
||
- **Parser contract** is documented inline in the file header: a release = a
|
||
`## R<NN> · <name>` heading; members = backticked full scenario ids under
|
||
`### scenarios (N)`; `## BACKLOG ·` / `## GATED ·` carry no ids and must not be
|
||
built.
|
||
|
||
## Addendum — git auth incident + SSH standardization
|
||
|
||
Pushing the release-plan commit, the HTTPS push to gitea failed: "Failed to
|
||
authenticate user", then "could not read Username … Device not configured". Root
|
||
cause: the macOS keychain entry for `git.wiggleverse.org` (which had worked for
|
||
earlier pushes this session) had dropped out, and a non-interactive agent shell
|
||
can't answer git's username/password prompt. No token was present in the
|
||
environment either.
|
||
|
||
**Resolution — switched to SSH.** Ben's `git.wiggleverse.org` SSH key ("Mac Mini")
|
||
authenticates fine. Pushed `ecomm-meta` over an explicit SSH URL, confirmed remote
|
||
`main` = `074fcd4`, and synced the local tracking ref.
|
||
|
||
**Then standardized the whole fleet on SSH** (Ben's call — the older wiggleverse
|
||
repos were already SSH; the ecomm + rfc repos had drifted to HTTPS):
|
||
|
||
- Flipped all **6 ecomm** repos and the **3 rfc/ohm** stragglers (`rfc-app`,
|
||
`rfc-app-prototype`, `ohm-rfc-app-flotilla`) from HTTPS → SSH. Canonical shape:
|
||
`ssh://git@git.wiggleverse.org:2222/<namespace>/<repo>.git` (note port **2222**).
|
||
Namespaces preserved exactly (`ben.stull/` stays `ben.stull/`); stripped an
|
||
embedded `ben.stull@` userinfo from the prototype URL. Each verified via
|
||
`ls-remote`. Final sweep: **zero HTTPS origins remain** under `~/projects`.
|
||
- **Carve-out left intact:** deploy VMs (e.g. the planner's ingest pull) keep their
|
||
own HTTPS bot-token credential-helper — that's deployment state, not a developer
|
||
clone. Only local working copies were flipped.
|
||
|
||
**Documented it in the engineering guide** (`wiggleverse/engineering`, README/§5),
|
||
following that repo's own branch→PR rule, two commits each on their own branch
|
||
then merged to `main` and pushed over SSH:
|
||
- §5.2 "Transport: SSH, always" — canonical URL shape, the explicit `:2222`, the
|
||
convert-from-HTTPS one-liner, namespace-preservation rule, the *why* (HTTPS
|
||
keychain token silently expires → non-interactive push fails), and the deploy-VM
|
||
carve-out.
|
||
- Sub-section anchors + nested TOC: promoted the bold lead-ins in §3/§5/§6/§7/§8
|
||
to numbered `### N.M` headings (matching §10's existing pattern) and nested every
|
||
sub-section in the table of contents. All 34 TOC anchors verified to resolve.
|
||
(Field-label bolds in §9/§11 — When:/Topology:/… — left as-is; they're definition
|
||
labels, not sub-sections.)
|
||
|
||
**LESSON:** local clones use SSH, never HTTPS — the HTTPS keychain credential is
|
||
brittle and a dropped credential is unrecoverable from a non-interactive session.
|
||
|
||
## Open / carried forward (session close)
|
||
|
||
- **Migration flow** — `flows/migration.md` (`14.02`), Ben narrates later.
|
||
- **Default store name** (`14.01.0026`) — literal `"My store"` vs. generic? (generic for now)
|
||
- **Goal selection** (`14.01.0017`–`0021`) — single vs. multi-select? (pick-one-or-skip for now)
|
||
- **Marketing site / branding / "Why we built Shopify"** — future discussion.
|
||
- **HTTPS keychain credential for `git.wiggleverse.org` is gone** — SSH is the path
|
||
now; only matters if some HTTPS-reliant script surfaces.
|
||
|
||
*Session 6 closed here.*
|