Entimema

Building a Credit Risk Feature Store That Actually Respects Time

Entimema
Contents

A production decision at 2026-08-18 14:00 used MissedPayments_90d = 2. Today, the offline warehouse says the historical value was 1. Was the difference caused by a late payment, a correction, new feature logic, a window boundary, stale online state or a changed identity mapping?

PRODUCTION @ 14:00MissedPayments_90d = 2OFFLINE TODAYMissedPayments_90d = 1

If the platform cannot answer why, it is not a controlled model-input layer. Serving matching column names online and offline is not enough.

A feature store is a semantic contract, not a scalar cache

type FeatureDefinition = {
  featureName: string;
  entityType: "PARTY" | "FACILITY" | "ACCOUNT";
  valueType: "NUMBER" | "BOOLEAN" | "CATEGORY";
  definitionVersion: string;
  observationWindow?: string;
  sourceDomains: string[];
};

Attach a feature to its economic object: payment volatility may be account-level, utilisation facility-level and total internal exposure party-level. Putting every feature under customer_id hides aggregation and duplication errors.

FeatureGrain = (Entity, Time) or (Entity, DecisionContext, Time)
Feature grain

For PaymentRatio_90d, define the exact interval—such as (T−90d, T]—and which timestamp admits an event. Event, effective and posting time are not interchangeable SQL conveniences. Boundary conventions belong in the contract and in tests.

Effective, available and calculated time answer different questions

EVENT / STATEeffective evidenceFEATURE EFFECTIVE13:00CALCULATED13:45AVAILABLE14:00DECISION14:10
A feature can describe state through 13:00, run at 13:45 and reach serving at 14:00. A 13:30 decision cannot use it.
Tavailable ≥ Teffective
Operational sequence
CalculatedAt ≠ EffectiveAsOf
Signature distinction
type FeatureValue<T> = {
  entityId: string;
  featureName: string;
  value: T;
  effectiveAsOf: Date;
  availableAsOf: Date;
  calculatedAt: Date;
  definitionVersion: string;
};

One definition feeds two serving layers with different workloads

SAME DEFINITION + SAME KNOWN STATE
ONLINE STORE
low-latency current serving
OFFLINE PIT STORE
training · validation · replay
IDENTICAL FEATURE VALUE
The online store optimises current key lookup; the offline store supports training, validation and replay while preserving historical availability.
FeatureDefinitiononline = FeatureDefinitionoffline
Semantic consistency

The physical code path may differ, but event inclusion, null handling, identity mapping, reversals and window boundaries may not. An online store alone has no historical modelling capability; an offline store without availability time creates hindsight leakage.

Point-in-time retrieval chooses the latest value legitimately available

getFeatureAsKnown(
  entityId,
  featureName,
  decisionTime
) // latest value with availableAsOf <= decisionTime

A restated API answers a different question: today's corrected feature for an historical effective time. Keep getFeatureAsKnown and getRestatedFeature separate.

SELECT d.decision_id, d.party_id, f.value
FROM decisions d
LEFT JOIN LATERAL (
  SELECT value
  FROM feature_history f
  WHERE f.party_id = d.party_id
    AND f.feature_name = 'payment_ratio_90d'
    AND f.available_as_of <= d.decision_time
  ORDER BY f.available_as_of DESC
  LIMIT 1
) f ON TRUE;

SQL dialects differ. The invariant does not: joining current features is wrong, and filtering only effective_as_of still admits a value computed later. An immutable feature_snapshot_id can simplify replay; dynamic retrieval lowers duplication but demands an immutable temporal store. A hybrid preserves critical scalars, a snapshot reference and reconstructible history.

The registry turns feature names into governed contracts

type FeatureRegistryEntry = {
  name: string;
  entityType: string;
  definitionVersion: string;
  owner: string;
  sourceDependencies: string[];
  observationWindow?: string;
  online: boolean;
  offline: boolean;
};
Minimum feature contract
DimensionRequired meaning
Business definitionWhat economic behaviour does the value represent?
Entity grainParty, facility, account or explicit context
Type and rangeRepresentation and expected domain
Null semanticsUnavailable, not applicable, missing source or failed computation
Time semanticsWindow boundaries, membership timestamp and freshness
SourcesExact governed upstream domains and semantic fields
OwnerDefinition, change control and quality accountability
Serving modeOnline, offline or both

