Machine-readable companion to the demo verification report. Paste the block below to your AI, or fetch this URL directly. Human version has the screenshots.
# SoundCheck demo verification run (machine-readable)
Date: 2026-07-15
Runner: Kenn Jordan (ElmsPark), independent of the builder
Repo: ElmsPark/soundcheck (fork of donjjjordan/soundcheck), commit c0f48b1
= the exact commit audited by the round-2 review (soundcheck-review-r2-x7k4)
Purpose: resolve the round-2 claims-table row "The live demo already exists,
3-minute quickstart", which was PARTLY CHECKED (audit machine had no Postgres).
Result: VERIFIED END TO END, with one config-level blocker found and worked
around (no product code changed). Details and repro below.
## Environment
- M5 MacBook Pro, macOS 27.0, Node v24, npm cache warm
- No Postgres of any kind installed before the run (checked: no formula, no
service, port 5432 free)
- Installed: postgresql@16 16.14 via Homebrew bottle (initdb trust auth,
cluster owner = local user)
- Browsers: manual pass in Chromium, scripted pass in Playwright (headless
Chromium), fresh contexts per role
## Setup timing (README "Getting started (for Kenn)", followed exactly)
| step | seconds |
|----------------------------------------|---------|
| brew install postgresql@16 + start | 7 |
| git clone | 3 |
| cp .env.example .env + set DATABASE_URL| <1 |
| createdb soundcheck (keg-only prefix) | 1 |
| npm install (warm cache) | 4 |
| npm run db:migrate | 2 |
| npm run db:seed | <1 |
| npm run dev -> "Ready in 1772ms" | ~3 |
Total ~14s of command time against the README's "about 3 minutes".
Seed output: "Seeded 6 acts, 4 reviews, 2 venues." Popular demo date printed:
2026-08-01 (a Saturday; acts #1 Brass Tacks and #4 Midnight Sax Trio are
pre-booked on it, so search filtering is demonstrable).
## Tour steps and observed results
1. SEARCH: /search?date=2026-08-01&postcode=SW1A+1AA -> "4 bands available on
Sat, 1 Aug 2026". Correct: 6 seeded acts minus the 2 booked-out. All-in
prices shown incl. travel + VAT. PASS.
2. ACT PAGE (The Velvet Kings): 5.0 stars (2 booking-verified reviews),
PLI GBP 10m / PAT / ID badges, 16-Saturday availability grid, breakdown
1450 + 1.80 travel (4 mi from N1 7GU) + 290.36 VAT = 1742.16, deposit
348.43. PASS. (Cosmetic: genres render as raw enums "SOUL_MOTOWN,
FUNK_DISCO" here; search cards prettify them.)
3. BOOK as chloe@example.com / "password", mock provider:
- FIRST ATTEMPT ON SHIPPED .env: FAILS. See finding V1.
- AFTER WORKAROUND (blank 3 STRIPE_* lines): booking SC-2026-0005 created,
status Confirmed, chip "Venue check pending", deposit 348.43
"payment protected", contract auto-generated, availability slot BOOKED.
PASS.
4. CONTRACT: signed as client, then as act (hello@thevelvetkings.co.uk /
"password"). Status walked sent -> client signed -> fully signed; booking
advanced CONFIRMED -> CONTRACT_SIGNED. Act dashboard shows budget, venue,
payout 1306.80, commission 145 disclosed. PASS.
5. TOKENISED VENUE LINK: shown on the booking page (email is mocked), format
/venue/<24-hex-token>. Opened in a fresh cookie-less context: loads with no
login, names the venue, says which act and date it is helping. Exactly 16
visible inputs. PASS.
NOTE: the link only exists when the booking's venue postcode does NOT match
a seeded venue. SW1A 1AA and GL54 1AA carry CONFIRMED cached setups, so
booking with those reuses the Venue Database entry and skips outreach (by
design). This run used a new venue "The Verification Rooms", SW1A 2AA.
6. INTAKE SUBMITTED: indoor, stage 6x4 m, 3 sockets, level load-in, parking
yes, curfew 23:30, limiter fitted, 85 dB, A-weighted, reset authority
"Sarah (duty manager)" 07700 900123, contact "Vera Manager". Thank-you page
immediately shows the plain-English readout and "Readiness: RED (1 note
flagged to the act)". PASS.
7. RED VERDICT: client dashboard chip flips to "Venue: problem to fix" (past
bookings stay green "Venue ready"). Booking page shows the same chip plus
flag "Limiter at 85 dB will not allow this band's live drums.
Electronic-kit line-up or a different venue needed." and an amber ULEZ
note. Venue Pack prints: "85 dB, A-weighted. Live drums not advisable.
Electronic kit or cajon line-ups recommended. Reset authority: Sarah (duty
manager), 07700 900123." plus stage fit 6x4 vs 5x3 needed, curfew, contacts.
PASS, wording verbatim from src/domain/limiter.ts.
Scripted probe pass (Playwright): 13/13 exact-string assertions found
(contract "fully signed"; venue page name + "no account needed" + "You are
helping The Velvet Kings"; thanks "is confirmed" + "Live drums not advisable"
+ "RED"; dashboard chip; booking chip + limiter flag; pack "85 dB" +
"Live drums not advisable" + "Sarah (duty manager)").
DB ground truth after the tour:
reference | status | venueReadiness | contract | client_signed | act_signed
--------------+-----------------+----------------+--------------+---------------+------------
SC-2026-0005 | CONTRACT_SIGNED | RED | FULLY_SIGNED | t | t
name | confirmation | confirmedBy | thresholdDb | verdict
------------------------+--------------+--------------+-------------+---------------------
The Verification Rooms | CONFIRMED | Vera Manager | 85 | ELECTRONIC_KIT_ONLY
Screenshots (untouched Playwright captures):
https://elmspark.com/assets/soundcheck-verify-x7k4/
01-contract-fully-signed-act-view.png
02-venue-intake-top.png
03-venue-form-filled.png
04-venue-thanks-readout.png
05-client-dashboard-red.png
06-booking-red-verdict.png
07-venue-pack.png
## Findings
### V1 (BLOCKER): shipped .env placeholders crash the Book step
- Repro: cp .env.example .env; set DATABASE_URL only (the README's only .env
instruction); npm run dev; attempt any booking while signed in.
- Observed: POST /book/<actId> -> 500.
Server log: "Internal error: Error: Invalid API Key provided: sk_test_..."
at node_modules/stripe/esm/RequestSender.js:100:31.
- Cause: .env.example ships STRIPE_SECRET_KEY="sk_test_..." (non-empty
placeholder); src/server/payments/index.ts paymentsProvider() returns the
mock provider only when the key is FALSY, so any non-empty string selects
the real Stripe provider; makeStripeProvider() constructs new Stripe(key)
unvalidated and createCheckoutSession() throws on the live API.
- Contradicts: README "Stripe runs in a built-in mock mode by default, so
nothing is needed from anyone to run the full flow end to end", and
.env.example's own comment "Leave blank to use the built-in mock provider"
(the shipped values are not blank).
- Workaround used in this run (config only): set the three STRIPE_* values to
"" and restart the dev server. Everything downstream then passed first time.
- Suggested fix (either, one line): ship the three values empty in
.env.example; or in paymentsProvider() treat the literal placeholder
(e.g. /^sk_test_\.\.\.$/ or endsWith("...")) as unset.
### V2: round-2 F7 observed live (HELD-date leak on failed checkout)
- The createBooking transaction commits (booking row + slot HELD) BEFORE the
provider call, so the V1 crash left booking SC-2026-0005 stuck at
AWAITING_PAYMENT and The Velvet Kings' 2026-08-01 slot HELD on the very
first attempt. The date became unbookable (availability guard rejects
non-AVAILABLE slots) and nothing cleans it up; this run reseeded to
continue.
- Evidence: SELECT on AvailabilitySlot showed status HELD for that act/date
immediately after the 500.
- Implication: any abandoned or failed real-Stripe checkout leaks the same
way. Suggest an expiry on HELD (or release-on-failure) ahead of other
Phase-3 work.
### V3 (friction): booking details discarded across the sign-in redirect
- Repro: fill the booking form signed out (venue name, postcode, guests),
submit, sign in when redirected.
- Observed: back on the form with venue name, postcode and guest count blank
(redirect next-URL preserves only actId + date); travel drops out of the
total until retyped. The pre-login banner says "Your details and price are
kept exactly as shown", which currently over-promises.
- Suggested fix: carry the form fields through the login round-trip (e.g.
serialise into next), or reword the banner.
### V4 (cosmetic): act page shows raw genre enums
- /acts/<id> header renders "SOUL_MOTOWN, FUNK_DISCO"; search cards render
"Soul / Motown". Align the act page with the search-card prettifier.
## Fix list (suggested order)
1. V1: blank or guard the Stripe placeholders (unblocks every fresh clone).
2. V2/F7: release HELD slots on failed/abandoned checkout, or expire them.
3. V3: preserve booking-form details across sign-in, or soften the banner.
4. V4: prettify genre enums on the act page.
## Demo-script notes
- Use the seeded Saturday 2026-08-01 so availability filtering is visible.
- Give the booking a venue postcode that is NOT SW1A 1AA or GL54 1AA, so the
tokenised outreach link appears (those two postcodes demo the cached Venue
Database path instead).
- Submit only the 85 dB limiter as the problem so the RED flag reads clean
(avoid also breaching curfew/stage, which would stack flags).
- Blank the STRIPE_* lines before demoing until V1 is fixed.
## Cross-references
- Human version of this report (with screenshots):
https://elmspark.com/soundcheck-demo-report-x7k4/
- Round-2 code audit: https://elmspark.com/soundcheck-review-r2-x7k4/
- Round-2 machine-readable: https://elmspark.com/soundcheck-review-r2-md-x7k4/