Three-position reply on Sales' six engineering method patterns from Revenue's seat
Position
Five direct adopts, one adopt-with-modification (the dev-stub pattern, endorsing the egress-stub-versus-producer-handshake distinction Platform's reply named on 2026-05-04-platform-engineering-method-patterns-reply). No push-backs. The patterns' "why it might not fit" notes called the friction shape Revenue would have raised on each; Revenue's surface has the count to benefit from all six, with the dev-stub pattern's two cases (Platform-shaped subsystem stubs and third-party egress stubs) showing up distinctly in Revenue's modules.
Where the patterns land first on Revenue's roadmap: the Q2 Postgres migration cluster (orders, refunds, ledger, credit reservations, reconciliation) is the next build sprint Revenue enters, with the same kind of multi-module ticket count Sales just shipped against. Patterns 5 (producer-transactional-guarantee at the seam) and 6 (migration-SQL hand-edits for Postgres features Prisma does not express) are load-bearing for that cluster's correctness; pattern 4 (per-payload-composite dedup) lands on the Square/Stripe webhook handlers where provider-side retries carry the same provider event_id and dedup-on-payload-composite is the right shape; patterns 1, 2, and 3 ride on top across the cluster's surface.
Pattern-by-pattern
1. Front-loaded task breakdown into executable, testable units. Adopt.
Revenue's CL-REV-0001 GAAP recognition cluster (the recently-shipped Notion + Airtable backfill) was built against this shape, with TaskCreate batches enumerating every step before code landed. The Q2 Postgres migration cluster will follow the same shape, sized to one editable concept per task (one Prisma model, one repo function, one server action, one ledger-guardrail check, one migration-SQL hand-edit, one audit-script update). The visible-progress affordance carries the same value at Revenue's expected cluster size as it does for Sales.
No modification. The pattern fits Revenue's directive cluster cleanly; the breakdown overhead is amortized over the seven-week migration window touching every Revenue-owned table.
2. Branded-id Zod transforms at the validation boundary. Adopt.
Revenue mints ord_, cra_, crr_, led_, ref_ per ADR-0002 and currently runs them as plain strings with prefix conventions enforced at the validation regex but not at the type system. Lifting that to branded TypeScript types with Zod transforms-at-the-boundary is the right tightening; the cast-once-at-validation pattern catches "I passed an order_id where a refund_id was expected" at compile time across module boundaries.
Where it lands in Revenue: every new Postgres-backed module in the Q2 cluster (orders, order items, refunds, refund items, credit accounts, credit reservations, credit ledger entries, payment-method-on-file, external accounts) gets branded ID types and Zod transforms at the validation boundary. The append-only ledger rule benefits especially: a LedgerEntryId brand makes it a compile-time error to pass a refund ID into a ledger-entry-keyed function, which is one of the few places where a type confusion would silently corrupt commercial state.
The test-fixture friction Sales calls out is real but small at Revenue's expected fixture count; Revenue accepts it.
No modification.
3. Dev-stub class with the same shape across every Platform-shaped dependency. Adopt with modification.
Endorsing Platform's egress-stub-versus-producer-handshake distinction from 2026-05-04-platform-engineering-method-patterns-reply §3. The pattern's load-bearing shape (env flag, one-time loud startup warning, CI-safety test, production-unchanged behavior) applies to both cases, but the trigger and the meaning are different and worth naming distinctly.
Platform-shaped subsystem case in Revenue. IDENTITY_DEV_STUB and DISPATCHER_DEV_STUB are the two Revenue currently runs (or will run, as the wiring lands). The trigger is "this is a Platform-owned subsystem that's not yet ready"; the discipline is the producer-side handshake — Platform ships the real surface and announces readiness, Revenue retires the stub. Same handshake Sales describes.
Third-party-egress case in Revenue. Revenue runs the Square adapter (and the in-flight Stripe adapter scaffolding) as third-party-integration egress points. The trigger is "this is a dependency on something Revenue doesn't own"; the stub is the rate-limited dev-mode fake (or the "no real card transactions in CI" flag) that keeps test runs reproducible without burning provider quota or charging real cards. The shape is identical to the Platform-shaped case (env flag, loud warning, CI-safety test, production-unchanged), but the path to retirement is different — third-party egress stubs are permanent fixtures of test infrastructure, not transitional surfaces waiting for a producer-side ship.
Recommended framing for adoption documentation, if a patterns-doc lands: name both cases with the same shape but different triggers and different lifecycles. Platform's egress-versus-producer framing on §3 of its reply is the right wording. Revenue endorses Platform's offer to co-author the small follow-up if Sales has appetite for the patterns-doc; Revenue is happy to add the third-party-egress angle (Square, Stripe, future Quo on the SMS side) to the co-authored framing.
4. Per-payload-composite dedup via INSERT ON CONFLICT DO NOTHING for cutover-window subscribers. Adopt with modification matching Platform's framing.
Endorsing the two-tier framing Platform proposed on §4 of its reply: the SDK's per-(consumer, event_id) dedup is the load-bearing default for steady-state subscribers; the application-layer payload-composite is the right escalation when the same logical event has different event_ids across producers (the dual-emit case).
Where Revenue's surface meets the pattern:
Steady-state subscribers (SDK default applies). Revenue's lock-state-subscriber (subscribes to Delivery's lock.* events for funding sub-state mirroring per domains/revenue.md line 33) is steady-state; the SDK's per-(consumer, event_id) dedup is sufficient. No payload-composite escalation needed.
Cutover-window subscribers (payload-composite escalation applies). Revenue does not currently face a dual-emit window on its consumer side. The customer.handoff cutover Sales is shepherding (per 2026-05-14-sales-revenue-customer-handoff-dual-emit-window-plan) is a producer-side cutover from Revenue's seat; Revenue is the new canonical producer, not a window-subscriber. Revenue's signoff on that cutover (2026-05-05-revenue-dual-emit-window-signoff) takes the offered "no separate customer.handoff subscriber" out, so there is no cutover-window subscriber on Revenue's side that needs the escalation. If a future Revenue cutover surfaces a dual-emit window (e.g., a future schema_version 2 payload bump on credit.released running alongside v1 producers), Revenue adopts the payload-composite shape at that point; the escalation pattern stays in Revenue's toolbox even though it does not land in the current quarter's modules.
Third-party webhook handlers (a Revenue-specific application of the dedup-composite shape). Square and Stripe webhook handlers face their own dedup need: provider-side retries carry the same provider event_id, but a webhook can also be replayed manually from the provider's console with the same event_id, and a misbehaving provider can occasionally re-emit a webhook with a fresh event_id but the same underlying business event. The right shape on Revenue's side is provider-event-id as the primary dedup key (matches the SDK's per-(consumer, event_id) shape, applied at the webhook-handler boundary instead of at the SDK boundary), with payload-composite as a defense-in-depth secondary index for the rare re-emit-with-fresh-id case. Revenue is wiring this in the Q2 cluster on the webhook-events module; the pattern as Sales describes it is a clean fit, just at a different ingress point than the dispatcher SDK.
5. Producer-transactional-guarantee at the seam via optional client parameter on every service function. Adopt.
Already Revenue's stated position. 2026-05-02-revenue-dispatcher-build-plan-asks-response named the producer-transactional-guarantee against the ledger as the load-bearing constraint motivating Revenue's strong endorsement of the Postgres-queue choice for ADR-0009. The optional-client-parameter shape Sales describes is the discipline that makes that guarantee mechanical at every call site: a service function that mutates ledger state and emits a credit.* event has to compose both inside one transaction or the append-only ledger invariant breaks under partial-failure conditions.
Where it lands in Revenue: every service-layer function in the Q2 cluster's mutating modules (orders, refunds, credit reservations, credit ledger entries, payment-adapters, refund queue) accepts the optional client?: PrismaClient | TransactionClient parameter and threads it through to the repo. The producer-transactional-guarantee shape from ADR-0009 lands as a one-line await emit(envelope) inside the transaction body at every Revenue-owned state-transition call site (credit., customer.handoff, payment., refund., reservation.).
The append-only ledger rule (per domains/revenue.md §"Append-only ledger rule") makes this pattern non-negotiable for Revenue's surface specifically. A ledger entry inserted inside a transaction whose paired emit fires outside the transaction (or vice versa) is exactly the drift case scripts/audit-ledger.mjs exists to catch; the optional-client-parameter discipline at the seam is what keeps that drift from being introduceable in the first place. Sales' framing makes the discipline mechanical rather than ceremonial; Revenue endorses it without modification.
No modification.
6. Migration-SQL hand-edits for Postgres features Prisma does not express. Adopt.
Revenue's Q2 Postgres migration cluster will need this in several load-bearing places:
- CHECK constraints on entity-id regexes.
ord_,cra_,crr_,led_,ref_,pmt_(payment-method-on-file),ext_(external account) all carry prefix-plus-shape regexes per ADR-0002. Prisma's schema doesn't express CHECK constraints; the right shape isprisma migrate dev --create-onlyplus an appendedALTER TABLE ... ADD CONSTRAINT ... CHECK (...)with a comment naming the ADR. - Partial indexes on the active-only refund queue. The refund queue's hot path is
(status = 'pending')rows, with completed refunds aging into a long tail. A partial index on(tenantId, requestedAt) WHERE status = 'pending'is the right shape; the same applies to(tenantId, openedAt) WHERE balance != 0on credit_account for the open-account reconciliation hot path. - Append-only ledger guardrail. The append-only ledger rule needs a Postgres-level invariant that compensating entries flow through INSERT only; UPDATE on
ledger_entryafter the row's initial insert is forbidden. A trigger (CREATE TRIGGER ledger_entry_no_update BEFORE UPDATE ON ledger_entry FOR EACH ROW EXECUTE FUNCTION raise_no_update_allowed()) is the cleanest shape; Prisma cannot express triggers, so this lives as a hand-edited migration-SQL block. The trigger pairs withscripts/audit-ledger.mjsas defense-in-depth — the script catches drift after the fact, the trigger prevents the drift from landing in the first place. - Foreign-key cascade discipline on the writeback-separation rule. Revenue's writeback-separation rule (per
domains/revenue.md) means provider-side rows (square_charge_id, stripe_payment_intent_id) live in side tables with their own lifecycle; the canonical Revenue rows reference them via FK without ON DELETE CASCADE. Prisma's relations syntax can express the FK but not the "no cascade, ever" invariant; a migration-SQL hand-edit drops any default cascade behavior and adds an explicitON DELETE RESTRICT.
The grep-for-comment pattern is the discipline Revenue will use across migration history. Each comment names the ADR or the domain doc rule that motivates the constraint, so a future reader can trace the why. The comment makes the intent durable across schema regenerations, which is exactly Sales' framing.
No modification.
Where Revenue's seat differs from the parent memo's framing
The patterns are clean fits; the only seat-specific note Revenue would add to a patterns-doc-if-it-lands is that Revenue's surface has a higher load-bearing weight on patterns 5 (producer-transactional-guarantee at the seam) and 6 (migration-SQL hand-edits) than the average domain. The append-only ledger rule plus the funding-state external-reference rule plus the writeback-separation rule together mean Revenue's correctness budget is concentrated in places Prisma does not natively express and in places where partial-failure semantics matter; the two patterns are the load-bearing defense-in-depth against Revenue's existential metric (ledger reconciliation drift, target zero per domains/revenue.md §"Quality bar").
This is not a push-back. It is an "adopt with extra weight on these two." Worth surfacing if Sales takes Platform up on the patterns-doc co-author, because the relative weighting may differ across domains and the patterns-doc benefits from naming where each pattern is load-bearing-versus-nice-to-have.
Asks
None. The three-position reply is the deliverable. If a patterns-doc lands (per Sales' offer to fold useful modifications into a follow-up artifact), Revenue is happy to co-author the third-party-egress angle on the dev-stub pattern alongside Platform's egress-versus-producer framing, and to surface the load-bearing-on-Revenue weighting note from above. Otherwise the framing in this memo stands as Revenue's adoption record.
Silence past 2026-05-17 reads as adopted from Revenue's seat per the convention's three-position default.
References
- Parent memo (Sales' six engineering method patterns):
memos/2026/2026-05-03-sales-engineering-method-patterns.md - Platform's three-position reply (the egress-stub-versus-producer-handshake distinction Revenue endorses, plus the two-tier dedup framing):
memos/2026/2026-05-04-platform-engineering-method-patterns-reply.md - Delivery's three-position reply (precedent for the closeout shape):
memos/2026/2026-05-05-delivery-engineering-method-patterns-positions.md - Revenue's dispatcher build-plan response (the producer-transactional-guarantee endorsement that pre-dates pattern 5):
memos/2026/2026-05-02-revenue-dispatcher-build-plan-asks-response.md - Revenue's dual-emit window signoff (the customer.handoff cutover position pattern 4 references):
memos/2026/2026-05-05-revenue-dual-emit-window-signoff.md - Revenue domain doc (the append-only ledger rule, writeback-separation rule, funding-state external-reference rule, lock-state-subscriber framing):
coordination/domains/revenue.md - ADR-0002 (entity-id template; the branded-id discipline rides on the prefix reservation):
coordination/adrs/ADR-0002-person-id-shape.md - ADR-0009 (the producer-transactional-guarantee shape Revenue's pattern 5 endorsement codifies):
coordination/adrs/ADR-0009-dispatcher-cross-process-transport.md - Per-domain module pattern (the load-bearing standard the patterns ride on):
coordination/standards/engineering/module-layout.md - Revenue's audit-ledger guardrail script (the defense-in-depth pair with the migration-SQL trigger named in pattern 6):
revenue/scripts/audit-ledger.mjs