NULL → 0 can silently change meaning. Missingness flags are valid only when online and offline computation preserve identical missing semantics.

Definition changes create new feature versions

Featurev1 ≠ Featurev2
Semantic version boundary

Changing utilisation_30d from average drawn/limit to maximum drawn/limit is a new definition even if the label stays. A pure rename may not be. Never overwrite v1 history with v2 logic.

{
  "modelVersion": "pd-v5",
  "features": {
    "payment_ratio_90d": "v3",
    "max_dpd_180d": "v2"
  }
}

The model registry validates exact feature contracts before deployment. If the model expects v3 and only v4 is available, do not silently substitute: fail validation or take a versioned governed fallback.

Freshness is feature- and decision-specific

FeatureAge = Td − EffectiveAsOf
Economic feature age
ServingLag = AvailableAsOf − EffectiveAsOf
Serving lag
CalculationLag = CalculatedAt − EffectiveAsOf
Calculation lag

A decision policy defines FeatureAge ≤ FreshnessBudget(D,X). Current utilisation may require high freshness; annual income naturally moves slower. One global SLA is semantically weak.

STREAMINGutilisation · recent payment state · transaction countBATCHlong-window aggregates · monthly structural features

Real time is not inherently superior. A mixed vector is sound when each component exposes its own freshness and the decision accepts it explicitly.

Incremental features must equal full recomputation

A streaming PaymentCount_90d can maintain a queue and rolling count rather than scan every customer. Its state remains a performance optimisation, not the source of methodology.

Featureincremental = Featurefull recompute
Feature computation invariant

Compute on write, read or a schedule according to cost, latency, volume and reproducibility. Compute-on-read without a pinned definition can make an old decision return a newly defined feature. Historical values used by decisions should remain immutable by definition version and state mode.

Late events create known and restated feature history

KNOWN FEATURE @ T

The exact value available to production. Immutable for decision replay.

RESTATED FEATURE @ T

The corrected value after late payments, reversals or identity changes.

A late payment may alter today's feature and restated history while leaving the actual historical decision input unchanged. Distinguish production replay backfill, which reconstructs known values, from restated analytical backfill, which uses corrected knowledge.

Every backfill records feature version, source-state mode and execution time. It must never rewrite an immutable decision snapshot.

Feature lineage is a dependency graph, not a free-text note

CANONICAL EVENTS / STATEBASE FEATURESDERIVED FEATURESMODELDECISION
Derived features remain traceable through base features to canonical events and states; cycles are rejected unless an explicit iterative method governs them.
getFeatureTrace(
  entityId,
  featureName,
  asOf
) // definition, inputs, state refs and timestamps

Lineage includes source event/state, transformation version, identity-resolution version and calculation time. It need not inflate every online response, but it must be queryable for model validation and incidents. A derived feature such as current PD minus 30-day-ago PD must preserve both dependency versions.

Point-in-time controls block four distinct leakage paths

Feature leakage taxonomy
ClassFailureControl
Future event leakageFeature includes an event after the decisionWindow ends at decision time
Availability leakageEarlier-effective event became known laterRequire availableAsOf ≤ decision time
Population leakageFuture identity or group relation enters historyUse identity/relationship version known then
Target leakageOutcome information enters pre-decision inputsEnforce source and temporal contract
Window leakage10:00 decision receives full 23:59 day aggregateUse exact intraday boundary, not end-of-day shortcut

The serving API returns values with versions and time

interface FeatureService {
  getCurrent(
    entityId: string,
    featureSet: string[]
  ): Promise<FeatureVector>;

  getAsKnown(
    entityId: string,
    featureSet: string[],
    asOf: Date
  ): Promise<FeatureVector>;
}

