Strategy → Delivery fork
Bolt-on app vs. first-class platform citizen.
An open strategic fork: bc-subscriptions can ship as a BC marketplace app (current shape) or as a native first-class BC service. They are not points on a continuum — they are different runtime substrates with different teams, languages, and operational shapes. This page surfaces the dimension-by-dimension gap, the artifact-level portability inventory, and the decision criteria — so the conversation with stakeholders happens against an honest scope, not abstractions.
Filed 2026-05-22 · Trigger: Slack thread, jordan.sim ↔ nino.chavez · Source authority:docs/strategy/delivery-fork.md
Path A
Marketplace app
BC marketplace app, App Extensions for control panel, own runtime (Cloudflare today / GCP Phase 2 per ADR-0030), consumes BC public APIs, owns its own data store, OAuth client per merchant, own payment-method vault wrapping BC Payments (ADR-0037), shipped/billed/supported as a marketplace product.
~95%+ of current investment on-rails
Path B
Native first-class
BC domain service owned by a Pod (paralleling Billing Pod's msms), Ruby/Scala/Java backend, gRPC interface in bigcommerce/interfaces, Nomad/Launchbay deploy, BigPay direct (not our vault), RabbitMQ Domain Eventing, Lightstep observability, BC's internal request-context propagation.
~70% of current investment directly portable; ~30% (bolt-on-only + rework) is executable spec
Native-shape gap matrix
20 substantive dimensions where current shape diverges from BigEng standards.
S — small
1
M — medium
7
L — large
6
XL — discardable
6
| # | Dimension | Current | Path A (marketplace) | Path B (native) | Rework A→B |
|---|---|---|---|---|---|
| 1 | Runtime infrastructure/deployments/containers.md | Cloudflare Workers (V8 isolates) | Cloud Run on GCP (Phase 2) | Nomad-scheduled containers in CDE/platform cluster; .container.yml | XL |
| 2 | Language services/merchant-subscription-manager-service.md | TypeScript (Hono) | TypeScript | Ruby (msms, BigPay) / Scala (api-proxy) / Java — never TS backend | XL |
| 3 | Service interface technical/standards/interfaces/protobuf-style-guide.md | Our REST API (apps/api) | REST + GraphQL | gRPC; protos in bigcommerce/interfaces | XL |
| 4 | Public API services/api-gateway.md | Our REST is the public surface | Hardened, versioned, OpenAPI | No public API; api-proxy-java composes our gRPC into BC /v3 and GraphQL | XL |
| 5 | Data store technical/standards/bounded-contexts.md | Cloudflare D1 (we own) | Cloud SQL MySQL (we own) | Shared store DB, bounded-context partitioned; never JOIN across contexts | L |
| 6 | Auth / context technical/standards/internal-services/context-propagation.md | OAuth token per merchant install | Same | x-bc-request-context-bin, x-audit-principal-bin, OT-trace (OpenTelemetry distributed tracing) via gRPC trailing metadata | L |
| 7 | Eventing technical/standards/domain-eventing.md | D1 outbox → Worker cron → BC webhooks | Cloud Tasks / Pub-Sub | RabbitMQ Domain Eventing; events in bigcommerce/interfaces | L |
| 8 | Layering technical/standards/layering.md | App-shaped: routes → handlers → D1 | Same | Strict Domain / Application / Infrastructure; immutable cross-layer DTOs | M |
| 9 | Bounded context technical/standards/bounded-contexts.md | We own our context boundary | Same | Cannot read Orders/Customers/Catalog tables; call their public interfaces | M |
| 10 | Payments / vault services/bigpay.md | Our bc-vault-client wraps BC /v3/payments (ADR-0037) | Same | Direct gRPC into BigPay; no separate vault façade | XL |
| 11 | Transactionality technical/architecture/transactionality.md | Eventual consistency + producer-outbox | Same | Sagas + 2PC; DB transactions within context; events across | M |
| 12 | Observability services/bigpay.md | Wrangler logs + Analytics Engine | + Sentry, dashboards | Lightstep + logstash app_name + Sentry per-habitat + Prometheus + Grafana | L |
| 13 | Deploy infrastructure/deployments/strategies.md | wrangler deploy from GHA | GHA → Cloud Run | Launchbay → Nomad → habitats (int/stg/prd); canary + rollback | XL |
| 14 | Secrets infrastructure/deployments/secrets.md | Wrangler secrets + Cloudflare KV | GCP Secret Manager | HashiCorp Vault | S |
| 15 | Service mesh infrastructure/deployments/containers.md | n/a (Workers routing) | Cloud Run native | Consul Connect + Envoy sidecars | M |
| 16 | Cluster placement infrastructure/deployments/containers.md | n/a | n/a | admin / payments (CDE) / platform — likely payments for PCI scope | M |
| 17 | Storefront surface | Stencil widget + Catalyst SDK + Web Component (ADR-0013) | Same | Native storefront UI in BC storefront-kit / Catalyst directly | L |
| 18 | Admin surface | App Extensions + iframe + our admin app (ADR-0012) | Same | Native control-panel routes in BC App with BigDesign | L |
| 19 | Merchant audit log sdlc-frameworks/bigcommerce-bigeng.md (Gate 3) | Our D1 audit_log table | Same | BC's merchant-facing audit log surface (BigEng DoD Gate 3) | M |
| 20 | Performance SLO sdlc-frameworks/bigcommerce-bigeng.md (Gate 4) | ≤ 800ms p95 admin; ≤ 1.5s writes | Same | < 100ms p95 (BC API DoD); < 200ms TTFB | M |
Aggregate read: 6 XL, 6 L, 7 M, 1 S across 20 dimensions. Calling Path B "refactoring" understates it — it's a re-implementation with the current codebase serving as executable spec.
Portability inventory
How each existing artifact travels across the fork. Curated highlights — full inventory (81 ADRs + specs + prototype + substrate + tooling) in docs/strategy/ (in repo).
🟢 Survives both
27
🟡 Bolt-on only
5
🔴 Requires rework
8
🟣 First-class only
0
ADR (19)
| 0010 | Webhook / event egress | Path B = RabbitMQ Domain Eventing | 🔴 requires rework |
| 0011 | Charge idempotency + retry semantics | Universal behavior | 🟢 survives both |
| 0012 | Merchant admin stack (Vite + React + BigDesign) | Native admin lives in BC App | 🔴 requires rework |
| 0013 | Storefront-components shape | Native ships in storefront-kit directly | 🔴 requires rework |
| 0014 | Subscriber-surface auth (magic-link + JWT) | Native uses BC session model | 🔴 requires rework |
| 0015 | Observability stack | Path B = Lightstep + Sentry + Prometheus | 🔴 requires rework |
| 0016 | Tax engine — defer to BC | 🟢 survives both | |
| 0023 | B2B Edition checkout-ownership pattern | Architectural pattern, fork-agnostic | 🟢 survives both |
| 0024 | DeliveryInstance as first-class entity | Domain entity | 🟢 survives both |
| 0027 | Outbox marker + catch-up cron | Eventing mechanism changes | 🔴 requires rework |
| 0028 | Eligibility-engine chokepoint pattern | Domain pattern | 🟢 survives both |
| 0029 | Marketplace-first, native-ready | Encodes the fork posture itself | 🟢 survives both |
| 0030 | BigEng pattern alignment | Explicitly bridges to native standards | 🟢 survives both |
| 0037 | Stored instruments as canonical charge rail | Entire vault façade vestigial in Path B | 🔴 requires rework |
| 0038 | Capture timing | BigPay must respect this too | 🟢 survives both |
| 0054 | Cloud SQL engine | Path A Phase 2 specific | 🟡 bolt-on only |
| 0060 | PCI scope SAQ-A boundary | Compliance posture | 🟢 survives both |
| 0061 | STRIDE payment flow threat model | 🟢 survives both | |
| 0063 | Email pipeline event pattern | Eventing mechanism changes | 🔴 requires rework |
Spec (6)
| BRD | User stories + AC | Behavioral; what, not how | 🟢 survives both |
| PRD | Product surface area | 🟢 survives both | |
| PRD-COMPANION | Worked examples | 🟢 survives both | |
| ARCH | Current architecture document | Documents the bolt-on shape; needs native companion on Path B | 🟡 bolt-on only |
| ADMIN-SPEC | Operator surface | Behavioral; mechanism changes | 🟢 survives both |
| PERSONAS | 5-actor persona model | Identity invariant | 🟢 survives both |
Prototype (7)
| PDP | Subscription PDP widget interactions | Design oracle for native storefront-kit | 🟢 survives both |
| Cart | Cart/checkout subscription affordances | 🟢 survives both | |
| Portal | Account portal flows (manage / pause / skip / cancel) | 🟢 survives both | |
| Admin-UX | Admin dashboard (plans, instances, dunning) | Operator UX portable | 🟢 survives both |
| Email previews + templates | 🟢 survives both | ||
| Connect-flow | Connect-your-store flow | Path B has no "connect" step | 🟡 bolt-on only |
| Onboarding | Marketplace install onboarding | 🟡 bolt-on only |
Substrate (4)
| Hive | Proposal / synthesis / decision workflow | Process is portable | 🟢 survives both |
| hive-meta | hive-meta metadata block | 🟢 survives both | |
| ADR-0055 | Substrate-derived-from-GH automation | 🟢 survives both | |
| Methodology | Two-track methodology + 10-gate DoD | 🟢 survives both |
Tooling (4)
| state-derive | tools/state-derive/ | Derives state from our codebase shape | 🟡 bolt-on only |
| hive-board-derive | tools/hive-board-derive/ | Process automation | 🟢 survives both |
| code-review-bot | Code-review bot v1.3 | Quality discipline | 🟢 survives both |
| sandbox-CI | Sandbox-scenario CI | Rebinds to native test infra | 🟢 survives both |
Aggregate read: ~70% of catalogued artifacts survive both paths (process, behavior, domain rules, methodology). ~20% are bolt-on-only (substrate mechanics, marketplace economics, our API surface). ~10% require implementation rework on Path B (where BC's standards mandate specific mechanisms — eventing, observability, vault, admin/storefront surfaces). The substrate mechanics are the smallest fraction by artifact count but the bulk of the rebuild cost on Path B.
Decision criteria
Not "which path is better?" — "what would have to be true for path X?" Each row is a condition that must hold for the corresponding path to be correct.
| Dimension | For Path A (marketplace) to be correct… | For Path B (native) to be correct… |
|---|---|---|
| Product positioning | Durable marketplace offering with rev-share / platform-fee economics | BC platform treats subscription billing as native capability, not partner-app concern |
| Team ownership | Continues as current team (you + handoff partners) | A Pod (Billing / Payments / new Subscriptions) owns it; staff engineer shepherds gRPC contract |
| Bounded context boundary | We own our context; integrate via public APIs | Boundary against Orders / Payments / Customers / BigPay is identifiable and accepted by those domain owners |
| Release cadence | Marketplace-product cadence (we control) | BC's platform cadence, SLO obligations, on-call rotation |
| Existing investment | ~95%+ of current code/ADRs/specs continue forward | ~70% survives as-is; ~30% (bolt-on-only + implementation rework) serves as executable spec for re-implementation |
| Native graduation | Option, not commitment (ADR-0029) | The commitment |
What's true today: neither column is fully checked. Path A has the most existing investment. Path B has the strongest architectural-correctness argument per Jordan's framing, but requires organizational decisions outside the project's scope.
Recommendation
Continue prototype-track work (Jordan explicitly endorsed this as the engineering handoff artifact). Freeze new platform-substrate ADRs until the fork is called — anything about D1 schema, Worker bindings, Cloudflare deploy, or our public API surface. Continue ADRs that lock in behaviors: capture timing, dunning rules, persona flows, eligibility rules, idempotency semantics. Surface the question through a [Decision] Hive proposal so it can be synthesized rather than living in Slack.
References
- docs/strategy/delivery-fork.md — narrative wrapper + decision criteria + trigger excerpt
- docs/strategy/native-shape-gap.md — full 20-dimension gap matrix with BigEng source citations
- docs/strategy/portability-inventory.md — exhaustive artifact-level portability tagging
- bigcommerce/merchant-subscription-manager — structural precedent (BC GitHub, internal access)
- BigPay overview — canonical payments platform a native subscription service integrates with
- BigEng — Bounded Contexts — the governing principle for native service design
- ADR-0029: Marketplace-first, native-ready — current posture (a graduation option, not commitment)
- ADR-0030: BigEng pattern alignment