Fleet Data Quality Hub — reconciliation & certification
You are auditing one collection of raw records that arrives as several
overlapping source snapshots and must produce a single JSON object that
reconciles them, computes integrity metrics, and states a release decision.
Every task in this family follows the same shape; only the domain differs.
0. Read the three contracts first, then act
prompt.txt — narrative; tells you the domain and any special counting rules.
payloads/case_scope.json — the machine-readable scope: collection id,
business cutoff, focus items, ranking limits, status thresholds / gates,
status→action map, and the lists of ids whose control codes you must return.
payloads/answer_template.json — the binding output schema. Treat it as
law: required keys, additionalProperties:false, enum sets, array
min/max/uniqueItems, patterns, and every description (they encode
ordering, rounding, and inclusion rules). Build your answer to validate
against it exactly.
Runtime access (base URL, auth header, the list of readable endpoints) is in the
task's environment_access.md — read it; do not assume paths or
credentials. The hub is read-only. There is no feedback endpoint at test
time: solve in one shot from the data. Do not look for, expect, or call any
grading/judge service while solving.
1. The hub data model
Access is an authenticated read-only SQL query interface over logical views
(plus per-family GET endpoints and a catalog/schema endpoint). Confirm the exact
view/field names from the catalog schema endpoint before querying. The
views you will typically see:
v_source_snapshots — one row per (collection, snapshot): snapshot_id,
source_system, snapshot_status (CERTIFIED / PROVISIONAL / STALE),
business_cutoff, created_at, row_count.
- One raw-record view per family:
v_contacts, v_fuel_transactions,
v_freight_charges, v_maintenance_events. Each row carries collection_id,
snapshot_id, source_system, a business key, the domain fields, a
record_status, and business_updated_at.
- Reference views:
v_reference_aliases (domain, alias_text→canonical_value,
validity window, reference_status), v_unit_conversions (kind, from_unit,
to_unit, factor, precision), v_fx_rates (rate_date, currency,
usd_per_unit, rate_status).
The query interface returns {columns, rows, truncated}. Pull whole scoped
tables into memory and reconcile in code (Python). Always check truncated; if
set, page by ordered key ranges. scripts/hub_toolkit.py wraps all of this
(reads environment_access.md, runs queries, and provides the normalizers,
dedup, alias/unit/fx resolvers described below).
2. Universal reconciliation pipeline
Every task is a variation of these steps:
- Pick the authoritative snapshot. Among the collection's snapshots within
the business cutoff, the CERTIFIED one is authoritative. Report its
snapshot_id (and status/row_count) wherever the contract asks.
- Scope the raw rows. All rows across the in-scope snapshots within the
cutoff / business period.
raw_row_count counts these raw rows (duplicates
included).
- Reduce raw rows to logical entities by the business key
(transaction/charge/event id) or by identity resolution (contacts). A key in
1 snapshot is a cross-snapshot duplicate; keep the authoritative
(CERTIFIED) occurrence's values as the retained record.
duplicate_raw_count = raw_row_count − logical_count.
- Classify each logical entity (valid / mismatch / quarantine) per the
family rules below.
- Normalize measures and money for the valid set (units → canonical via
v_unit_conversions; amount → USD via v_fx_rates).
- Aggregate: counts, per-category/per-region totals, focus rollups,
rankings.
- Assign control codes for the scoped ids (see §5).
- Decide certification from the thresholds/gates in
case_scope.
- Emit one JSON object; nothing else.
3. Family playbooks
Full detail (with the confirmed edge cases and traps) is in
references/reconciliation_playbook.md. Summary:
Contacts (partner onboarding, dealer/field-service rosters)
- Merge key = normalized email only. Normalize: NFKC → strip → lowercase;
treat placeholder tokens (
"", n/a, none, null, unknown, -) as
missing. Do not merge on phone, name, or master_hint — shared
"helpdesk" phone numbers are shared across many people, and
master_hint values like SHARED-HELPDESK / NOISY-* are traps that must
not cause a merge. Same-name/different-email rows are different people.
- Field-level precedence (different fields can come from different sources):
canonical_name: from the CERTIFIED "portal/HR-directory" source
(typically snapshot …-s01), title-cased to a proper display name that
preserves Unicode/accents. Report that source as name_source_system.
email, phone, city, region/depot, consent, and the master/survivor
row: from the CERTIFIED source that carries master_hint (typically
…-s03, e.g. "Compliance Master" / "Identity Registry").
canonical_phone_digits = national digits only (strip formatting; do
not prepend a country code).
- The PROVISIONAL source (CRM / Dispatch) often has deliberately wrong city
values — never source location from it.
- Quarantine = a row with no usable email and no usable phone.
canonical_entity_count includes quarantined people. quarantine_rate
as defined by the contract (usually quarantined_rows ÷ canonical_entities,
rounded to the stated dp).
- Readiness: an entity is eligible if ACTIVE and it has a usable email or
phone; a channel is ready only if consent is GRANTED. Partition eligible
entities into both / email_only / phone_only / not_ready.
dispatchable =
ACTIVE + usable channel + GRANTED consent. Depot partitions
(dispatchable / blocked_consent / blocked_no_contact / blocked_inactive) must
sum to the depot total.
resolution_outcome: multi-source cluster → FIELD_LEVEL_PRECEDENCE_APPLIED;
single row → SINGLE_SOURCE; contested (shared-helpdesk/identifier collision)
→ CONTESTED_NO_AUTOMERGE; no usable contact → NO_USABLE_CONTACT.
Transactional (fuel purchases, freight charges)
- Dedup logical txn/charge by its id across snapshots (keep CERTIFIED).
- Category resolution from the description via
v_reference_aliases in the
matching domain: consider only aliases whose reference_status = ACTIVE and
whose validity window covers the row's business date. Match alias_text
as a whole word/phrase; when a longer matched phrase contains a shorter
one, the longest match wins (e.g. "premium unleaded" beats "unleaded").
0 canonical values → unrecognized; ≥2 distinct → ambiguous; exactly 1
→ recognized. Watch for near-miss traps (e.g. a word that merely contains
an alias substring, or a not-yet-effective / retired alias).
- Quarantine = unrecognized OR ambiguous class OR non-positive measure
(quantity/weight/distance ≤ 0). Valid = recognized class AND positive
measures. Mismatch = valid AND recognized class ≠ expected class.
Exception = mismatch OR quarantine (disjoint sets).
- Normalized totals over the VALID set only: convert measure via
v_unit_conversions.factor; convert amount via v_fx_rates using the
CERTIFIED usd_per_unit for the row's currency on its business date —
apply the rate to every currency, including USD (do not shortcut USD to
1.0). Sum exact values, then round to the contract's dp. Group by the
recognized class.
- Rankings: order by the specified exposure/exception measure desc, id asc,
limited to the stated count.
Maintenance events
- Population = union of snapshots, deduped by
event_id, retained =
CERTIFIED (using certified-only under-counts and fails). Report the
certified snapshot as authoritative; authoritative_row_count = its row
count; scoped_raw_row_count = raw rows in scope.
- Per logical event integrity flags: missing timestamp (null/empty),
invalid timestamp (unparseable, e.g. impossible month/day), invalid odometer
(negative), negative labor (<0), extreme labor (gross outliers), odometer
regression.
invalid_event_ids = events failing time/odometer/labor validity
(not regressions). valid_event_count = logical − invalid.
- Odometer regression / distance: per asset, order the valid events
chronologically, convert odometer to km; a reading below the running max is a
regression.
total_distance_km = Σ over assets of (last − first reliable
reading), rounded as specified. Regressions are reported in
corrected_metrics, not in invalid_event_ids.
duplicate_groups: each key present in >1 snapshot; snapshot_ids sorted;
retained = certified.
- Certification obeys the gate in
case_scope (e.g. any odometer
regression → HOLD / BLOCK_AND_REMEDIATE).
4. Certification / close decision
Apply the thresholds, gates, and status_action_map from case_scope
literally. When thresholds are given (e.g. a max quarantine rate), compare the
computed metric and map status→action through the provided map. When only a gate
is given, the gate condition forces the failing status.
5. Opaque control codes
Contracts ask for short coded values (e.g. identity / outreach /
field-provenance codes for contacts; reference-policy / source-basis /
ledger-disposition codes for transactions; maintenance-source / history-route
codes for events). Their plain-text meanings are intentionally withheld; the
allowed value set is the enum in the answer template.
Do not guess blindly. Each code family maps one enum value per underlying
condition, and the scoped ids are chosen to span those conditions:
- Identity codes ↔ the entity's
resolution_outcome
(precedence-applied / single-source / contested / no-contact).
- Outreach codes ↔ the readiness bucket (both / email_only / phone_only /
not_ready). The contract's readiness_partition object is the key: whatever
code you place on each bucket there must match the code you give elsewhere for
an entity in that bucket.
- Field-provenance codes ↔ how many/which sources supplied the surviving
fields (single-source vs multi-source precedence).
- Source-basis / retention codes ↔ snapshot provenance of the retained
record (certified-only / provisional-only / present-in-both).
- Ledger-disposition / history-route codes ↔ the entity's disposition
(clean / mismatch / unrecognized / ambiguous / invalid-measure, or
valid / invalid / regression).
- Reference-policy codes ↔ the alias's state at the cutoff
(active-usable / not-effective (future or retired/inactive) / provisional).
Method: enumerate the distinct conditions present among the scoped ids, map each
condition to exactly one allowed enum value consistently across the whole
answer (the same condition always gets the same code), and keep the mapping
internally consistent with the readiness_partition / decision panels that pin
it. Codes are the least determinable part of these tasks; get everything else
exact first.
6. Output discipline (where easy points are lost)
- Emit one JSON object, no prose/markdown.
- Honor every
required key and additionalProperties:false; add nothing extra.
- Sort exactly as each
description/x-ordering_rules says (lexicographic
id lists; ranked arrays by their sort keys). Dedup where uniqueItems.
- Round to the stated decimal places; respect
multipleOf.
- Use only values from the allowed
enums and only stable ids that exist in the
data or the case scope.
- Re-validate your object against
answer_template.json before finishing
(scripts/hub_toolkit.py has a validate() helper).
7. Traps checklist
- Placeholder strings (
n/a/none/null/empty) are missing, not values.
- Shared phone numbers and
SHARED-HELPDESK/NOISY-* hints must not merge
identities; same name ≠ same person.
- Alias matching is whole-word + longest-wins; a not-yet-effective or
retired/inactive alias is not usable even if its text appears.
- FX applies to all currencies (including USD); measures need unit
conversion before summing.
- Quarantined rows are excluded from normalized totals but valid class
mismatches are included.
- Contacts: name from the s01 source (title-cased), everything else from the
master-hint (s03) source; phone is national digits.
- Maintenance: reconcile the union (not certified-only); regressions are
reported separately from rejected/invalid events.
1---2name: fleet-data-quality-reconciliation-23description: Solve "Asteria Fleet Data Quality Hub" reconciliation, cleanup, and certification tasks. Use when a task gives a prompt plus payloads/case_scope.json and payloads/answer_template.json and asks you to reconcile overlapping source snapshots for a collection (contacts / fuel / freight / maintenance) as of a business cutoff and emit one JSON object matching the answer contract (quality counts, duplicate/quarantine sets, normalized totals, focus rollups, rankings, opaque control codes, and a certification/close decision). Runtime connection details come from the task's own environment_access.md.4---56# Fleet Data Quality Hub — reconciliation & certification78You are auditing one **collection** of raw records that arrives as several9overlapping **source snapshots** and must produce a single JSON object that10reconciles them, computes integrity metrics, and states a release decision.11Every task in this family follows the same shape; only the domain differs.1213## 0. Read the three contracts first, then act14151. `prompt.txt` — narrative; tells you the domain and any special counting rules.162. `payloads/case_scope.json` — the machine-readable scope: collection id,17 business cutoff, focus items, ranking limits, status thresholds / gates,18 status→action map, and the lists of ids whose control codes you must return.193. `payloads/answer_template.json` — the **binding output schema**. Treat it as20 law: required keys, `additionalProperties:false`, enum sets, array21 `min/max/uniqueItems`, patterns, and every `description` (they encode22 ordering, rounding, and inclusion rules). Build your answer to validate23 against it exactly.2425Runtime access (base URL, auth header, the list of readable endpoints) is in the26task's **`environment_access.md`** — read it; do not assume paths or27credentials. The hub is **read-only**. There is **no feedback endpoint at test28time**: solve in one shot from the data. Do not look for, expect, or call any29grading/judge service while solving.3031## 1. The hub data model3233Access is an authenticated **read-only SQL query interface over logical views**34(plus per-family GET endpoints and a catalog/schema endpoint). Confirm the exact35view/field names from the catalog **schema** endpoint before querying. The36views you will typically see:3738- `v_source_snapshots` — one row per (collection, snapshot): `snapshot_id`,39 `source_system`, `snapshot_status` (CERTIFIED / PROVISIONAL / STALE),40 `business_cutoff`, `created_at`, `row_count`.41- One raw-record view per family: `v_contacts`, `v_fuel_transactions`,42 `v_freight_charges`, `v_maintenance_events`. Each row carries `collection_id`,43 `snapshot_id`, `source_system`, a business key, the domain fields, a44 `record_status`, and `business_updated_at`.45- Reference views: `v_reference_aliases` (domain, alias_text→canonical_value,46 validity window, reference_status), `v_unit_conversions` (kind, from_unit,47 to_unit, factor, precision), `v_fx_rates` (rate_date, currency,48 usd_per_unit, rate_status).4950The query interface returns `{columns, rows, truncated}`. Pull whole scoped51tables into memory and reconcile in code (Python). Always check `truncated`; if52set, page by ordered key ranges. `scripts/hub_toolkit.py` wraps all of this53(reads `environment_access.md`, runs queries, and provides the normalizers,54dedup, alias/unit/fx resolvers described below).5556## 2. Universal reconciliation pipeline5758Every task is a variation of these steps:59601. **Pick the authoritative snapshot.** Among the collection's snapshots within61 the business cutoff, the **CERTIFIED** one is authoritative. Report its62 `snapshot_id` (and status/row_count) wherever the contract asks.632. **Scope the raw rows.** All rows across the in-scope snapshots within the64 cutoff / business period. `raw_row_count` counts these raw rows (duplicates65 included).663. **Reduce raw rows to logical entities** by the business key67 (transaction/charge/event id) or by identity resolution (contacts). A key in68 >1 snapshot is a **cross-snapshot duplicate**; keep the **authoritative69 (CERTIFIED)** occurrence's values as the retained record.70 `duplicate_raw_count = raw_row_count − logical_count`.714. **Classify each logical entity** (valid / mismatch / quarantine) per the72 family rules below.735. **Normalize** measures and money for the valid set (units → canonical via74 `v_unit_conversions`; amount → USD via `v_fx_rates`).756. **Aggregate**: counts, per-category/per-region totals, focus rollups,76 rankings.777. **Assign control codes** for the scoped ids (see §5).788. **Decide certification** from the thresholds/gates in `case_scope`.799. **Emit** one JSON object; nothing else.8081## 3. Family playbooks8283Full detail (with the confirmed edge cases and traps) is in84`references/reconciliation_playbook.md`. Summary:8586### Contacts (partner onboarding, dealer/field-service rosters)87- **Merge key = normalized email only.** Normalize: NFKC → strip → lowercase;88 treat placeholder tokens (`""`, `n/a`, `none`, `null`, `unknown`, `-`) as89 missing. **Do not merge on phone, name, or `master_hint`** — shared90 "helpdesk" phone numbers are shared across many people, and91 `master_hint` values like `SHARED-HELPDESK` / `NOISY-*` are traps that must92 **not** cause a merge. Same-name/different-email rows are different people.93- **Field-level precedence** (different fields can come from different sources):94 - `canonical_name`: from the CERTIFIED "portal/HR-directory" source95 (typically snapshot `…-s01`), **title-cased** to a proper display name that96 preserves Unicode/accents. Report that source as `name_source_system`.97 - `email`, `phone`, `city`, `region/depot`, `consent`, and the master/survivor98 row: from the CERTIFIED source that carries `master_hint` (typically99 `…-s03`, e.g. "Compliance Master" / "Identity Registry").100 - `canonical_phone_digits` = **national digits only** (strip formatting; do101 **not** prepend a country code).102 - The PROVISIONAL source (CRM / Dispatch) often has deliberately wrong city103 values — never source location from it.104- **Quarantine** = a row with **no usable email and no usable phone**.105- `canonical_entity_count` **includes** quarantined people. `quarantine_rate`106 as defined by the contract (usually quarantined_rows ÷ canonical_entities,107 rounded to the stated dp).108- **Readiness**: an entity is *eligible* if ACTIVE and it has a usable email or109 phone; a channel is *ready* only if consent is GRANTED. Partition eligible110 entities into both / email_only / phone_only / not_ready. `dispatchable` =111 ACTIVE + usable channel + GRANTED consent. Depot partitions112 (dispatchable / blocked_consent / blocked_no_contact / blocked_inactive) must113 sum to the depot total.114- `resolution_outcome`: multi-source cluster → FIELD_LEVEL_PRECEDENCE_APPLIED;115 single row → SINGLE_SOURCE; contested (shared-helpdesk/identifier collision)116 → CONTESTED_NO_AUTOMERGE; no usable contact → NO_USABLE_CONTACT.117118### Transactional (fuel purchases, freight charges)119- Dedup logical txn/charge by its id across snapshots (keep CERTIFIED).120- **Category resolution** from the description via `v_reference_aliases` in the121 matching domain: consider only aliases whose `reference_status = ACTIVE` **and**122 whose validity window covers the row's **business date**. Match `alias_text`123 as a **whole word/phrase**; when a longer matched phrase contains a shorter124 one, the **longest match wins** (e.g. "premium unleaded" beats "unleaded").125 0 canonical values → **unrecognized**; ≥2 distinct → **ambiguous**; exactly 1126 → **recognized**. Watch for near-miss traps (e.g. a word that merely contains127 an alias substring, or a not-yet-effective / retired alias).128- **Quarantine** = unrecognized OR ambiguous class OR non-positive measure129 (quantity/weight/distance ≤ 0). **Valid** = recognized class AND positive130 measures. **Mismatch** = valid AND recognized class ≠ expected class.131 **Exception** = mismatch OR quarantine (disjoint sets).132- **Normalized totals over the VALID set only**: convert measure via133 `v_unit_conversions.factor`; convert amount via `v_fx_rates` using the134 **CERTIFIED** `usd_per_unit` for the row's currency **on its business date** —135 **apply the rate to every currency, including USD** (do not shortcut USD to136 1.0). Sum exact values, then round to the contract's dp. Group by the137 **recognized** class.138- Rankings: order by the specified exposure/exception measure desc, id asc,139 limited to the stated count.140141### Maintenance events142- Population = **union of snapshots, deduped by `event_id`, retained =143 CERTIFIED** (using certified-only under-counts and fails). Report the144 certified snapshot as authoritative; `authoritative_row_count` = its row145 count; `scoped_raw_row_count` = raw rows in scope.146- **Per logical event** integrity flags: missing timestamp (null/empty),147 invalid timestamp (unparseable, e.g. impossible month/day), invalid odometer148 (negative), negative labor (<0), extreme labor (gross outliers), odometer149 regression. `invalid_event_ids` = events failing time/odometer/labor validity150 (**not** regressions). `valid_event_count = logical − invalid`.151- **Odometer regression / distance**: per asset, order the valid events152 chronologically, convert odometer to km; a reading below the running max is a153 regression. `total_distance_km` = Σ over assets of (last − first reliable154 reading), rounded as specified. Regressions are reported in155 `corrected_metrics`, not in `invalid_event_ids`.156- `duplicate_groups`: each key present in >1 snapshot; `snapshot_ids` sorted;157 retained = certified.158- Certification obeys the **gate** in `case_scope` (e.g. any odometer159 regression → HOLD / BLOCK_AND_REMEDIATE).160161## 4. Certification / close decision162163Apply the thresholds, gates, and `status_action_map` from `case_scope`164literally. When thresholds are given (e.g. a max quarantine rate), compare the165computed metric and map status→action through the provided map. When only a gate166is given, the gate condition forces the failing status.167168## 5. Opaque control codes169170Contracts ask for short coded values (e.g. identity / outreach /171field-provenance codes for contacts; reference-policy / source-basis /172ledger-disposition codes for transactions; maintenance-source / history-route173codes for events). Their plain-text meanings are intentionally withheld; the174**allowed value set is the `enum` in the answer template**.175176Do **not** guess blindly. Each code family maps **one enum value per underlying177condition**, and the scoped ids are chosen to span those conditions:178179- **Identity** codes ↔ the entity's `resolution_outcome`180 (precedence-applied / single-source / contested / no-contact).181- **Outreach** codes ↔ the readiness bucket (both / email_only / phone_only /182 not_ready). The contract's readiness_partition object *is* the key: whatever183 code you place on each bucket there must match the code you give elsewhere for184 an entity in that bucket.185- **Field-provenance** codes ↔ how many/which sources supplied the surviving186 fields (single-source vs multi-source precedence).187- **Source-basis / retention** codes ↔ snapshot provenance of the retained188 record (certified-only / provisional-only / present-in-both).189- **Ledger-disposition / history-route** codes ↔ the entity's disposition190 (clean / mismatch / unrecognized / ambiguous / invalid-measure, or191 valid / invalid / regression).192- **Reference-policy** codes ↔ the alias's state at the cutoff193 (active-usable / not-effective (future or retired/inactive) / provisional).194195Method: enumerate the distinct conditions present among the scoped ids, map each196condition to exactly one allowed enum value **consistently** across the whole197answer (the same condition always gets the same code), and keep the mapping198internally consistent with the readiness_partition / decision panels that pin199it. Codes are the least determinable part of these tasks; get everything else200exact first.201202## 6. Output discipline (where easy points are lost)203204- Emit **one JSON object, no prose/markdown**.205- Honor every `required` key and `additionalProperties:false`; add nothing extra.206- **Sort** exactly as each `description`/`x-ordering_rules` says (lexicographic207 id lists; ranked arrays by their sort keys). Dedup where `uniqueItems`.208- **Round** to the stated decimal places; respect `multipleOf`.209- Use only values from the allowed `enum`s and only stable ids that exist in the210 data or the case scope.211- Re-validate your object against `answer_template.json` before finishing212 (`scripts/hub_toolkit.py` has a `validate()` helper).213214## 7. Traps checklist215216- Placeholder strings (`n/a`/`none`/`null`/empty) are **missing**, not values.217- Shared phone numbers and `SHARED-HELPDESK`/`NOISY-*` hints must **not** merge218 identities; same name ≠ same person.219- Alias matching is whole-word + longest-wins; a not-yet-effective or220 retired/inactive alias is **not** usable even if its text appears.221- FX applies to **all** currencies (including USD); measures need unit222 conversion before summing.223- Quarantined rows are excluded from normalized totals but valid class224 **mismatches are included**.225- Contacts: name from the s01 source (title-cased), everything else from the226 master-hint (s03) source; phone is national digits.227- Maintenance: reconcile the **union** (not certified-only); regressions are228 reported separately from rejected/invalid events.