Delivery shim path — platform-collaborative as peer to marketplace and native¶
Generated from a canonical source
This page is a read-only projection of docs/strategy/delivery-shim-path.md.
Edit the canonical file, then run npm --prefix tools/project-knowledge-derive run derive.
Status: Open question — establishing the lane as a peer; per-shim ratification gated on §B catalog
Filed: 2026-05-27
Trigger: Analysis thread (Opus orchestrator + operator, 2026-05-27) applying bc-promo-rules' "what needs to be true" + architect challenge + architectural-principles re-test discipline to the marketplace-vs-native binary. Surfaced that the binary is incomplete — a third sibling lane exists. See METHODOLOGY-AMENDMENTS.md for the methodology lessons (three-pass research discipline; back-door-native anti-pattern; don't subordinate a peer to an existing binary).
The three-lane delivery model¶
delivery-fork.md established a binary: marketplace app (Path A) vs. native first-class platform citizen (Path B). That binary is incomplete. A third lane exists — platform-collaborative shims — where BC ships small, typed, additive extensions to its platform that our marketplace app composes with. The shim lane is not a modifier on Path A. It is a peer.
The distinction matters structurally. A modifier says "Path A, but with some BC cooperation added." A peer lane says "this fails differently, requires different preconditions, has different political cost, and produces different ecosystem benefit." If shim fails differently from both marketplace and native, it is a sibling. The table below shows that it does.
| Dimension | Pure marketplace | Shim (platform-collaborative) | Pure native |
|---|---|---|---|
| Code home | Our worker only | Our worker + BC platform extensions | bigcommerce/bigcommerce + BC services |
| Lifecycle owner | Us | Us; BC owns the seam | BC pod |
| BC platform change | None | Small, typed, additive | Deep, bounded-context ownership |
| Write-off exposure | None on shim; ~30% on app code if Path B ever called per delivery-fork.md | Same as marketplace for our app code; zero on shim itself (BC owns it) | Owned by BC |
| Ecosystem benefit | Us only | Every BC app + merchant | Every BC merchant |
| Political cost | Low | Medium — per-ask BC team coordination | High — BC roadmap claim, pod staffing |
| Failure mode | Shadow-store drift; monkey-patching extension points not designed for the use case; brittleness against platform roadmap changes | BC-side ratification velocity; cascade dependency on keystone shims; back-door-native anti-pattern if asks name our domain | BC roadmap claim risk; bounded-context coordination cost; staff engineer dependency |
Framing each lane by its failure mode is deliberate. A SWOT would collapse these orthogonal axes into a 2×2. The right question in each lane is: "what does failure look like here that it doesn't look like in the other two lanes?" For the shim lane, failure is not "we built the wrong thing" — it is "BC-side ratification stalls" or "we filed domain-named asks that implicitly anoint subscriptions as a native concern." Both failure modes are avoidable with the right ask discipline.
The current codebase is in the pure-marketplace lane. This document establishes the shim lane as an eligible peer so it can be pursued in parallel — not instead of — the existing marketplace delivery.
Architectural-principles preconditions for the shim lane¶
Not every BC-side ask qualifies as a shim. The architectural-principles re-test applied during the analysis thread reclassified several first-pass candidates: four as native (most notably B2B Edition federated identity, which is a domain-ownership ask, not a typed additive extension) and two as pure-app (things we can model ourselves without platform-side changes that would benefit the ecosystem). The eight tests that made those reclassifications:
-
Single bounded context. The change sits inside one existing context's natural boundary (Catalog, Payments, Cart, Checkout, Domain Eventing). Asks that span contexts are federation initiatives, not shims.
-
Existing extension pattern. The ask reuses a documented extension point rather than inventing one. If BC has never done it before, it is either a feature request or a native concern — not a shim.
-
Single source of truth. The shim replaces our shadow store with first-class data. It does not create a second source that will drift against ours. If the ask would produce two owners of the same field, it fails this test.
-
Data, not behavior. Fields, structured slots, contract additions, typed event topics are shim-shaped. Policy decisions, lifecycle ownership, orchestration logic are native-shaped. The test: "if BC implements this, does it make a decision on our behalf?" If yes, it's native.
-
Public-goods test. The extension benefits every BC merchant and app, not only us. An extension that solves only the subscriptions use case is either a native concern (if it belongs in BC) or pure-app work (if it doesn't). A shim that passes this test makes BC better for everyone.
-
Doesn't implicitly anoint our domain. The ask is for general mechanisms — sanctioned-app-emitted event topics, marketplace-declared extension contexts, typed recurrence fields in Catalog — not for domain-named surfaces like "subscription webhooks" or "subscription Checkout step." The back-door-native anti-pattern is: frame the ask in our domain's language, get BC to commit to the surface, and have effectively transferred domain ownership without going through the native conversation honestly.
-
Forward-compatibility. The ask ages well against known platform roadmap. The 2H'26 checkout billing-step replanting is the canonical anchor: any Checkout shim ask must be framed against the post-replanting step ordering, not the current one. Asks that would require immediate rework after a known platform change do not qualify.
-
Reversibility. The extension can be deprecated cleanly if usage doesn't materialize. Typed additive fields can be hidden behind capability flags; sanctioned event topics can be retired if no consumers emerge. An ask that cannot be cleanly reversed is more like a platform commitment than a shim.
Applying these tests to a first-pass shim list reclassified four candidates as native (B2B Edition federated identity; customer-scoped recurring-consent ledger; inventory holds for subscription commitment; mixed-cart recurrence policy) and two as pure-app (retry-aware idempotency at platform level; platform-computed customer LTV / subscription_count fields). See ../feasibility/platform-shims.md §C and §D for the full reclassification table and rationale.
Keystone shims — forward-link, don't duplicate¶
The per-shim analysis lives in ../feasibility/platform-shims.md. This section identifies three keystones that cascade through the rest of the shim catalog. Ratifying any keystone is not additive — it unlocks a cluster of dependent shims that have been stalled waiting for it.
A1 — product.recurrence_options (Catalog). Adds a structured, typed slot to the BC Catalog product entity for subscription recurrence options — intervals, trial periods, billing cycles. Currently the marketplace app shadows this data in our own D1 schema; merchants configure it in our admin surface; BC never sees it as first-class product data. Nine of fifteen catalog-domain shims cascade from A1 ratifying: storefront Catalog API exposes recurrence options directly, cart line items carry interval, order line items carry cycle metadata. Without A1, every downstream catalog shim is either pure-app work or blocked. See ../feasibility/platform-shims.md §B for the per-keystone analysis.
A8 — authorize/capture adapter split (Payments). Adds a typed separation between payment authorization and capture in the BC Payments orchestration layer, with configurable capture-on-ship timing. Currently the marketplace app's adapter.charge() is auth+capture atomic; ADR-0038 captures this as an interim posture. The entire payments shim cluster — six candidates — depends on the platform supporting a deferred-capture path rather than requiring the marketplace app to manage its own authorize/capture state machine against the BC vault. See ../feasibility/platform-shims.md §B.
A15 — sanctioned app-emitted MES event topic (Domain Eventing). Adds a mechanism for marketplace apps to emit structured events into BC's Domain Eventing system under a sanctioned, per-app topic — without those events naming a BC domain. This is the shim that unlocks subscription lifecycle webhooks (merchants subscribe to our MES topic rather than our outbox-cron webhook emitter), email template extensions (BC's notification system composes with our events), and the long-term path toward native-style event contracts — all without filing a "subscription events" ask that would constitute back-door-native. See ../feasibility/platform-shims.md §B.
The keystone dependency structure means the shim path is not a flat catalog of independent asks. It has a critical path. A1, A8, and A15 are the asks that go first; everything else waits for at least one of them to ratify or decline.
Decision criteria¶
The fork is not "is shim better than marketplace?" It is "what would have to be true for the shim lane to be correct?"
For the shim path to be the right lane:
- BC is open to small, typed, additive platform extensions in named bounded contexts on a per-ask basis — Catalog, Payments, Cart, Checkout, Domain Eventing. This is an organizational posture question, not a technical one. The answer is unknown today; it requires BC-side stakeholder conversations that are operator-only work.
- The three keystones (A1, A8, A15) are ratifiable in a reasonable cadence — months, not years. If the BC-side conversation on any keystone takes two years, the shim lane is effectively closed for that cluster and the marketplace-app mitigations stay load-bearing.
- We can sustain the BC-side conversation cadence. Per-team owner outreach is the operator's responsibility. The agent cannot file these asks; they require named team DRI conversations. This dependency is structural.
- The marketplace-app shape continues to ship while shims ratify in parallel. Shim ratification accelerates and supersedes parts of the marketplace implementation; it does not gate shipping.
- BC accepts general-mechanism asks rather than domain-named asks. The test: "would this extension exist on the platform if subscriptions didn't?" If yes, it passes. If it requires BC to say "we're adding this for subscriptions," it's either a native ask or a back-door-native ask.
What's true today: zero shims ratified; the lane is being established with this document. The keystones are inspectable asks; the per-shim catalog is enumerated in ../feasibility/platform-shims.md; the architectural-principles test has been applied; the B2B reframe is honest (B2B identity federation is a native concern, not a shim). What's pending is BC-side conversation.
What survives across all three lanes¶
portability-inventory.md tags artifacts for the two-fork model. The shim lane is additive: everything that survives both marketplace and native also survives the shim lane. The table below extends the portability framing.
| Artifact category | Pure marketplace | Shim (platform-collaborative) | Pure native |
|---|---|---|---|
| Behavioral specifications (BRD/PRD/AC) | Invariant | Invariant | Invariant |
| Behavior-rail ADRs (ADR-0028 eligibility, ADR-0011 idempotency, ADR-0024 delivery-instance, ADR-0027 outbox-cron) | Behaviors, not mechanisms — survive | Survive | Survive |
| Mechanism-rail ADRs (ADR-0037 vault, ADR-0038 capture timing) | Survive as-is | Converted to interim on shim ratification (A9, A8 respectively) | Rewritten against BigPay |
| Prototype-as-spec | Survives | Survives | Survives |
| Methodology + Hive substrate | Portable | Portable | Portable |
The mechanism-rail ADRs deserve explicit treatment. ADR-0037 (stored instruments as canonical charge rail) and ADR-0038 (capture timing) are both load-bearing in the marketplace lane today. They are interim in the shim lane — the vault façade is the right answer until A9 (a typed BC-native stored-instrument accessor for marketplace apps) ratifies, and the atomic charge is the right answer until A8 ratifies. The shim path doesn't invalidate these ADRs; it defines the conditions under which they are superseded. The transition is forward-declared, not retroactive.
What's lane-dependent¶
| Mechanism | Pure marketplace | Shim (platform-collaborative) | Pure native |
|---|---|---|---|
| Substrate mechanics (CF bindings, D1, Worker cron) | Load-bearing | Shared with marketplace; shims add BC-side seams, not replace CF-side | Discarded |
API consumption (/v3 REST + OAuth per merchant) |
Load-bearing | Shared until shims expose native typed reads; OAuth stays | Internal gRPC; no /v3 consumption |
| Payment vault façade (ADR-0037) | Owns it | Superseded on A9 ratification | BigPay direct |
| Storefront integration (Scripts API + widget injection) | Owns it | Superseded on A11/A12 ratification (typed Catalog storefront fields) | Ships with storefront-kit |
| Domain eventing | Our own outbox + BC webhook emitter | Emission lifts to sanctioned MES topic on A15 | Participates in MES natively |
| BC platform schema | No changes | Small typed additive fields and event topics | Bounded-context table ownership |
The shim lane's footprint is narrower than this table implies in steady state. The marketplace app keeps running as-is; shims are additive extensions that supersede specific mechanisms without requiring the marketplace app to be rebuilt. The transition is per-cluster, not wholesale.
Why this isn't a SWOT either¶
The three-lane model has at least four independent axes (code home, lifecycle owner, public-goods benefit, political cost), and the dominant constraint for the shim lane — BC-side ratification velocity — lives entirely outside the artifact. A SWOT would score shim as "strengths: ecosystem benefit, future platform alignment; weaknesses: BC dependency; opportunities: native upgrade path; threats: BC declines." That framing is useless for prioritization. It doesn't tell you whether to file A1 or A8 first, whether to frame the ask as a general mechanism or a domain-specific one, or what the cascade dependency structure looks like.
The right instruments are the same as delivery-fork.md identified, extended:
../feasibility/platform-shims.md— per-shim catalog with architectural-principles test applied to each- portability-inventory.md — extended above for three lanes
- This document — narrative wrapper + decision criteria
- A
[Spec]Hive proposal referencing the three, once the lane is operator-confirmed
The per-lane comparison table in §2 is the right analytical instrument for the lane-selection question. The per-shim catalog is the right instrument for the sequencing question.
Revisit conditions¶
Symmetric with delivery-fork.md's revisit posture. The shim path is revisited if:
- Any keystone (A1 / A8 / A15) ratifies. Positive revisit — pull all dependent shims in that cluster into the active queue; update mechanism-rail ADRs to interim; file the supersession
[Decision]proposals. - BC explicitly declines a keystone after a stakeholder conversation. Negative revisit — narrow to non-cascade shims that don't depend on the declined keystone, or fold those cluster shims back into pure-marketplace mitigations and close them with honest
oos_markerentries. - The 2H'26 checkout billing-step replanting lands without subscription input. Forward-risk realized. Any Checkout-cluster shim ask (A11, A12) may need reframing against the post-replanting step ordering. Revisit timing: at Checkout replanting GA announcement.
- Two or more of the four delivery-fork.md revisit conditions flip (BC org-alignment posture shifts; pod staffing commits; bounded-context boundary stabilizes; BC release cadence opens). When those conditions shift, re-test whether the shim lane is still the right peer or whether native graduation is the conversation instead. The shim lane does not preclude native — it operates in parallel with Path A and can coexist with a native-graduation conversation if one ever opens.
Recommendation¶
The analysis thread produced five concrete next actions:
-
File the three keystones (A1, A8, A15) as inspectable BC-side conversation topics with named team owners. The asks are formulated in
docs/feasibility/platform-shims.md§A with the architectural-principles tests applied. The BC team DRI outreach is operator-only work; this is not agent-executable. The asks should be framed as general-mechanism requests (typed Catalog recurrence slot; authorize/capture adapter separation; sanctioned-app MES topic) — not as "we need BC to support subscriptions." -
Continue marketplace-app delivery in parallel. ADR-0037, ADR-0038, the outbox-cron eventing rail, and the Scripts API storefront injection are the load-bearing mechanisms today. Shim ratification supersedes them cluster by cluster; none of it gates the current delivery. Portfolio posture: marketplace ships, shim path ratifies asynchronously.
-
Treat the B2B reframe honestly. B2B-on-subscriptions is
blocked-on-other-teamregardless of shim ambition. The analysis thread reclassified B2B federated identity as a native ask (does not pass the single-bounded-context or data-not-behavior tests). The right next move is filing a B2B identity federation initiative as an independent proposal — not under the subscriptions umbrella, not as a shim. Conflating the two in stakeholder communications creates false urgency on the B2B path and understates the actual scope. -
Convert ADR-0037 and ADR-0038 to interim status via separate
[Decision]Hive proposals. Both ADRs are the right marketplace answer today. Both have a named shim path that supersedes them. Future readers should see the supersession condition without having to trace back to this document. The[Decision]proposals should encode: "superseded when A9 / A8 ratifies; remains load-bearing until then." -
File a
[Spec]Hive proposal extending fork-aware priority to three lanes. Current CLAUDE.md posture isportable > substrate-A(Hive #1519, ADR context). The shim lane warrants a third tier:portable > shim-collaborative > substrate-A. Shim-collaborative work (per-shim feasibility analysis, BC-side ask formulation, keystone dependency mapping) ranks above pure substrate-A work because it compounds — a ratified shim benefits every BC app, not only ours, and the ecosystem-benefit test in §3 is what distinguishes it from substrate-A. The priority extension does not apply to BC-side conversation work itself (which is operator-gated) but does apply to our analysis and framing artifacts for those asks.
References¶
../feasibility/platform-shims.md— the per-shim catalog; §B for keystone analysis; §C for reclassification table- delivery-fork.md — the marketplace-vs-native binary this document extends to three lanes
- native-shape-gap.md — dimension-by-dimension gap matrix between marketplace and native shapes
- portability-inventory.md — artifact-level portability tagging; extended above for three lanes
- ADR-0029: Marketplace-first, native-ready — current marketplace-first posture; this document adds the shim lane as a named peer without replacing ADR-0029
- ADR-0030: BigEng pattern alignment — pattern alignment context; shim asks must respect BigEng extension-point patterns
../../METHODOLOGY-AMENDMENTS.md— methodology lessons captured from the analysis thread: three-pass research discipline; back-door-native anti-pattern; don't subordinate a peer to an existing binary/Users/nino.chavez/Workspace/dev/wip/bc-promo-rules/docs/feasibility.md— cross-project precedent for a sibling-option doc; CEL/Phase 2 was established as a peer to typed conditions using the same "what needs to be true?" + architect-challenge discipline applied here