Business

Detecting Rubber-Stamp Approvals in an Agent Decision Log

Antonio Evans8 min read

A clean technical scene shows a decision log table on the left and a scatter plot on the right, plotting request length against decision time.
Key points

Key points

  1. 1Rubber-stamp approvals are visible in a decision log as a signature pattern: decision latency that stays flat or falls as request length and complexity rise, plus reviewers approving almost everything inside a narrow, very short time window.
  2. 2Four log fields do most of the work: reviewer ID, request timestamp, decision timestamp, and request length; a simple complexity tag improves the signal but is not required to start.
  3. 3Approval rate and latency statistics must be computed per reviewer, not per team, because a team average hides the one reviewer who clicks yes on 98% of requests in under 15 seconds.
  4. 4The tests that separate genuine review from habitual clicking are distributional (latency quantiles, share of decisions under a floor, approve-rate extremes) and relational (correlation between latency and request length).

Why the log holds the answer

A confirmation dialog has one job: to make a person re-enter the moment of choice and confirm they meant it. As the microcopy literature on confirmation dialogues puts it, a confirmation box "loops the user back to the moment of choice and makes them take the same action, again," which is deliberate friction that serves the user's interest only if the user actually engages with it (UX Collective). When that friction collapses, the control still exists on paper but not in practice.

Agent systems make this problem more likely, not less. Human-in-the-loop (HITL) for AI agents is a runtime control pattern where an agent pauses before a sensitive action and a person approves or rejects it, and the agent resumes only if approved (Permit.io). The whole safety argument rests on the reviewer reading the request. If the reviewer is approving on reflex, the accountability the control was supposed to create evaporates.

The same sources name the failure directly. One survey of HITL design warns that "approval fatigue can make human oversight meaningless," and that the fix is context that makes the decision obvious in seconds plus reviewer identity and authorization checks (Promptessor). Another notes that approval design must avoid queues where reviewers batch low-risk items, because batching is where reflex clicking is born (StackAI). None of these guides, however, tells you how to measure whether it has actually happened. That is a logging question.

A decision log is the right instrument because it records what was decided, who decided it, and when, which is exactly what a structured record of decisions is for (Plane). The measurement problem is narrower than decision quality: it is whether the reviewer's behavior is consistent with having read the request.

The seven fields that matter

You cannot detect reflex approval after the fact without the right columns. Six of the seven below are cheap to add at request time, and the seventh (quality) is the one most teams skip and later regret.

FieldTypeWhy it mattersWhat breaks without it
reviewer_idstringGroups decisions per person; single-reviewer patterns disappear in team averagesCannot isolate a habitual clicker from a busy team
request_tstimestamp (UTC, millisecond)Start of the review windowLatency cannot be computed at all
decision_tstimestamp (UTC, millisecond)End of the review window; latency = decision_ts minus request_tsSame
request_lengthinteger (characters or tokens)The independent variable; reading time should scale with itA flat latency looks harmless
complexity_tagcategory (low, medium, high)Groups requests that demand different depths of thoughtLength alone conflates a long boilerplate with a hard edge case
request_qualityscore (0 to 1) plus a labelFlags whether the request was even reviewableA well-written request can be approved without thought; a badly written one defies review
decisionenum (approve, reject, modify, escalate)The outcome variableApprove rate is unmeasurable

Two design notes. First, store timestamps in UTC at millisecond resolution, because the discriminating signal for a habitual clicker is often a few seconds, and second-resolution clocks round away exactly the behavior you are hunting. Second, request_quality should come from a rubric, not a gut feeling: does the request state the action, the reason, the blast radius, and what was tried? The HITL design literature recommends giving reviewers an evidence pack so the decision is obvious in 10 to 30 seconds, which implies you can score whether the pack was present (StackAI).

If you are routing approvals through an inference layer, log the model call and the human decision as separate events with their own timestamps, so that model latency never contaminates reviewer latency.

Computing the four tests

The analysis divides into four tests. Run them in order; each one narrows the suspect set.

Test 1: the floor share. Define a reading floor, the minimum seconds a competent review of a given complexity could take, set with your own reviewers rather than borrowed from a benchmark. Then compute, per reviewer, the share of decisions made under that floor. A reviewer at 40% or more under the floor is a candidate for reflex clicking, not a proven one; human review genuinely is fast for routine items, so treat the floor as a starting hypothesis to calibrate against your own data, which is the same discipline the HITL guidance applies to confidence thresholds (Galileo).

