You read a DATA QUALITY MONITORING PACK -- one run of a domain's declared quality rules, the records they were run over, the field catalogue, the upstream change log and the data steward's notes -- and return a TRIAGE: one finding for each rule a RULE ENGINE has already marked FAILED. You return JSON and nothing else.
THE RULE ENGINE HAS ALREADY RUN. Every declared rule was evaluated in pure code over the Record Extract before this prompt was assembled, and its verdict is given to you below as a fact. You do not re-check any rule, you do not disagree with a PASSED, and you do not re-count a failing population. That question is settled.
You are drafting requests for a qualified data owner. You never edit a record, never open a ticket, never quarantine a load, never suppress a rule and never write to any system. Your job is to say WHICH FIELD has to change, WHICH RECORDS show it, WHAT the pack says caused it, and WHAT TO ASK FOR -- and to NAME THE FAILURES THE PACK DOES NOT EXPLAIN.
RULES, in order of importance:
1. ONE OBJECT PER RULE THE ENGINE MARKED FAILED, AND NO OTHERS. Not one per failing record. Not one for a rule marked PASSED. If the engine marked four rules FAILED, return four findings.
2. `at_fault_field` IS THE FIELD THAT MUST CHANGE, WHICH IS OFTEN NOT THE FIELD THE RULE NAMES. Ask yourself what would have to be different for this failure not to happen. If the Upstream Change Log says the source began writing a value into a different column, the at-fault field is that column. If it says a re-key made a unique value repeat, the at-fault field is the field the re-key used. Only when nothing in the pack points elsewhere is the answer the rule's own subject field. Spell it exactly as the Field Catalogue spells it, and use the literal 'not_determined' when the pack does not settle it.
3. `at_fault_records` IS EXACTLY THE LIST THE ENGINE PRINTED FOR THAT RULE -- every identifier it listed, and no others. The Record Extract contains NEAR-MISS records that look like violations and are not; the engine did not flag them, so they are not evidence. Never return an identifier that is not in the Record Extract.
4. `cause` IS READ OFF THE PACK, NOT GUESSED. Work through the policy's definitions and take the one the pack actually evidences. 'genuine_data_error' is the answer when NOTHING ELSE explains the failure; it is the wrong answer whenever the change log, the reference data or the steward notes do explain it, and getting that backwards sends a data owner to correct values that the next load will break again.
5. A RULE CAN BE THE THING THAT IS WRONG. If the rule's bound contradicts what the Field Catalogue declares for the field, or the field it checks is no longer in the catalogue at all, the cause is 'rule_is_wrong' and the data is fine.
6. `remediation_action` IS DECIDED ONLY BY THE POLICY BELOW, from `cause` and `field_still_declared`. Work through the six steps IN ORDER and STOP at the first that fires. In particular a rule whose field was DROPPED is 'retire_rule' and never 'amend_rule' -- there is no bound left to amend.
7. `owner_route` IS A READING OF THE RULE'S OWN SECTION. If its Owner line reads 'not declared', the answer is 'no_owner_declared'. Do not name a plausible team; an unaddressed request is a real finding and hiding it is worse than reporting it.
8. 'not_determined' IS A REAL ANSWER AND YOU ARE EXPECTED TO USE IT. A triage that never reaches for it is guessing, and a cause asserted with no evidence sends somebody to look at data that is fine.
9. `remediation_note` IS ONE SENTENCE FOR A PERSON. It must name `at_fault_field` exactly as you spelled it and must quote at least one identifier from `at_fault_records`. Under 240 characters. No rule syntax, no promises.
10. Copy every identifier verbatim from the pack. Use the exact allowed value for every field that lists them, and return every field for every finding.
REMEDIATION POLICY (the authority for `remediation_action`; this is an ILLUSTRATIVE policy written for this kit, and it reproduces no data-governance framework, data-quality standard or company remediation procedure)
WHAT A FINDING IS
- One finding per DECLARED RULE THE ENGINE FAILED. Never one per failing record, and never one per rule that passed.
- A finding is a TRIAGE of a failure the rule engine already found in pure code. It does not decide whether the rule failed; that question was settled before the model was called and the engine's verdict is stated in the prompt.
- A finding names the FIELD THAT MUST CHANGE for the failure to stop, and the RECORDS that show it. A verdict with no field and no record is not a finding.
- A finding is a REMEDIATION REQUEST FOR A PERSON. It is never an edit, never a ticket, never a write of any kind.
THE CAUSE, read off the pack for every failed rule
genuine_data_error The records are simply wrong and nothing else in the pack explains them. No change log entry touches the field, the reference list is current, and the steward notes say nothing about it.
upstream_schema_change The Upstream Change Log records a change inside the run window that produced this failure -- a field renamed and the data now landing in a different column, a source that began classifying records differently, a re-key that made a supposedly unique value repeat.
stale_reference_data The rule checks values against a Reference Data list, the failing values are legitimate codes the change log records as ADDED to the source, and the list was last refreshed before that date. The data is right and the list is behind.
source_system_gap A named source system has stopped sending the field. The Steward Notes record it, and every failing record carries that source.
rule_is_wrong The failure is the rule's fault, not the data's. Either the rule's bound contradicts what the Field Catalogue declares for the field, or the field the rule checks no longer exists at all.
not_determined The pack does not settle it. Nothing in the change log, the reference data or the steward notes explains the failure, and the notes themselves record that the cause is unresolved. This is a real answer.
IS THE FIELD STILL DECLARED
yes The Field Catalogue in this pack still lists the field the rule checks.
no The Field Catalogue no longer lists it. The column was dropped upstream and the rule is checking something that is not there any more.
THE REMEDIATION CALL -- work through IN ORDER, stop at the first that fires
1. cause 'not_determined' -> 'investigate'. Nothing can be raised against a cause nobody has established.
2. cause 'rule_is_wrong' AND field_still_declared 'no' -> 'retire_rule'. The column is gone; there is nothing left to amend.
3. cause 'rule_is_wrong' AND field_still_declared 'yes' -> 'amend_rule'. The field is there and the rule's bound is wrong about it.
4. cause 'stale_reference_data' -> 'refresh_reference_data'. The data is right; the list is behind.
5. cause 'upstream_schema_change' OR 'source_system_gap' -> 'fix_upstream'. Correcting the records here would be undone by the next load.
6. anything else -> 'fix_records'.
WHO IT IS ADDRESSED TO
'declared_owner' when the rule's own section names an owning team.
'no_owner_declared' when it does not. A remediation request with no addressee is work nobody has been asked to do, and calling it 'the data team' does not make it addressed.
WHY `not_determined` IS A REAL ANSWER
A monitoring pack that never returns 'not determined' is not a confident monitor, it is a guessing one. A cause asserted with no evidence sends a real person to look at data that is fine, and the second time it happens they stop reading the alerts.
RULE ENGINE RESULT (pure code, already run over the Record Extract before this prompt was assembled -- NOT a question, and not yours to revisit)
DQ-R01 high FAILED unique(product_sku) -- 4 of 26 record(s): REC-0003, REC-0005, REC-0012, REC-0022
DQ-R02 high PASSED requires(order_channel=online, hazard_note) over 26 record(s)
DQ-R03 low PASSED matches(supplier_email, email_address) over 26 record(s)
DQ-R04 high FAILED range(margin_pct, 0, 60) -- 3 of 26 record(s): REC-0005, REC-0012, REC-0018
DQ-R05 low FAILED not_null(unit_of_measure) -- 3 of 26 record(s): REC-0003, REC-0016, REC-0024
DQ-R06 low FAILED not_null(record_status) -- 26 of 26 record(s): REC-0001, REC-0002, REC-0003, REC-0004, REC-0005, REC-0006, REC-0007, REC-0008, REC-0009, REC-0010, REC-0011, REC-0012, REC-0013, REC-0014, REC-0015, REC-0016, REC-0017, REC-0018, REC-0019, REC-0020, REC-0021, REC-0022, REC-0023, REC-0024, REC-0025, REC-0026
DQ-R07 medium FAILED not_null(country_code) -- 4 of 26 record(s): REC-0003, REC-0004, REC-0008, REC-0011
Return ONE finding for each rule marked FAILED above, and for no other rule.
Return these:
- run_id (string) -- the monitoring run reference from the Monitoring Run section, verbatim
- domain (string) -- the data domain the Monitoring Run section names, verbatim, including the qualifier before the dash
- reference_data_state (enum) one of: current, stale, not_stated -- what this pack says about the REFERENCE DATA it checks values against, read from the Reference Data section alone. That section restates the run window and gives each list a Last refreshed date. 'stale' when AT LEAST ONE list was last refreshed BEFORE the run window opened -- the source may have added codes since and the list would not know; 'current' when every list was refreshed on or after the window opened; 'not_stated' when the pack carries no Reference Data section at all. This is about the lists, never about the records
- findings (array of objects) -- one object per rule the RULE ENGINE RESULT marks FAILED, each carrying:
- rule_id (string) -- the identifier of the DECLARED RULE this finding is about, verbatim (for example DQ-R03). THIS IS THE KEY -- one object per rule the RULE ENGINE RESULT marks FAILED, and no others. Never one per failing record, and never one for a rule marked PASSED
- at_fault_field (string) -- the name of the ONE FIELD THAT MUST CHANGE for this failure to stop, exactly as the Field Catalogue spells it. ⚑ THIS IS OFTEN NOT THE FIELD THE RULE NAMES. A not_null rule on `delivery_email` whose records are empty because the source began classifying kiosk orders as `online` is at fault at `order_channel`; a unique rule on `customer_id` broken by a re-key is at fault at the field the re-key used. Use the literal value 'not_determined' -- and only that -- when the pack does not settle which field must change
- at_fault_records (array of string) -- the record identifiers that show this failure, verbatim (for example ["REC-0007", "REC-0019"]). EXACTLY the records the RULE ENGINE RESULT lists as failing for this rule -- no others, and none left out. A record the engine did not flag is not evidence of this failure, and an identifier that is not in the Record Extract at all is not evidence of anything
- severity (enum) one of: high, medium, low -- the severity this rule's own section declares, verbatim
- cause (enum) one of: genuine_data_error, upstream_schema_change, stale_reference_data, source_system_gap, rule_is_wrong, not_determined -- what the pack says produced this failure, decided from the Upstream Change Log, the Reference Data section, the Steward Notes, the Field Catalogue and the records themselves. Read the policy's definitions and take the FIRST one the pack actually evidences. 'genuine_data_error' means nothing else in the pack explains it -- it is the answer for a plain wrong value, and it is the wrong answer for a failure something in the pack does explain
- field_still_declared (enum) one of: yes, no -- does the Field Catalogue in THIS pack still list the field the rule checks? 'no' when the column was dropped upstream and the catalogue no longer carries it. This is a lookup in the Field Catalogue and nothing else
- evidence_source (enum) one of: record_extract, upstream_change_log, reference_data, field_catalogue, steward_notes, nothing_states_it -- WHICH SECTION OF THE PACK you read the cause from. 'record_extract' when the values themselves are the whole story; 'nothing_states_it' when no section explains the failure at all, which is the honest answer that goes with cause 'not_determined'
- remediation_action (enum) one of: fix_records, fix_upstream, refresh_reference_data, amend_rule, retire_rule, investigate -- the request this finding raises, decided STRICTLY by the shipped remediation policy from `cause` and `field_still_declared` and nothing else. Work through the six steps IN ORDER, stopping at the first that fires. (1) cause 'not_determined' -> 'investigate'. (2) cause 'rule_is_wrong' AND field_still_declared 'no' -> 'retire_rule'. (3) cause 'rule_is_wrong' AND field_still_declared 'yes' -> 'amend_rule'. (4) cause 'stale_reference_data' -> 'refresh_reference_data'. (5) cause 'upstream_schema_change' or 'source_system_gap' -> 'fix_upstream'. (6) anything else -> 'fix_records'
- owner_route (enum) one of: declared_owner, no_owner_declared -- 'declared_owner' when this rule's own section names an owning team; 'no_owner_declared' when its Owner line reads 'not declared'. A request with no addressee is work nobody has been asked to do, and naming a plausible team does not make it addressed
- remediation_note (string) -- ONE SENTENCE drafting the request for the data owner, in business terms, no more than 240 characters. It MUST name `at_fault_field` exactly as spelled, and it MUST quote at least one of the record identifiers in `at_fault_records`. Say what has to change and why; do not restate the rule syntax and do not promise anybody a fix
Return a JSON object with exactly these top-level keys: run_id, domain, reference_data_state, findings
`findings` is an array. Return it empty only if the RULE ENGINE RESULT above marks no rule FAILED.
MONITORING PACK
---------------
Synthetic Record
----------------
This is a SYNTHETIC data quality monitoring pack, generated for the AI Foundry `dq-rulecheck` kit.
No real company, retailer, person, product, supplier, store, system or dataset appears in it. Every
identifier, address, code and team name is invented, and every email domain is `.invalid`, which is
reserved and cannot resolve. The declared rules and the remediation policy shipped beside them are
this kit's own construction: they reproduce no data governance framework, no data quality standard,
no maturity model, no regulation and no organisation's own remediation procedure.
Monitoring Run
--------------
DQR-2026-0452
Domain: Retail — Product Master
Run window: 2026-07-01 to 2026-07-28
Run on: 2026-08-02
Records in scope: 26
Declared rules in this set: 7
Field Catalogue
---------------
product_sku string, the product key, unique per sellable unit
source_system string, the feed that supplied this record
listed_on date, ISO 8601, the date the product was first listed
country_code string, two-letter country of the listing
unit_of_measure string, the unit the product is sold in
supplier_email string, the supplier contact for this line
order_channel string, the channel the line is sold through
hazard_note string, free text, entered by the receiving team
margin_pct number, percent, 0 to 100
unit_of_measure_v2 string, the replacement column the source now populates
Upstream Change Log
-------------------
2026-07-03 STOCK-SYS changed the character encoding of the export from Latin-1 to UTF-8. Values that contained no accented characters are byte-identical.
2026-07-07 Column `record_status` was REMOVED from this domain's feed and from the Field Catalogue. Nothing populates it and nothing consumes it; the declared rule set was not updated.
2026-07-15 POS-EU renamed `unit_of_measure` to `unit_of_measure_v2`. The old column is still in the feed layout and is no longer populated; every value now lands in `unit_of_measure_v2`.
2026-07-17 PARTNER-FEED extended the retention window on archived records from 24 to 36 months. No column changed and no value changed.
Rule DQ-R01
-----------
Statement: product_sku must be unique across every record in scope.
Check: unique(product_sku)
Subject field: product_sku
Severity: high
Owner: Platform Data Engineering
Rule DQ-R02
-----------
Statement: Where order_channel is online, hazard_note must be populated.
Check: requires(order_channel=online, hazard_note)
Subject field: hazard_note
Severity: high
Owner: Data Governance Desk
Rule DQ-R03
-----------
Statement: supplier_email must be a well-formed email address.
Check: matches(supplier_email, email_address)
Subject field: supplier_email
Severity: low
Owner: not declared
Rule DQ-R04
-----------
Statement: margin_pct must be between 0 and 60 inclusive.
Check: range(margin_pct, 0, 60)
Subject field: margin_pct
Severity: high
Owner: Data Governance Desk
Rule DQ-R05
-----------
Statement: unit_of_measure must be populated on every record.
Check: not_null(unit_of_measure)
Subject field: unit_of_measure
Severity: low
Owner: Data Quality Control
Rule DQ-R06
-----------
Statement: record_status must be populated on every record.
Check: not_null(record_status)
Subject field: record_status
Severity: low
Owner: Source Systems Team
Rule DQ-R07
-----------
Statement: country_code must be populated on every record.
Check: not_null(country_code)
Subject field: country_code
Severity: medium
Owner: Platform Data Engineering
Record Extract
--------------
One line per record. A field with nothing after the `=` is empty in the source.
REC-0001 | product_sku=SKU-003227 | source_system=MDM-HUB | listed_on=2023-08-09 | country_code=GB | unit_of_measure=PK | supplier_email=mira.sorensen@inbox.invalid | order_channel=in_store | hazard_note=checked at goods-in | margin_pct=27 | unit_of_measure_v2=
REC-0002 | product_sku=SKU-003234 | source_system=CRM-CORE | listed_on=2019-01-11 | country_code=FR | unit_of_measure=LT | supplier_email=mateo.brandt@post.invalid | order_channel=online | hazard_note=signed off at the daily stand-up | margin_pct=44 | unit_of_measure_v2=
REC-0003 | product_sku=SKU-003255 | source_system=MDM-HUB | listed_on=2019-12-09 | country_code= | unit_of_measure= | supplier_email=finn.abadi@mailbox.invalid | order_channel=in_store | hazard_note=reviewed on the weekly call | margin_pct=50 | unit_of_measure_v2=EA
REC-0004 | product_sku=SKU-003248 | source_system=WEB-STORE | listed_on=2023-10-20 | country_code= | unit_of_measure=EA | supplier_email=ben.abadi@relay.invalid | order_channel=phone | hazard_note=confirmed by the duty manager | margin_pct=25 | unit_of_measure_v2=
REC-0005 | product_sku=SKU-003255 | source_system=MDM-HUB | listed_on=2020-03-01 | country_code=ES | unit_of_measure=KG | supplier_email=mira.haugen@inbox.invalid | order_channel=online | hazard_note=signed off at the daily stand-up | margin_pct=80 | unit_of_measure_v2=
REC-0006 | product_sku=SKU-003262 | source_system=PARTNER-FEED | listed_on=2021-02-17 | country_code=ES | unit_of_measure=KG | supplier_email=ines.ferreira@mailbox.invalid | order_channel=partner | hazard_note=no exception raised | margin_pct=41 | unit_of_measure_v2=
REC-0007 | product_sku=SKU-003269 | source_system=CRM-CORE | listed_on=2020-08-22 | country_code=DE | unit_of_measure=KG | supplier_email=noor.abadi@mailbox.invalid | order_channel=partner | hazard_note=no exception raised | margin_pct=4 | unit_of_measure_v2=
REC-0008 | product_sku=SKU-003276 | source_system=STOCK-SYS | listed_on=2020-05-07 | country_code= | unit_of_measure=KG | supplier_email=ava.delacroix@mailbox.invalid | order_channel=online | hazard_note=signed off at the daily stand-up | margin_pct=36 | unit_of_measure_v2=
REC-0009 | product_sku=SKU-003283 | source_system=STOCK-SYS | listed_on=2019-10-27 | country_code=GB | unit_of_measure=KG | supplier_email=liam.ferreira@inbox.invalid | order_channel=phone | hazard_note=reviewed on the weekly call | margin_pct=33 | unit_of_measure_v2=
REC-0010 | product_sku=SKU-003290 | source_system=MDM-HUB | listed_on=2020-06-19 | country_code=NL | unit_of_measure=PK | supplier_email=yara.osei@inbox.invalid | order_channel=online | hazard_note=checked at goods-in | margin_pct=9 | unit_of_measure_v2=
REC-0011 | product_sku=SKU-003297 | source_system=STOCK-SYS | listed_on=2022-11-09 | country_code= | unit_of_measure=EA | supplier_email=liam.quinn@relay.invalid | order_channel=partner | hazard_note=reviewed on the weekly call | margin_pct=50 | unit_of_measure_v2=
REC-0012 | product_sku=SKU-003304 | source_system=PARTNER-FEED | listed_on=2025-05-28 | country_code=ES | unit_of_measure=KG | supplier_email=ines.lindqvist@post.invalid | order_channel=in_store | hazard_note=checked at goods-in | margin_pct=91 | unit_of_measure_v2=
REC-0013 | product_sku=SKU-003311 | source_system=CRM-CORE | listed_on=2026-02-07 | country_code=FR | unit_of_measure=KG | supplier_email=noor.lindqvist@post.invalid | order_channel=in_store | hazard_note=no exception raised | margin_pct=29 | unit_of_measure_v2=
REC-0014 | product_sku=SKU-003318 | source_system=CRM-CORE | listed_on=2021-04-17 | country_code=not supplied | unit_of_measure=LT | supplier_email=mira.novak@relay.invalid | order_channel=phone | hazard_note=signed off at the daily stand-up | margin_pct=33 | unit_of_measure_v2=
REC-0015 | product_sku=SKU-003325 | source_system=MDM-HUB | listed_on=2026-03-12 | country_code=GB | unit_of_measure=LT | supplier_email=mateo.sorensen@inbox.invalid | order_channel=partner | hazard_note=checked at goods-in | margin_pct=28 | unit_of_measure_v2=
REC-0016 | product_sku=SKU-003332 | source_system=CRM-CORE | listed_on=2024-12-08 | country_code=NL | unit_of_measure= | supplier_email=noor.ferreira@relay.invalid | order_channel=partner | hazard_note=no exception raised | margin_pct=35 | unit_of_measure_v2=EA
REC-0017 | product_sku=SKU-003339 | source_system=POS-EU | listed_on=2022-09-23 | country_code=FR | unit_of_measure=KG | supplier_email=sofia.quinn@mailbox.invalid | order_channel=online | hazard_note=reviewed on the weekly call | margin_pct=27 | unit_of_measure_v2=
REC-0018 | product_sku=SKU-003346 | source_system=WEB-STORE | listed_on=2022-12-27 | country_code=GB | unit_of_measure=LT | supplier_email=elsa.novak@mailbox.invalid | order_channel=partner | hazard_note=signed off at the daily stand-up | margin_pct=96 | unit_of_measure_v2=
REC-0019 | product_sku=SKU-003353 | source_system=MDM-HUB | listed_on=2019-09-27 | country_code=DE | unit_of_measure=EA | supplier_email=noor.osei@relay.invalid | order_channel=partner | hazard_note=checked at goods-in | margin_pct=24 | unit_of_measure_v2=
REC-0020 | product_sku=SKU-003360 | source_system=STOCK-SYS | listed_on=2022-01-10 | country_code=ES | unit_of_measure=LT | supplier_email=omar.ferreira@post.invalid | order_channel=partner | hazard_note=checked at goods-in | margin_pct=20 | unit_of_measure_v2=
REC-0021 | product_sku=SKU-003367 | source_system=CRM-CORE | listed_on=2019-09-06 | country_code=GB | unit_of_measure=EA | supplier_email=arjun.abadi@post.invalid | order_channel=partner | hazard_note=reviewed on the weekly call | margin_pct=31 | unit_of_measure_v2=
REC-0022 | product_sku=SKU-003304 | source_system=MDM-HUB | listed_on=2024-03-08 | country_code=IT | unit_of_measure=EA | supplier_email=mateo.haugen@relay.invalid | order_channel=in_store | hazard_note=checked at goods-in | margin_pct=50 | unit_of_measure_v2=
REC-0023 | product_sku=SKU-003381 | source_system=MDM-HUB | listed_on=2023-05-28 | country_code=ES | unit_of_measure=LT | supplier_email=omar.osei@inbox.invalid | order_channel=in_store | hazard_note=signed off at the daily stand-up | margin_pct=11 | unit_of_measure_v2=
REC-0024 | product_sku=SKU-003388 | source_system=WEB-STORE | listed_on=2021-11-25 | country_code=IT | unit_of_measure= | supplier_email=arjun.hart@relay.invalid | order_channel=partner | hazard_note=reviewed on the weekly call | margin_pct=9 | unit_of_measure_v2=EA
REC-0025 | product_sku=SKU-003395 | source_system=STOCK-SYS | listed_on=2025-12-19 | country_code=ES | unit_of_measure=PK | supplier_email=sofia.brandt@post.invalid | order_channel=in_store | hazard_note=checked at goods-in | margin_pct=6 | unit_of_measure_v2=
REC-0026 | product_sku=SKU-003402 | source_system=STOCK-SYS | listed_on=2021-09-27 | country_code=FR | unit_of_measure=KG | supplier_email=noor.brandt@post.invalid | order_channel=online | hazard_note=no exception raised | margin_pct=38 | unit_of_measure_v2=
Steward Notes
-------------
PARTNER-FEED and MDM-HUB both return these records and each is configured as the master for this domain. Which of the two is correct has not been established, no change has been raised on either side, and nothing in the change log touches `product_sku`. The duplication is being carried while ownership is decided.
The declared bound on `margin_pct` in this rule set stops at 60. The Field Catalogue declares the column to 100 and the trading committee approved values above the rule's bound before this window opened. The records below are correct and the rule has not been updated.