Security

Which Repairs Need a Human: A Policy for Meaning Changes

Antonio Evans8 min read

A split scene: on the left, a conveyor of small data records passes a mechanical gate labeled with a simple checkmark, moving straight through; on the right, records with altered labels (a changed unit symbol.
Key points

Key points

  1. 1A repair can be automated only when it does not change what the record asserts; anything that changes the record's meaning needs a human decision.
  2. 2Mechanical fixes (whitespace, encoding, formatting, reversible conversion with a stated source unit) can run unattended; unit changes without a source unit, date shifts across boundaries, and enum swaps cannot.
  3. 3Approval queues fail when reviewers get a value without the evidence behind it, so the queue must carry the original, the proposal, the rule applied, and the downstream blast radius.
  4. 4Every approval decision should be logged as structured data, because that log is what lets a repair class graduate to automatic acceptance later.

The core distinction: syntax versus meaning in data repairs

A repair pipeline exists because incoming records are wrong in small, repetitive ways: stray whitespace, mojibake from a bad encoding, a date written as 03/04/2025, a weight in pounds where the schema says kilograms. The temptation is to write one normalizer and let it run on everything. That works until the normalizer silently changes what a record claims.

The cleanest way to see the line is the distinction between syntactic and semantic validation. Syntactic validation checks structure and format; semantic validation checks whether the value is valid in the context of the system's business rules the SKA telescope semantic validation guide. A repair that only touches syntax can be automatic. A repair that touches semantics needs a decision about intent, and intent is exactly what an automated rule cannot supply.

This matters more than it sounds, because the failure mode is quiet. A pipeline that writes 1.2 where the source said 1,200 still produces valid JSON, still passes a schema, and still loads into the warehouse. As one production write-up puts it, valid JSON is not a contract; shape is not truth, and a schema-valid amount, date, or ID can still violate domain rules TrueFoundry's guide to structured outputs. The same logic applies to repairs: a repair that passes validation has only proven it is well-formed, not that it is correct.

The decision rule

Write the rule as a single gate with four pass conditions. A repair may be auto-accepted only if all four hold:

  1. The change is reversible without information loss.
  2. The information needed to reverse it is present in the same record.
  3. The change does not touch any field consumed by a downstream calculation.
  4. The change cannot alter which entity, time, or category the record refers to.

If any condition fails, the repair goes to the approval queue. In practice that yields a short auto-accept list and a longer review list, which is the correct shape: automation should be the narrow path and review the wide one, not the reverse.

Repair typeExampleChanges meaning?Route
Whitespace and case normalization" ACME Corp " to "ACME Corp"NoAutomatic
Encoding repair"Müller" to "Müller"No, if reversible and loggedAutomatic
Format normalization with no loss"03/04/2025" to "2025-04-03" where the source locale is statedNoAutomatic
Unit conversion with source unit in the record120 lb with unit: lb to 54.43 kgNoAutomatic
Unit conversion without a source unit120 with no unit field, schema expects kgYesApproval queue
Date shift across a timezone or calendar boundaryLocal midnight to UTC, or a non-Gregorian calendar to GregorianYesApproval queue
Enum swap between values with different semantics"closed" to "resolved", or "pending" to "in_progress"YesApproval queue
Any repair to a field feeding a downstream calculationQuantity, unit price, tax rate, durationYesApproval queue

The table is the whole policy in one screen, and it is worth pinning next to the pipeline code so that adding a new repair rule forces an explicit choice about which column it belongs in.

Three worked examples

Unit change with a stated source unit. A supplier feed sends {"weight": 120, "unit": "lb"} and the warehouse schema stores kilograms. The repair multiplies by 0.45359237 and writes 54.43, retaining the original and its unit in an audit column. Nothing about the claim changed; only its representation did. This is the textbook case for reversible conversion, and unit-conversion literature shows why the source unit must travel with the number: conversion errors in scientific computing are a recognized class of defect precisely because values are interpreted in the wrong unit system Chizeck et al. on error detection and unit conversion. Auto-accept, log the conversion factor, done.

Unit change without a stated source unit. Same feed, but now the payload is {"weight": 120} and a legacy note in the vendor contract says pounds. The pipeline converts. Then the vendor changes its export, and 120 was kilograms all along. The record now asserts 54.43 kg instead of 120 kg, a 2.2x error, and nothing in the record flagged the assumption. This one belongs in the queue, with the reviewer shown the inferred unit, the evidence for it, and the age of that evidence. If the evidence is a contract clause with a date, the reviewer can see whether it still applies.

Enum swap. A ticketing system migrates statuses. The mapping table says "done" becomes "closed", and someone adds "done" becomes "resolved" because the two sound similar. They are not the same: one usually ends the workflow, the other usually keeps it visible for a follow-up window. Swapping them changes what the record asserts about the case's lifecycle, and any SLA report or backlog count computed from status will shift. A reviewer who sees the old value, the new value, the mapping rule's rationale, and the list of downstream reports that filter on status can make this call in seconds. An automated rule cannot.

Why machines cannot resolve these alone

The reason to insist on human review for meaning-changing repairs is that the information needed is often absent from the record itself. Vocabulary drifts: teams repurpose a status column for payment failures or fraud alerts, and the technical container stays the same while its semantic payload moves ThoughtWorks on semantic drift. The same term can mean different things in two pipelines, and the divergence is invisible to standard accuracy and data-quality metrics Dataiku on semantic drift.

Agents make this sharper because they produce plausible, well-formed output while their behavior drifts away from intent without throwing errors Trussed on semantic drift in agents. A repair agent that proposes a unit conversion has produced a technically valid suggestion. Whether it is contextually correct is a separate question, and that gap between "technically authorized" and "contextually authorized" is where approval gates earn their keep Scalekit on human-in-the-loop tool calling.

The research on command gating offers the most useful warning here. In a study of 1,709 real-world command denylists, 69.0 percent to 98.6 percent were fragile, because the same goal can be reached by many different commands that the list did not anticipate Characterizing Denylist Fragility in AI Agents. Repair rules have the same property: you can enumerate the repairs you know about, but not the ones an agent will invent. That is an argument for routing by class of change, not for trying to enumerate every bad case.

Designing the approval queue so review is a real check

Most approval queues die from volume and missing context. A documented failure: a claims-intake agent routed every decision to human approval, the queue backed up within weeks, reviewers cleared items in seconds, and a misclassified claim was paid out with a human signature attached ReadyForRole on human-in-the-loop design. The fix is not more reviewers. It is routing by risk and giving each reviewer enough evidence to decide quickly.

The same problem has a measured version on the agent side: approval fatigue leads users to approve about 93 percent of command execution requests, which collapses the queue into an allowlist Characterizing Denylist Fragility in AI Agents. If your reviewers approve nearly everything, the gate is decorative.

Design the queue item so the decision takes ten to thirty seconds. A workable schema:

{
  "repair_id": "rp_01HX",
  "record_id": "sku_88213",
  "field": "shipping_weight_kg",
  "original": {"value": 120, "unit": null},
  "proposed": {"value": 120.0, "unit": "kg"},
  "repair_class": "unit_conversion_without_source",
  "rule_id": "units.infer_from_vendor_contract.v3",
  "evidence": [
    {"type": "contract_clause", "ref": "MSA-2021 s.7", "asserted_unit": "lb"},
    {"type": "conflict", "ref": "sku_88214", "asserted_unit": "kg"}
  ],
  "downstream": [
    {"consumer": "freight_cost_model", "impact": "high", "sensitivity": "linear"}
  ],
  "blast_radius": {"rows": 412, "distinct_suppliers": 3},
  "reviewer_role": "logistics_data_owner",
  "sla_minutes": 60
}

Three fields do the heavy lifting. evidence shows why the pipeline proposed what it did, including conflicts. downstream tells the reviewer what breaks if they are wrong. blast_radius tells them whether this is one row or four hundred. Without those three, the reviewer is asked to re-do the investigation, which is why queues that omit them get rubber-stamped.

Two queue mechanics are easy to miss. First, batch by rule, not by row: if one inference rule is wrong, the reviewer should see all 412 affected rows in one item with a single approve or reject. Second, treat every decision as training data. Capture the reviewer's reason code, and after a class of repair accumulates consistent approvals, promote it to automatic acceptance with a sampling rate for quality assurance. That is the progressive autonomy ladder, and it is the only way the queue shrinks over time ReadyForRole.

Implementation: gating the repair before it commits

The pipeline shape is a classifier in front of every repair, with the auto path and the queue path sharing the same audit log.

MEANING_FIELDS = {"quantity", "unit_price", "tax_rate", "duration_s", "amount"}

def route(repair, record):
    if repair.field in MEANING_FIELDS:
        return "queue"
    if repair.class_ in {"unit_change", "date_shift", "enum_swap"}:
        if repair.class_ == "unit_change" and record.get("unit"):
            return "auto"          # reversible, source unit present
        return "queue"
    if repair.class_ in {"whitespace", "case", "encoding", "format"}:
        return "auto"
    return "queue"                 # unknown class defaults to review

Note the default. Anything the classifier does not recognize goes to review, because the cost of a wrong auto-repair is silent corruption and the cost of an unnecessary review is a few seconds of a reviewer's time. That asymmetry is the whole justification for the policy.

Two engineering details make the gate trustworthy. Idempotency: a repair proposal should carry a deterministic key derived from the record and the rule, so a retried repair cannot be applied twice or produce a second queue item Trussed on tool call idempotency. And structured error handling: when the repair service rejects a proposal for a schema mismatch, the proposal should be regenerated with the error in context rather than retried unchanged, because blind retries replay full context and multiply cost tianpan.co on retry budgets.

If you are building the repair agent itself, structured outputs enforce the proposal shape so the gate always receives a complete object: original, proposed, rule, evidence Agenta's guide to structured outputs. Without that, the gate spends its time repairing the repairs, which is exactly the failure pattern practitioners call tool argument rot Lanham on JSON schema.

What to log, and how to shrink the queue

Log every proposal, every route decision, every approval and rejection, and the reason code. That log answers the regulator question "who approved this automated change and why," which is the same evidence requirement that applies to agent actions generally Dataiku on human-in-the-loop governance. It also gives you the two numbers that matter: the auto-accept rate by repair class and the rejection rate by class.

A rejection rate near zero for a class over a few hundred items is the signal to promote it to automatic acceptance with sampling. A rejection rate above a few percent is the signal to fix the rule or widen the queue. Reviewing those two numbers monthly is a far better use of a data owner's time than clearing individual items.

If the queue is growing because you have many repair classes and no one to own the policy, that is a good moment for a short working session rather than more tooling. A free 30-minute AI discovery call can map your repair classes to routes and identify which ones are ready to automate: Quanta Consulting. And if the repair agent spans text extraction, embedding-based deduplication, and image or scanned documents, running them through one API key removes a layer of glue code from the pipeline: Quanta Inference.

FAQ

FAQ

What is the single question that decides whether a repair can be automatic?

Ask whether the repair changes what the record asserts about the world. If the record still claims the same quantity, the same moment in time, and the same category, it is mechanical and can be automated. If any of those three shifts, a human decides.

Why is a unit conversion sometimes automatic and sometimes not?

It is automatic only when the source unit is stated in the same record, which makes the conversion reversible and verifiable. Without a stated unit, the pipeline is guessing, and a guess about units can be wrong by an order of magnitude while still producing a schema-valid number.

How do I handle date repairs that cross a timezone boundary?

Route them to review. A timestamp of local midnight is a different instant in UTC, and the correct mapping depends on the source's timezone, which is often missing from the record. Show the reviewer both representations, the assumed zone, and any consumers that compare timestamps across sources.

How many items can one reviewer handle per day without rubber-stamping?

An item designed around an evidence pack takes seconds to judge; an item without evidence takes minutes to investigate, and reviewers under volume pressure will skip the investigation. Track the median decision time by class, and treat a sudden drop as a sign the queue has become a formality rather than a control.

When should a repair class move from the queue to automatic acceptance?

When it has accumulated a meaningful number of reviewed items with a rejection rate near zero, and the promotion includes a sampling rate so a share of automatic repairs is still checked. Record the promotion date and the reviewer who signed off, so the decision is auditable and reversible.

Sources

Sources

  1. Semantic Validation, developer.skatelescope.org 1.13.0 ...
  2. LLM Structured Outputs with JSON Schema
  3. Error Detection and Unit Conversion - PMC - NIH
  4. Semantic drift and semantic integrity
  5. Semantic drift in AI: how to detect, measure, and prevent it
  6. Semantic Drift Detection in AI Agents: A Technical Guide
  7. Human-in-the-Loop Tool Calling: Approval Gates for AI ...
  8. Characterizing Denylist Fragility in AI Agents
  9. Human-in-the-Loop Design: Escalation and Approval Patterns ...
  10. Tool Call Idempotency for AI Agents: A Technical Guide
  11. Retry Budgets for LLM Agents: Why 20% Per-Step Failure ...
  12. The guide to structured outputs and function calling with ...
  13. Stop Blaming the LLM: JSON Schema Is the Cheapest Fix ...
  14. Human-in-the-loop AI agents: design patterns for governance
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles