An agent changes a function. Veridu finds the caller it missed.
One real run of the verify loop, start to finish: the change, Veridu's result, the fix, and the follow-up. The code is a small PHP example written for this page; both results are Veridu's actual output, quoted as returned on 30 October 2026.
The task: "Let discounts be passed as a percentage (10 for 10%) instead of a fraction, and update the promo-code caller." The agent changed the method and the promo-code caller in another class:
--- a/src/Checkout.php
+++ b/src/Checkout.php
if ($code === 'SPRING10') {
- $this->invoice->applyDiscount(0.10);
+ $this->invoice->applyDiscount(10);
}
--- a/src/Invoice.php
+++ b/src/Invoice.php
- /** Apply a discount as a fraction of the subtotal, e.g. 0.1 for 10%. */
- public function applyDiscount(float $rate): void
+ /** Apply a discount as a percentage of the subtotal, e.g. 10 for 10%. */
+ public function applyDiscount(float $percent): void
{
- if ($rate < 0 || $rate > 1) {
- throw new \InvalidArgumentException('Discount rate must be between 0 and 1.');
+ if ($percent < 0 || $percent > 100) {
+ throw new \InvalidArgumentException('Discount must be between 0 and 100 percent.');
}
- $this->discount = $rate;
+ $this->discount = $percent / 100;
}It did not touch a second caller in the same class, which still passes a fraction:
public function applyLoyaltyDiscount(int $years): void
{
// 2% per year as a customer, up to 10%.
$this->applyDiscount(min($years * 0.02, 0.10));
}Nothing fails: the old value 0.10 is still inside the new 0 to 100 range. A loyal customer just gets 0.1% off instead of 10%.
The agent sent the diff and the full content of both files with verify_change. Because the change altered a method signature, Veridu also looked for calls to it within the files sent.
The unchanged loyalty-discount caller still passes fractional discount values to applyDiscount, but applyDiscount now treats its argument as a percentage and divides by 100, making loyalty discounts 100x smaller than before.
The validation window widened from 0..1 to 0..100, so every previously valid fractional argument (e.g. 0.10) remains accepted but now means 0.10%. Any caller not updated in this change fails silently instead of throwing, making the migration error-prone.
The high finding is the missed caller. It blocked because both reviewers found it independently.
public function applyLoyaltyDiscount(int $years): void
{
// 2% per year as a customer, up to 10%.
- $this->applyDiscount(min($years * 0.02, 0.10));
+ $this->applyDiscount(min($years * 2, 10));
}The agent checked the fixed change. Veridu linked it to the first check and reported:
- Loyalty discount caller still passes fractional rates (high) — the flagged line changed
- Silent semantic change: old fractional inputs still validate (medium) — the flagged line did not change
The accepted domain widened from [0,1] to [0,100], so any caller still passing the old fractional form (e.g. 0.10) now passes validation and silently applies a 100x smaller discount instead of failing loudly. The deterministic search found only the two in-repo call sites, both updated, so this only bites external/serialized callers or named-argument callers (`$rate` was renamed to `$percent`).
"No longer reported" is not proof of a fix, which is why the follow-up says whether the flagged line changed. The low finding is a judgment call for the person committing: both callers in this code are updated, but anything outside it that still passes 0.10 would not fail loudly. Keeping the old name for a fraction, or rejecting values below 1, are both reasonable answers.
It shows the loop: an independent check before the commit, findings the agent can act on, and a follow-up that says what changed. It is one small example, not a measure of how often Veridu finds problems. Veridu saw only the two files the agent sent; for PHP it traces callers and overrides within them. How Veridu looks for callers.