An acceptance criterion that names a user journey the product does not have — so the only ways to satisfy it are to fake it or to drop it.
MOTIR-3462 requires:
Two invites with the same idempotency key produce exactly ONE outbox entry.
and its journey step 5 says “Send the same workspace invite twice, with the same key.” MOTIR-3415's own verification_recipe says the same in plainer words: “send the same workspace invite twice and confirm one email.”
There is no such thing as sending the same invite twice. Read on origin/main@18d60791:
$ grep -n "generateToken" lib/services/workspaceInvitesService.ts
65:function generateToken(): string {
198: const token = generateToken();
$ grep -n "idempotencyKey" lib/services/workspaceInvitesService.ts
109: idempotencyKey: args.token,
One call site, unconditional, with no reuse-existing-invite branch — and that fresh token IS the idempotency key. Two invites to one address are two DIFFERENT invites with two different keys, and they correctly produce two emails. No UI path in the product can mint the same key twice, so no Playwright spec can assert same-key dedup, however it is written.
The criterion is not merely unachievable — it is unachievable in a way that invites a false pass. The obvious repairs are all bad: assert two emails and call it satisfied (measures nothing); reach into the DB to forge a duplicate event (asserts the constraint, not the journey, while looking like a journey test); or add a _test route that emits a raw event (new surface, and still not a journey). The run that discharges it correctly is the one that stops and reports — which costs a session the time to discover what a grep would have shown at plan time.
And the guarantee it was reaching for is real. Engine-side dedup ships and is proven, one tier down and against real Postgres:
tests/jobs/engine-idempotency.test.ts — two same-key events → one queued run, including a genuinely CONCURRENT duplicate, plus the P2002-swallowed path;tests/jobs/event-cutover-story-gate.test.ts §1 — two same-key events → one delivery, read back through the operator DTO.So nothing is untested. What is wrong is the TIER the criterion assigns the check to.
A criterion is authored by asking what would prove this, and the answer here needed one more question: what USER ACTION produces the input the assertion needs? The key is minted by the service, not chosen by the user, so no click can hold it fixed. A criterion that pins a value the user cannot control is a criterion for the tier where the value CAN be controlled — a vitest seam, not an E2E.
Related in shape to plan-rules/phase-deepen.md's precondition family: the card verified that four HELPERS existed (and they did — it says so, correctly) but not that the JOURNEY it composed from them was expressible.
Nothing to build. MOTIR-3462 is amended on the record: the criterion is struck through with the evidence, the two tests that DO prove it are named, and it is replaced by the assertion the UI path can actually make — one invite produces exactly one job_run row and one outbox entry with the fast lane on the engine, which pins that the dedup neither double-sends nor swallows a legitimate first send.
MOTIR-3415's verification_recipe still carries the same wrong sentence and should be corrected when that story is next touched.
Found by running the card on parent/MOTIR-3415-event-jobs-cutover.