type FeatureVector = {
  values: Record<string, unknown>;
  featureVersions: Record<string, string>;
  effectiveAsOf: Record<string, Date>;
  availableAsOf: Record<string, Date>;
};

The decision manifest references the feature-set version, exact feature versions and immutable snapshot or history references. A training dataset manifest adds extraction time, entity population, observation period, point-in-time mode and source versions; a fingerprint can verify metadata and rows, but never replaces lineage.

Shadow comparison turns feature changes into decision evidence

Before replacing an online computation path, run old and new versions over the same live traffic without changing decisions. Compare disagreement rate, magnitude, distribution and downstream decision impact.

OLD FEATURE PIPELINESAME MODEL + POLICYNEW FEATURE PIPELINE
ΔDecision = D(Featurenew) − D(Featureold)
Decision impact

Stable distributions are not proof of semantic consistency: payment count may still average three after its source silently changes from settled to initiated payments. That is semantic drift—economic meaning changed while name and schema remained stable.

A golden feature stream tests time, identity and computation together

Golden feature portfolio and property tests
TestExpected proof
Window boundariesEvents exactly at each boundary follow the declared convention
Point-in-time joinNo value with availability after T enters training or replay
Incremental equalityIncremental value equals full recomputation for identical history
Duplicate eventIdempotent ingestion leaves the feature unchanged
Late paymentRestated history changes; known historical input does not
ReversalPayment features follow the versioned economic-event semantics
Identity correctionCurrent mapping never leaks into old party features
Version compatibilityA model cannot consume an undeclared feature version
Missing featureUnavailable, failed and not-applicable remain distinguishable
Online rebuildRebuilt serving state equals canonical feature history

Use deterministic streams covering clean payments, missed dues, reversal, late payment, multiple facilities, stale source and identity correction. Rebuild both online state and offline datasets from governed definitions rather than treating ad hoc extracts as methodology truth.

Monitor semantics and lineage as well as distributions

FeatureFreshnessOnlineOfflineMismatchRateFeatureNullRateFeatureComputationFailureRateLateFeatureUpdateRateFeatureVersionMismatchRate
Feature incident taxonomy
IncidentQuestion
AvailabilityIs the feature missing or stale?
SemanticDid definition or source meaning change?
ComputationDid the logic fail or diverge?
TemporalWas point-in-time correctness violated?
IdentityWas the feature attached to the wrong economic entity?

No universal thresholds apply. End-to-end freshness catches a healthy cache serving stale state; upstream semantic contracts catch pipelines that succeed technically while changing economic meaning.

The Entimema architecture makes time part of every feature value

CANONICAL EVENTS / STATEFEATURE REGISTRY + CONTRACTSFEATURE COMPUTATION LAYERFEATURE HISTORY STORE
OFFLINE PIT STORE
training / validation
ONLINE SERVING STORE
decision engine
DECISION MANIFEST / REPLAY
A governed definition and immutable history support both low-latency serving and point-in-time training, then converge through the decision manifest and replay chain.
ENTIMEMA FRAMEWORKDefine → Compute → Serve → Reconstruct → Validate
  1. Define feature semantics
  2. Define entity grain
  3. Define observation window
  4. Define time semantics
  5. Define version
  6. Compute
  7. Persist immutable history
  8. Serve online
  9. Retrieve point-in-time offline
  10. Compare and monitor

A Feature Integrity & Point-in-Time Agent can investigate discrepancies without changing production

A controlled agent can monitor definitions and versions, compare online and offline values, identify staleness and availability leakage, trace lineage, detect model/feature incompatibility and upstream semantic drift, compare incremental with full recomputation and find historical decisions affected by defects.

Continue with Point-in-Time Customer State Reconstruction, Handling Joint Borrowers and Connected Exposures, Building a Golden Customer Record, Event Time vs Processing Time vs Posting Time, Building a Reliable DPD Engine, Behavioural Credit Scoring and Early Warning Systems. Streaming behavioural features, real-time utilisation and silent-schema-change detection remain future research directions—not fabricated routes.