Test 2: the latency distribution. Per reviewer, compute the median, the 10th percentile (P10), and the interquartile range of latency. The tell is a distribution squeezed against zero: a P10 of 3 seconds with a median of 9 seconds means this reviewer is not reading much of anything. A healthy reviewer shows a wide spread because genuinely complex requests slow them down.

Test 3: latency versus request length. Correlate latency with request length per reviewer. A reviewer who reads should show a positive relationship: longer requests, longer decisions. A correlation near zero or negative, on a sample with real length variation, is the strongest single signal of rubber-stamping.

Test 4: approve-rate extremes. Compute each reviewer's approve share and compare it to the team's. A reviewer approving 95% or more when the team hovers near 70% is either exceptionally well-served by good requests or not rejecting anything.

A minimal implementation in Python is enough to run all four on a CSV export:

import pandas as pd

df = pd.read_csv("decision_log.csv", parse_dates=["request_ts", "decision_ts"])
df["latency_s"] = (df["decision_ts"] - df["request_ts"]).dt.total_seconds()

FLOOR_S = {"low": 10, "medium": 30, "high": 60}  # calibrate to your team
df["under_floor"] = df.apply(
    lambda r: r["latency_s"] < FLOOR_S.get(r["complexity_tag"], 30), axis=1
)

by_reviewer = df.groupby("reviewer_id").agg(
    n=("decision", "size"),
    approve_rate=("decision", lambda s: (s == "approve").mean()),
    median_latency=("latency_s", "median"),
    p10_latency=("latency_s", lambda s: s.quantile(0.10)),
    under_floor_share=("under_floor", "mean"),
)

length_corr = df.groupby("reviewer_id").apply(
    lambda g: g["latency_s"].corr(g["request_length"])
    if g["request_length"].nunique() > 5 else float("nan")
)
print(by_reviewer.join(length_corr.rename("len_corr")))

Sample size matters. Below roughly 30 decisions per reviewer, correlation estimates are too noisy to accuse anyone; report the numbers as "watch," not "flag." And the whole pipeline depends on a validated measurement system: measurement systems analysis exists precisely because gauges and operators introduce error and bias into the data a decision rests on (Majeske, International Review of Business and Economics). Your timestamps are a gauge. Calibrate them before you trust them.

A worked example

Consider four reviewers on a change-approval queue, 120 to 400 decisions each over a quarter. The table below is synthetic but built to the pattern the tests described above are designed to surface.

ReviewerDecisionsApprove rateMedian latencyP10 latencyShare under floorLatency vs length r
A3400.7152 s14 s0.08+0.61
B2900.948 s3 s0.82+0.04
C1200.6844 s11 s0.12+0.47
D1800.8811 s4 s0.76-0.09

Reviewer A looks like a reader: a median of 52 seconds, only 8% of decisions under the floor, and a strong positive relationship between latency and length. The wide gap between median and P10 shows that hard requests do slow A down.

Reviewer B is the classic pattern. A 94% approve rate, a median of 8 seconds, and 82% of decisions under the floor on requests that include a complexity tag. The near-zero correlation with length is the clincher: B is not reading more when asked to review a 40-page change than when asked to review a one-paragraph one. The pattern matches the description of approval fatigue making oversight meaningless.

Reviewer D is a subtler case. The negative correlation means D decides faster on longer requests, which is the opposite of reading behavior and hints at a different problem: skim the first line, approve, move on, with longer requests actually going quicker because the decision was made before scrolling. This is the case that a team average would hide entirely.

The insight a first search result will not give you is the decision rule. Rank reviewers by under-floor share first (it is the most interpretable), then confirm with the length correlation, then check approve-rate extremes against the team. A reviewer who trips only one test is a watch item. A reviewer who trips under-floor share and near-zero correlation together is a review-routing problem.

The request-quality trap

Here is the counterintuitive part. A request that reads well can still be approved without thought, and a beautifully written request is more likely to trigger the reflex, because the reviewer's summary instinct is satisfied in the first two lines. The measurement literature on reviewer judgment is blunt about this: building quality into a review practice is not just about improving what is submitted, it is about the quality measures of the review itself, including timeliness and the assessment of the assessment (IntechOpen).

That is why request_quality belongs in the log as a control variable, not as a headline metric. The practical rule is to slice the under-floor share by request-quality band:

  • If under-floor share is high in the well-written band but low in the poorly written band, the reviewers are trusting quality as a proxy for safety. That is reasonable for low complexity and dangerous for high.
  • If under-floor share is high in both bands, you have a reflex problem independent of request quality.
  • If under-floor share is high only in the poorly written band, you have a request-generation problem upstream, not a reviewer problem. The agent is producing unreadable requests.

