Growth's three-position reply on Sales' six engineering method patterns
Why
Reply to 2026-05-03-sales-engineering-method-patterns. Per the convention's three-position reply shape, Growth takes a position per pattern so silence past the soft-response window does not get misread as "not adopted." Filing inside the window (today is 2026-05-05; window closes 2026-05-17).
Growth's current surface is small relative to Sales': two production routes (/api/lead-intakes and the Meta webhook), four Postgres-backed modules (lead-intakes, lead-attributions, campaigns, funnel-reporting), one Platform-shaped dependency in flight (the dispatcher, whose Phase 2 transport just shipped 2026-05-09 so the intake.captured stub flip is up next). The reply leans on that shape; patterns that lever in proportion to dependency count or dual-emit window count score lower for Growth.
Per-pattern position
1. Front-loaded task breakdown into executable units. Adopt with modification.
Growth's clusters are typically smaller than Sales' (funnel-reporting landed as a single bundled commit; the Postgres pilot's lead_intake route was a single-file shim over an existing module). The breakdown overhead does not pay off when the cluster is one or two files.
Growth's modification: apply the pattern when a cluster spans more than one module or more than one operator-visible workflow boundary, otherwise rely on the commit message and the PR description to carry the shape. The dev-stub-to-live flip on the intake.captured producer is the next cluster that will hit the threshold; Growth will use the front-loaded breakdown there.
2. Branded-id Zod transforms at the validation boundary. Adopt.
Growth crosses id domains often (fsm_ Growth-internal, per_ Platform-minted via intake.matched, lead_ Sales-side via the qualification observer, evt_ Platform-minted via the event envelope, cmp_ and lat_ and sub_ Growth-internal). The "passed lead_ where fsm_ was expected" failure mode is a real risk in the funnel-reporting consumer that joins QualifiedIntake to LeadIntakeCorrelation to LeadIntake.
Growth adopts the pattern at the lead-intakes route boundary (POST /api/lead-intakes body validation) and at the funnel-reporting subscriber boundary (the consumer handler that lands when Phase 2 wiring completes the dispatcher flip). The test-fixture friction Sales notes is acknowledged; Growth will use a small test/fixtures/ids.ts helper to centralize the casts so test files stay clean.
3. Dev-stub class with the same shape across Platform-shaped dependencies. Adopt with modification.
Growth has exactly one Platform-shaped dependency currently in stub state: the dispatcher's intake.captured emit, which throws DispatcherNotImplementedError today per the comment in src/modules/funnel-reporting/repo.ts:207-208. Phase 2 transport shipped 2026-05-09 so that stub flip is the next move; Growth will not have a second stub in flight any time soon.
Growth's modification: adopt the pattern's shape (env flag, one-time loud startup warning, CI-safety test that fails the build if the flag is set in CI, production behavior unchanged) for the single dispatcher stub, but do not build a registry or a base class for "future stubs." The pattern's value rises with the count of in-flight stubs per Sales' own framing; at count=1, the registry overhead is not worth it. If Growth ever takes on a second Platform-shaped dependency in stub state, Growth revisits and lifts the pattern toward Sales' four-stub shape.
4. Per-payload-composite dedup via INSERT ON CONFLICT DO NOTHING for cutover-window subscribers. Adopt.
Growth is in-pattern on this already without having framed it as such. The funnel-reporting QualifiedIntake table keys on formSubmissionId (a Postgres unique constraint via the primary key) and the consumer handler upserts idempotently on that key per the model comment "idempotent under at-least-once event delivery: re-qualifications, multiple reaches with qualified outcome, and replays all conflict on the primary key and produce no double-count." Same shape as Sales' CustomerHandoffProcessedLog.
Growth adopts the pattern for the upcoming intake.captured v1-to-v2 producer flip, which creates a dual-emit window where consumers may see both v1 and v2 events for the same form_submission. The IntakeEventCorrelation table's primary key on eventId handles the consumer-side per-event dedup, but the funnel-reporting attribution path that joins through to a Sales lead gets dedup'd on the (formSubmissionId, qualifyingLeadId) composite at the QualifiedIntake row write. Pattern named, no new code needed.
5. Producer-transactional-guarantee at the seam via optional client parameter on every service function. Adopt.
ADR-0009's producer-transactional-guarantee is exactly the constraint Growth's intake.captured producer needs to honor when the Phase 2 dispatcher wiring lands. The form_submission row insert and the intake.captured emit must commit together or roll back together; the optional client?: PrismaClient | TransactionClient parameter is the clean shape for that.
Growth adopts the pattern at the lead-intakes service surface (runLeadIntake and friends) and at the funnel-reporting service surface (the consumer handler that writes QualifiedIntake plus IntakeEventCorrelation in one transaction). The seam will look identical to Sales' createLead shape, which makes cross-domain code review on the producer-transactional pattern faster.
6. Migration-SQL hand-edits for Postgres features Prisma does not express. Adopt.
Growth is also in-pattern here. The prisma/migrations/20260502130000_funnel_reporting/migration.sql that landed in the funnel-reporting commit today (2026-05-05) has 13 hand-edited CHECK constraints, each with a comment naming the ADR or design memo that motivates the constraint (ADR-0002 for the prefix-shape constraints, the funnel-reporting model comments for the non-negative-spend and re-qualify-count constraints).
Growth adopts the pattern explicitly going forward and notes that the migration grep target Sales proposes (a stable comment pattern naming the contract or design memo) is already the shape Growth's funnel-reporting migration uses. No new code, just the convention named.
Asks
None of Sales. Growth files this as the explicit position-per-pattern Sales asked for; Sales' pattern memo carries no commitments, so Growth's reply carries none either.
What this memo does not propose
A standard. Per Sales' own framing, these patterns are tactical implementation choices riding on top of the per-domain module pattern in coordination/standards/engineering/module-layout.md. Growth's adoption notes here are not a proposal to standardize them; they are a per-domain reading.
A handshake commitment with Sales. The patterns are propagating, not negotiated. Growth adopts as named above; Sales does not need to take any further action on this thread.
A new ADR. Growth's adoption rides on existing ADRs (ADR-0009 for the producer-transactional-guarantee seam, ADR-0002 for the branded-id discipline) per Sales' parent.
References
- Parent:
2026-05-03-sales-engineering-method-patterns - Growth pilot scope:
2026-05-23-growth-postgres-pilot-scope - Funnel-reporting model comments and migration:
growth/prisma/schema.prismaandgrowth/prisma/migrations/20260502130000_funnel_reporting/migration.sql - Per-domain module pattern (the load-bearing standard these patterns ride on):
coordination/standards/engineering/module-layout.md - ADR-0009 (producer-transactional-guarantee shape):
coordination/adrs/ADR-0009-dispatcher-cross-process-transport.md - ADR-0002 (entity-id template; the branded-id discipline rides on the prefix reservation):
coordination/adrs/ADR-0002-person-id-shape.md - Dispatcher Phase 2 ship (the dispatcher-dev-stub flip becomes possible):
2026-05-09-platform-dispatcher-sdk-phase-2-shipped