- Source Registry (§10): rights/license/purpose metadata, provenance,
freshness SLA, health checks, describe/query; purpose gate FAILS CLOSED
(no rights record => deny); cross-tenant probes => NOT_FOUND.
- Search (§10/§42): OpenSearch REST adapter (no SDK) + SearchService with
MANDATORY tenant + purpose/rights filtering, versioned index definitions,
bulk, generation-per-rebuild (opt-{name}--g{n}) with atomic alias cutover,
rollback, failed-rebuild generation discard. OpenSearch never canonical.
- Quality (§10): versioned rule registry (GE-JSON interchange), local
engine for the GE core subset (never silently passes unsupported types),
runs/results/issues/score/trend, whole-run delegation to the GE backend
via N0D (0pt.quality.ge_run) - never fabricated results.
- Dataset (§10/§5/§53): immutable numbered versions holding canonical
st0re:artifact refs only, idempotent createVersion, export registers the
ST0RE artifact + AUD0 evidence + OpenLineage.
- Metadata (§10): OpenMetadata PUT /api/v1/tables projection adapter +
projectAll rebuild path; projection never canonical.
- Analytics (§10): ClickHouse HTTP adapter, closed metric-query DSL with
FORCED tenant predicate + readonly/max_execution_time/max_result_rows,
TTL retention. Zero connection to b0ts/quarantined pipelines.
- Features (§10): versioned feature-view registry, real Feast
get-online-features adapter, materialize/get-historical as N0D delegation.
- ER (§10): generic candidate API with deterministic blocking + transparent
scoring + per-field explanations, product hard-rule hook (force both
directions), review-band handoff, Splink batch via N0D contract.
93 new unit/contract tests; suite 248 passed / 1 skipped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
115 lines
3.7 KiB
TypeScript
115 lines
3.7 KiB
TypeScript
/**
|
|
* src/quality/quality-types.ts
|
|
* =============================
|
|
* Types for 0pt's Data Quality capability (Master-DoD §10 Data quality:
|
|
* rule registry, runs, results, issues, scores, trend, rule versioning,
|
|
* product-supplied rules).
|
|
*
|
|
* IMPORTANT HISTORY: this repo once carried FABRICATED claims that a
|
|
* quality-check service existed (see CLAUDE.md + docs/P0_DATASET_QUALITY_FLOW.md,
|
|
* which is the explicit target spec). THIS module is the first real
|
|
* implementation — anything it cannot do is stated, not implied.
|
|
*
|
|
* Expectations are serialized in Great Expectations' canonical JSON shape
|
|
* (`expectation_type` + `kwargs`) so a rule authored here can be executed
|
|
* verbatim by a GE backend (0pt-motor's Python engine, Master-DoD §11 DQ)
|
|
* AND by the local TypeScript engine for the supported core subset. The GE
|
|
* suite is the interchange format; the local engine is honest about which
|
|
* expectation types it supports (unsupported ⇒ must delegate, never fake).
|
|
*/
|
|
|
|
/** GE-compatible expectation (interchange shape). */
|
|
export interface QualityExpectation {
|
|
/** Great Expectations expectation type, e.g. "expect_column_values_to_not_be_null". */
|
|
expectation_type: string;
|
|
kwargs: Record<string, unknown>;
|
|
}
|
|
|
|
export type QualitySeverity = "info" | "warning" | "error" | "critical";
|
|
|
|
export interface DataQualityRule {
|
|
rule_id: string;
|
|
tenant_id: string;
|
|
project_id: string;
|
|
/** Dataset the rule targets; product-supplied rules set their own dataset ids. */
|
|
dataset_id: string;
|
|
name: string;
|
|
expectation: QualityExpectation;
|
|
severity: QualitySeverity;
|
|
/** Monotonic rule version — bumped on every mutation (§10 rule versioning). */
|
|
version: number;
|
|
status: "active" | "disabled" | "superseded";
|
|
/** Which product supplied the rule ("0pt" | "vehiq" | ...). */
|
|
supplied_by: string;
|
|
created_at: string;
|
|
updated_at?: string;
|
|
}
|
|
|
|
export interface CreateQualityRuleInput {
|
|
rule_id: string;
|
|
tenant_id: string;
|
|
project_id: string;
|
|
dataset_id: string;
|
|
name: string;
|
|
expectation: QualityExpectation;
|
|
severity?: QualitySeverity;
|
|
supplied_by?: string;
|
|
}
|
|
|
|
/** One executed expectation within a run. */
|
|
export interface DataQualityResult {
|
|
rule_id: string;
|
|
rule_version: number;
|
|
success: boolean;
|
|
/** Fraction of evaluated rows/elements that passed (1 for table-level checks that pass). */
|
|
pass_ratio: number;
|
|
evaluated_count: number;
|
|
unexpected_count: number;
|
|
/** Up to 20 sample unexpected values (never full rows — PII minimization). */
|
|
unexpected_samples: unknown[];
|
|
/** Engine that executed the expectation. */
|
|
executed_by: "0pt-local" | "great_expectations";
|
|
}
|
|
|
|
/** An issue opened for a failed rule (human-review handoff). */
|
|
export interface DataQualityIssue {
|
|
issue_id: string;
|
|
run_id: string;
|
|
rule_id: string;
|
|
rule_version: number;
|
|
tenant_id: string;
|
|
dataset_id: string;
|
|
severity: QualitySeverity;
|
|
status: "open" | "acknowledged" | "resolved" | "wont_fix";
|
|
summary: string;
|
|
created_at: string;
|
|
}
|
|
|
|
export type QualityRunStatus = "running" | "succeeded" | "failed" | "delegated";
|
|
|
|
export interface DataQualityRun {
|
|
run_id: string;
|
|
tenant_id: string;
|
|
project_id: string;
|
|
dataset_id: string;
|
|
/** Dataset version under test, when versioned. */
|
|
dataset_version?: number;
|
|
status: QualityRunStatus;
|
|
results: DataQualityResult[];
|
|
/** Overall score 0..100 (severity-weighted pass ratio). */
|
|
score?: number;
|
|
started_at: string;
|
|
finished_at?: string;
|
|
correlation_id?: string;
|
|
/** N0D job id when execution was delegated to the GE backend. */
|
|
delegated_job_id?: string;
|
|
}
|
|
|
|
/** One point of the §10 trend series. */
|
|
export interface QualityTrendPoint {
|
|
run_id: string;
|
|
dataset_id: string;
|
|
score: number;
|
|
finished_at: string;
|
|
}
|