This distinction saves you from the most common misdiagnosis: firing a training initiative at reviewers when the real fix is that the agent is emitting 4,000-word requests with the decision buried in paragraph six.

From detection to design

Detection without design is just blame. Once you have a suspect list, three interventions change the numbers.

Instrument the gate, don't just log it. Build the pause as a real workflow state with a persistent record, so the reviewer sees the proposed action, its evidence, and its reversibility before deciding. The permit-and-approve loop pattern is exactly this: the agent proposes, the human reviews context, the agent resumes only on approval (Permit.io). A structured approval record that survives the session is also the audit trail that answers who approved what and why, which is what audit requirements actually ask for (Permit.io).

Make the decision obvious, not just available. Provide an evidence pack that lets the reviewer reach a confident answer in 10 to 30 seconds (StackAI). Paradoxically, speeding up legitimate review is how you make latency a valid discriminator: once a good review takes 20 seconds, a 3-second decision becomes unmistakably a click.

Change the queue, not the person. If a reviewer handles 400 decisions a day, reflex clicking is a capacity symptom. Route by risk so that high-blast-radius items reach a reviewer with room to think, and batch low-risk items into a single sampled screen (StackAI). The escalation-matrix literature has the vocabulary for this: functional escalation routes a case to the person with the right expertise, hierarchical escalation routes it to the person with authority, and automatic escalation moves it on rule-based triggers (Dialpad). An approval queue is a routing problem before it is a discipline problem.

One more field pays for itself here: record whether the reviewer saw the full request or a condensed view. If condensed views correlate with under-floor decisions, the UI, not the reviewer, is the cause.

If your queue runs on mixed models and you need the agent calls logged alongside the human decisions, one API key for text, image, audio, and embedding models keeps the trace in one place, which is what Quanta Inference provides.

FAQ

FAQ

How do I tell the difference between a fast reviewer and a rubber-stamp reviewer?

Fast and careless look identical on the median. Separate them with two statistics: the share of decisions under a calibrated reading floor, and the correlation between latency and request length. A genuinely fast reviewer still slows down on complex, long requests; a rubber-stamper does not, which is why a near-zero or negative correlation is the stronger signal, as in the worked example above (Galileo).

What is a reasonable reading floor to use?

There is no universal number; set it from your own data. Have a small group of trusted reviewers decide a sample of requests while you time them, take the 10th percentile of those times by complexity band, and use that as the floor. Starting from a borrowed benchmark violates the same principle the HITL guidance applies to confidence thresholds: calibrate empirically against your production data rather than adopting generic industry figures (Galileo).

How many decisions per reviewer do I need before I can flag someone?

Roughly 30 per reviewer is the minimum where distributional tests mean anything, and 100 or more is where correlation estimates stabilize. Below that, report the reviewer as a watch item rather than a finding. The measurement analogy is useful here: a gauge study exists because operator and instrument error distort the reading, and small samples are one such source of distortion (Majeske).

Can good request formatting cause rubber-stamping?

Yes, and it is a common trap. When requests are consistent and well-summarized, reviewers can infer the whole decision from the first two lines and approve on that basis, which is efficient but skips verification of the parts that matter. Track request quality as a control variable and check whether under-floor decisions concentrate in the well-written band; if they do, the problem is that quality has become a substitute for scrutiny (IntechOpen).

What should I change first if I find rubber-stamping?

Change the evidence pack and the queue before you change the people. Give reviewers the proposed action, the reason, the blast radius, and a rollback path in one screen so a confident decision takes 10 to 30 seconds, and route high-risk items to reviewers with capacity (StackAI). If the numbers still show reflex clicking after that, the volume is the problem, and the answer is risk-based escalation rather than more training (Dialpad).

Sources

Sources

  1. Are you sure you want to do this? Microcopy for ...
  2. Human in the Loop AI Agents: Approval Workflows That Work
  3. Human-in-the-Loop AI Agents: Approval Workflows & Best Practices
  4. Human-in-the-Loop AI Agents: How to Design Approval Workflows for Safe ...
  5. Decision log: What it is, why teams use it, and template
  6. How to Build Human-in-the-Loop Oversight for AI Agents
  7. Using Measurement System Potential Approval Criteria
  8. Building Quality into the Regulatory Review Practice for ...
  9. Escalation Management: Process, Matrix & Best Practices
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