Inspect
Research corpus and decision lineage.
All Stage 1 research files, architectural decision lineage, and methodology notes.
Every competitive claim in the portal traces to a file in research/competitive/.
Stage 1 research corpus
BC Promotions Engine — Current State
Full execution flow, DiscountContext structure, why domain.Customer { ID, GroupID } is the only customer context at evaluation time, and the structural gap.
Architectural Options
Option A (PHP typed conditions) vs Option C (CEL expression engine in Go). Recommended phased path. What's already "paid for" in the cart hydration pipeline.
Competitive Synthesis
Six-platform competitive matrix. BC below market minimum on three criteria. Guest checkout differentiation analysis. SAP RAO pattern as architectural model.
Personas
Three personas: Enterprise IT / Marketing Ops Admin, Mid-Market B2B Distributor, Solution Engineer / Agency Developer. Trigger events, success signals, objections.
Current Promotion Setup Flow
Step-by-step walkthrough of the Advanced Promotion Manager, exactly where in the Conditions panel merchants hit the wall, and what the missing "Customer" condition category would look like.
Architectural decision lineage
Why CEL over OPA (Rego)?
CEL is non-Turing-complete, Go-native, and production-proven in Kubernetes admission webhooks.
OPA/Rego is optimized for recursive set operations — not checkout-path predicate evaluation.
CEL's Go library (github.com/google/cel-go) integrates directly
into the Go promotions service without an RPC boundary.
Source: architectural-options.md ↗
Why Phase 1 uses PHP typed conditions, not the Go CEL path?
Email is already in the cart record at checkout step 4 — zero additional fetches, zero latency cost. The PHP monolith's typed condition DSL can extend today. The Go service extraction is the right home for the CEL model, but it is a WIP milestone not yet on the customer-attribute evaluation path. Phase 1 proves the transformer plumbing without architectural commitment. Phase 2 migrates to CEL.
Why no customer metafields as condition targets?
BC platform policy (domains/metafields.md) prohibits building business logic on top of metafields.
Customer custom fields (formfieldvalues, customers-scala gRPC) are the designed extension point.
A portal or proposal using metafields as condition targets would be rejected at engineering review on policy grounds.
Why is guest checkout targeting in Phase 2, not Phase 1?
billing_address.email is in the checkout record for guests — no additional data fetch.
The deferral is CP UX, not technical feasibility: guest customers have no persisted account,
and the conditions editor needs a clear explanation of how the email is obtained for the
"no account" case. Phase 1 covers signed-in customers (matching Shopify). Phase 2 ships the differentiation.
How this session was run
This proposal was built using the Blueprint methodology — three-stage greenfield pipeline. Stage 1 produced the research corpus above (five files, sourced against BC platform docs and competitive sources). Stage 2 produced the design document (DESIGN.md ↗) with five visual rules and architectural invariants. Stage 3 produced this portal. See docs/how-this-session-worked.md ↗ for the full methodology trace.