M54: harden operations and demo resilience
This commit is contained in:
+25
-11
@@ -32,13 +32,26 @@ updates the record and its evidence but leaves the issue open.
|
||||
|
||||
## DQ-03 Odometer regression
|
||||
|
||||
Flag an inspection or maintenance reading below the canonical odometer. Never lower the canonical value automatically.
|
||||
Flag a newly recorded checkout, return-inspection or maintenance reading below the
|
||||
canonical odometer. The deterministic import scan compares booking, inspection and
|
||||
maintenance readings in chronological order. A return inspection's actual completion
|
||||
time is authoritative over the booking's planned end, so an early return cannot be
|
||||
mistaken for a later regression. Never lower the canonical value automatically.
|
||||
|
||||
When another regression is recorded while the vehicle already has an open DQ-03 issue,
|
||||
append the new source reference and signal to that issue. Do not silently discard the
|
||||
new evidence and do not open parallel issues for the same vehicle.
|
||||
|
||||
Resolution: `POST /resolve-odometer-regression` offers exactly two bounded decisions —
|
||||
`retain_canonical` (the submitted reading is treated as erroneous; canonical is
|
||||
untouched) or `correct_reading` (updates a named related booking's reading and the
|
||||
vehicle's canonical odometer together). A `correct_reading` value below the current
|
||||
canonical is rejected, since it would not resolve the regression, not silently applied.
|
||||
untouched) or `correct_reading`. The correction option is offered only for an explicitly
|
||||
named, correctable booking reading; checkout-only and maintenance-only issues can only
|
||||
retain the canonical value. A corrected return updates the booking, its related return
|
||||
inspection and the vehicle's canonical odometer in one transaction. A
|
||||
`correct_reading` value below the current canonical is rejected, since it would not
|
||||
resolve the regression, not silently applied. When one open issue contains several
|
||||
source readings, correcting one removes only that booking/inspection evidence and keeps
|
||||
the issue open until every remaining signal has received a bounded decision.
|
||||
|
||||
## DQ-04 Booking overlap
|
||||
|
||||
@@ -63,10 +76,11 @@ function to confirm the conflict is actually gone before resolving.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
Detection is idempotent by `(rule_type, entity_type, entity_id)` while open — the CSV
|
||||
seed rows don't carry a stable evidence fingerprint, so the literal
|
||||
`(..., evidence fingerprint)` scheme from an earlier draft of this rule was dropped as
|
||||
unworkable for seeded data; re-implementing it would need to reconcile with that. Resolved
|
||||
issues remain historical. Reintroduced evidence creates a new issue whose evidence carries
|
||||
`reopened_from` (the prior issue's reference) and `previous_decision` (its resolved
|
||||
status), so a repeat problem is never presented as if no decision was ever made.
|
||||
Detection is idempotent by `(rule_type, entity_type, entity_id)` while open. Source-aware
|
||||
rules additionally store stable evidence identity. For DQ-03 this is the tuple
|
||||
`(source_type, later_ref, later_km)`: an explicit `retain_canonical` decision suppresses
|
||||
only that exact fact on later scans. A changed reading or a different source is actionable
|
||||
again. Resolved issues remain historical. Reintroduced evidence creates a new issue whose
|
||||
evidence carries `reopened_from` (the prior issue's reference) and `previous_decision`
|
||||
(its resolved status), so a repeat problem is never presented as if no decision was ever
|
||||
made.
|
||||
|
||||
Reference in New Issue
Block a user