Repository navigation
[P28-M02b] #2113 follow-up: Native authored-issue test source with Prepared/Unknown projection on a synthetic fixture #2373
Description
Split child of #2113 (Phase 28 batch 9). Filed by Scope per Samson's approval of #2113 r1. Not Ready.
Parent: #2113, which now covers only its -a slice.
Scope
M02-b of #2113 r1 (§1 items 8–10): one native authored-issue test source with a visible Prepared/Unknown projection. Per Samson's OQ2 ruling it builds in parallel against a synthetic fixture issue and revision, with no link to M02-a or #2112.
- One native source:
native_issue_test_runsrecords one test request: issue, exact revision, requester, idempotency key, release ref, state. Creating it and its required intent is one transaction throughReleasePort([Phase 17] Atomic Delivery Plan occurrence compiler — source-fenced complete release into the Phase 6 spine #888; test adapter). The source reads the revision through a restricted revision read (the synthetic fixture here; M01's restricted read when wired), never caller input. It isn't a system-message catalog key, queue, outbox or dispatch ledger. - Replay and conflict: the same key and revision return the same run; the same key with another revision is a conflict.
- Projection: the editor panel shows the run's state: "Test prepared — not sent", "Test may have started" or "Recovery unknown", with the tested revision number. A response that arrives after a AL-2069 — [P28-W01] Enter and switch the exact authorized workspace context #2069 context change is dropped and the projection re-reads under the current context (AC28-M41-02). No state reads "Delivered".
- A4 [A][R] Native test source (AC28-M41-02): a test of revision 5 creates one run and one released intent atomically; a fault between them leaves neither. The same key returns the same run; the same key with revision 6 conflicts. The panel shows "Test prepared — not sent" with revision 5; the fixture's lost response shows "Test may have started"; no state reads "Delivered". A response arriving after a context switch is dropped, and the projection re-reads under the new context.
- B1 [B][R] Source input: the run reads revision content only through the restricted revision read; a caller-supplied body or subject is rejected at the schema.
- C1 [A] Journey: on a real stack with test adapters, the synthetic fixture and the controlled transport fixture, at desktop, keyboard-only and with screen-reader names checked: Maya requests a test of her saved revision, sees "Test prepared — not sent" with the revision number, and reloads after a simulated crash and sees the same result. Axe clean. (M02-c adds the restore step.)
- Handback: H1 (real-stack tests in "Verify tenant isolation (real stack)"), H2 (read-only development catalog check:
tenant_guardschema and role, and that the new names don't exist; no writes), H3 (Playwright log for C1), H4 (Shadscan and eslint results;bun run verify:shadscanpasses).
Declared edits (Builder): supabase/migrations/20261026154000_native_issue_test_runs.sql + rollback (test-run source table and function); packages/api/src/newsletters/tests/** (new: native test source service, synthetic fixture issue for tests); apps/missionary/app/api/newsletters/[issueId]/tests/** (new: test request route); apps/missionary/app/feed/newsletters/** (projection panel); packages/api/src/identity/tenant-guard.ts (new GUARDED_RPCS entries only); docs/features/communications/p6-prepared-submissions.md (native test source); tooling refresh. (Acceptance): A4 in tests/unit/acceptance/issue-2113/**; tests/e2e/newsletter-test-preparation.spec.ts (new) for C1.
Size
~560 code+docs / ~620 tests.
Migration
20261026154000_native_issue_test_runs.sql: native_issue_test_runs (append-only; unique per tenant and idempotency key; RLS and FORCE RLS, same-tenant foreign keys, no anon/authenticated/service_role table privileges) and its guarded function. Sorts after M02-a's 20261026153000 (#2113). Rollback drops the function and refuses while any run row exists. Version is reserved; Samson may renumber at handback to keep merge order.
Pins
- M02-a producer tables and functions (AL-2113 — [P28-M02] Prepare one native test message through the missing P6 sealed-submission producer #2113): Out (not linked; parallel work per OQ2).
- M01 revisions and editor (AL-2112 — [P28-M01] Prepare and recover a native newsletter draft #2112, M01-b): Out (not linked; the synthetic fixture stands in per OQ2).
- Email send seam (
packages/email/resend/*,packages/api/src/email/*): Out (unchanged and not imported). packages/api/src/identity/tenant-guard.ts: In (newGUARDED_RPCSentries only).- Missionary navigation list (
tests/unit/apps/missionary/missionary-navigation-search.test.tsx:67-75): Out (no nav item). - Donor detail suppressions (
tooling/eslint-config/suppressions.json:1181-1188): Out (the donor detail isn't touched). - Shadscan app floors: In (no new unreviewed finding).
- Workflow fingerprints,
docs/ci.mdbyte pin, Phase 28 PRD archive: Out (no CI step; OQ6 closed "no").
Blocked by
- [Phase 17] Atomic Delivery Plan occurrence compiler — source-fenced complete release into the Phase 6 spine #888 (Delivery Plan release; copied from the parent)
Notes
- Per Samson's OQ2 ruling, M02-b isn't linked to M02-a (AL-2113 — [P28-M02] Prepare one native test message through the missing P6 sealed-submission producer #2113) or AL-2112 — [P28-M01] Prepare and recover a native newsletter draft #2112. It's parallel work on the synthetic fixture.
- [Phase 17] Atomic Delivery Plan occurrence compiler — source-fenced complete release into the Phase 6 spine #888 is copied because the run and its intent are created through
ReleasePort. [Phase 6] communication-recorder write path + capture at the sendEmail seam + sole-seam CI import-lint #554 isn't copied (M02-b doesn't call the recorder). - Production stays inert while the parent's adapters are
unavailable(parent OQ1 handback gate Samson checks). - Donor spine: none.
Spec
Spec: see parent r1 §10 (split) and the M02-b rows of §1, §2, §4 and §6 at #2113 (comment), plus Samson's approval #2113 (comment) and the pins addendum #2113 (comment); a child r1 follows if needed.
Deploy: Samson relays to Blake at merge.
Activity