Neon and Snowflake physical storage¶
Physical storage specification for the decision_* tables in Neon and the signal_* /
decision_* schemas in Snowflake.
Aligned to the one-way CDC model in ADR-003 and the decision publication pattern in ADR-036. Converts the data-contract layer into physical storage structures.
Design principles¶
- Neon → Snowflake carries operational facts through CDC. Snowflake does not become the operational system of record.
- Snowflake → Neon returns only approved, stable decision outcomes. It does not push back raw analytical features or internal model state.
- Reason codes must be both machine-readable and human-readable. The returned operational decision must show the status, score summary, short labels, and plain-language explanations without exposing the full internal algorithm.
- All return publications must be versioned, idempotent, and replay-safe.
- Physical tables must support auditability, lineage, and point-in-time reconstruction of the decision that was applied.
Schema layout¶
| Platform | Schema | Purpose |
|---|---|---|
| Neon | decision_inbox |
Inbound approved decisions from Snowflake awaiting application |
| Neon | decision_state |
Current operational decision state by customer/application/payment |
| Neon | integration |
Delivery, replay, and idempotency tracking |
| Snowflake | signal_raw |
Append-only typed signal events |
| Snowflake | signal_curated |
Conformed and query-friendly signal layers |
| Snowflake | decision_curated |
Approved decision results ready for publication |
| Snowflake | governance_meta |
Contract versions, reason-code catalogues, and publication metadata |
Neon physical model¶
Neon stores operationally relevant results. It mirrors Snowflake's full analytical structures only where operationally necessary. Instead it keeps the current applied decision state, a replay-safe inbound queue, and delivery logs.
decision_inbox.decision_result_inbox¶
Append-only inbound publication queue from Snowflake. One row per decision publication
attempt keyed by decision_id and idempotency_key. Processed asynchronously by
operational application services.
| Column | Type | Notes |
|---|---|---|
decision_id |
uuid | Primary identifier for the decision result |
idempotency_key |
text | Unique constraint; replay-safe apply key |
entity_type |
text | CUSTOMER, APPLICATION, PAYMENT |
entity_id |
text | Identifier in the operational domain |
decision_type |
text | ONBOARDING, RISK_TIER, FRAUD_ACTION, SCREENING_ACTION |
decision_status |
text | ACCEPT, REJECT, REFER, HOLD, CLEAR |
risk_score |
numeric(8,2) | Optional score summary |
fraud_score |
numeric(8,2) | Optional score summary |
risk_tier |
text | LOW, MEDIUM, HIGH |
reason_summary |
jsonb | Human-readable and machine-readable reason list |
policy_refs |
jsonb | Policy references e.g. AML-011, AML-012, AML-013 |
model_versions |
jsonb | Risk/fraud model versions used |
effective_at |
timestamptz | When the decision becomes active |
expires_at |
timestamptz | Optional expiry |
source_contract_version |
text | Decision contract version |
ingested_at |
timestamptz | Default now() |
processing_status |
text | PENDING, APPLIED, FAILED, SKIPPED |
processed_at |
timestamptz | When operational system applied it |
decision_state.customer_decision_state¶
Current applied state per customer. Supports fast lookups by onboarding, servicing, fraud operations, and case management. Stores the latest effective decision rather than the full history.
decision_state.application_decision_state¶
Current applied state per onboarding application. Useful when a customer can have multiple applications or resubmissions.
integration.decision_delivery_log¶
Tracks publication receipt, validation, apply outcome, retry outcome, and errors. Supports operational support and replay analysis.
Snowflake physical model¶
Snowflake holds the analytical and decisioning layers. The tables below are designed so the signal and decision contracts map directly into physical storage without each model inventing its own payload shape.
signal_raw.signal_event¶
Append-only fact table for typed signals. Stores raw but structured risk, fraud, and screening observations. Allows lineage back to producing module, policy, and model version.
See Signal taxonomy v1 for the full signal code catalogue.
signal_curated.customer_signal_current¶
Materialised latest-state view/table for current customer-facing signal posture. Used by risk, fraud, onboarding, and case operations for quick reads.
decision_curated.decision_result¶
Approved decisions ready for publication back to Neon. Holds a compact score summary and operator-friendly reason package. Can be published repeatedly without changing decision identity.
governance_meta.reason_code_catalog¶
Canonical reason-code registry. Each code includes:
| Field | Purpose |
|---|---|
reason_code |
Stable machine key |
reason_label |
Short operator label |
reason_text |
Plain-language explanation template |
score_impact |
Optional signed summary impact |
display_rank |
Default display order shown to humans |
Publication and apply flow¶
| Step | Platform | Action |
|---|---|---|
| 1 | Neon | Operational facts created and replicated outward through CDC |
| 2 | Snowflake | Signals created, aggregated, and evaluated by risk/fraud/AML logic |
| 3 | Snowflake | Approved decision_result row created with reason package and scores |
| 4 | Snowflake → Neon | Decision result published to decision_result_inbox |
| 5 | Neon | Operational service validates idempotency_key and applies decision |
| 6 | Neon | Current state updated; apply outcome written to decision_delivery_log |
Human-readable reason design¶
The return contract to Neon always contains two layers of reasoning:
- A compact machine-readable reason code list — e.g.
PEP_MATCH,DEVICE_CLUSTER_RISK,ADDRESS_MISMATCH. - A customer-service-readable explanation list — e.g. "Application linked to a device already used by multiple identities" or "Additional identity review is required because address information could not be confidently matched."
This gives clear visibility in operational systems without disclosing hidden thresholds, internal weights, or all features used by the scoring model.
Related¶
- ADR-036 — Decision result publication
- ADR-003 — CDC pipeline
- Data contracts and decision publication
- Policy DT-012 — Ledger Data Contracts & Event Publication
- Policy OPS-007 — Financial Processing Resilience & Idempotency
- MOD-042 CDC pipeline — Neon logical replication to S3 Iceberg
- MOD-043 EventBridge domain event governance