Record what running the flow proved, and fix the leaf that caused one defect
The create-and-participate flow was driven in a real browser for the first time. It had been called correct by construction -- typecheck, build, reading -- and the probe found three defects none of those could see. Two open bugs, both major, both filed rather than worked around: signing up to your own event makes the NEXT connection fail outright (`ensureIdentity()` rejects inside the data layer's own inbox processing, 3/3, reproduced on a fresh origin and identity), and the participant count does not converge in the same session (2/2, 120 s and 75 s). Whether it converges at the next connection is recorded as UNKNOWN and unmeasurable, because the first bug stops the app from getting there. The doctrine defect is the one worth the trouble. `knowledge_build-pipeline` said production builds into `dist/`; `knowledge_deployment` said the container runs `bun run start` from `src/`. Both were written down, they contradicted each other, and the code followed the wrong one -- which is how a deployed app that could sign nobody in was shipped. The three paths now live in one table whose discriminating column is what is actually served: dev `src/`, production `src/`, and `dist/` served by nothing at all. A build artefact nobody serves is a trap for the next reader who assumes otherwise. The probe method itself is written down: the suite cannot run, a targeted probe can, and the difference is worth knowing before concluding that nothing is measurable. Stated once where a reader meets it: honest steps do not add up to an honest flow. Every gesture in the sign-up reports correctly, and the user is still told they participate while the count never moves and the next connection fails.
This commit is contained in:
@@ -39,3 +39,4 @@ BDD tests written in **Cucumber/Gherkin in French** (`Etant donné`, `Quand`, `A
|
||||
- [[decision_2026-03-12_headless-wallet-creation]] — why the test wallet is created through a headless UI
|
||||
- [[caveat_source-grep-vestiges]] — leftovers from the "source analysis" era in `world.ts`
|
||||
- [[cookbook_add-scenario]] — adding a scenario/step (layers, `evaluate` serialization pitfall, `@wip`)
|
||||
- [[cookbook_live-probe]] — verifying a flow for real when the suite cannot answer: a throwaway Playwright probe on the real app, what it must collect, and why its findings must be written down the same day
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
type: cookbook
|
||||
summary: How to verify a flow for real when the suite cannot answer — a throwaway Playwright probe that boots the REAL app in a real browser against the real broker and drives the UI as a user does; what it must collect, and why its findings must land in doctrine the same day.
|
||||
last_checked: 2026-08-16
|
||||
---
|
||||
|
||||
# Driving the real app with a throwaway probe
|
||||
|
||||
A **probe** is a one-off Playwright script, outside Cucumber — no World, no hooks, no fixtures — that boots the **real app** in a real browser against the **real broker** and drives its interface the way a user does. You write it, you run it, you read it, you delete it.
|
||||
|
||||
## When to reach for one
|
||||
|
||||
Before believing a flow works. The create-and-participate flow had been declared *correct by construction* on typecheck, build and reading; the first probe ever run against it found **three defects** none of those could see — two still open ([[bug_signup-breaks-the-next-connection]], [[bug_participant-count-stays-at-zero]] in `data-layer`) and one shipped as a fix.
|
||||
|
||||
Reach for it when the suite cannot answer the question: the `@data` run dies silently from around its sixth scenario ([[caveat_wallet-bloat-hang]]), its scenarios have no fixtures ([[caveat_data-suite-has-no-fixtures]]), and entry paths are covered by nothing ([[caveat_first-time-entry-untested]], `app-architecture` → [[caveat_boot-unverified-outside-broker]]).
|
||||
|
||||
## Method
|
||||
|
||||
1. **Drive the app's own interface, never a bridge.** A probe that calls into the data context proves the data context. The whole point is the collaboration between the layers, so the only inputs are the ones a user gives — clicks, typing, waiting — and the only outputs are the ones a user sees.
|
||||
2. **Reuse the boot the `@e2e` layer already documents** ([[knowledge_e2e-layer]]) rather than inventing one: the app server on its own port, the broker round-trip, the app in its iframe. Do not build a second way in.
|
||||
3. **Collect `pageerror` and `console` from the first navigation.** The findings that matter surface as a rejection raised *inside a layer you never called* — invisible on screen except as a panel saying something failed.
|
||||
4. **Time the steps you assert on.** "The toast landed after the write" and "1.8 s" are two different findings; the second is what makes a later regression legible.
|
||||
5. **Keep watching after the confirmation, then reconnect.** A step that reports honestly can still leave the flow wrong. Give the state a real interval (minutes, not a tick), then come back through a fresh load — most of what a probe finds lives after the point where a test would have asserted green.
|
||||
6. **Say what state you started from.** A **brand-new origin with a brand-new identity** is what separates a real defect from accumulated wallet state, and a finding reported without it is not yet a finding. Report the run count too (*"3 of 3"*).
|
||||
|
||||
## What a probe is not
|
||||
|
||||
It is **not a regression guard**: nothing re-runs it, and a deleted script protects nothing. Its whole value is converted at the end of the run, into doctrine or a `bug_` leaf, the same day — a probe run that is not written down bought nothing. Recording an observation, mark **VERIFIED** (seen, with the run count) apart from **INFERRED** (the explanation you reached for); a real symptom does not certify its diagnosis.
|
||||
|
||||
> **The lesson that pays for the method: honest steps do not add up to an honest flow.** Every step of the sign-up reports truthfully — the mutation rejects rather than lying, the confirmation follows the write — and the flow as a whole still announces a success it does not obtain. No layer can see that from inside itself; only exercising the whole thing end to end shows it.
|
||||
Reference in New Issue
Block a user