A field note from the AIdeazz AI Lab — a real incident on a live production system, written up from the logs. October 15, 2026.
A job-screening judge learns from the reasons its owner gives when she rejects a role. Its strongest lesson about her, pay below her floor, was eight times "her" reason, and seven of those eight were a staging script's instructions for filling in a form.
What it looked like from outside
A read-only audit of how the operation's agents share knowledge opened the screening judge's live lesson file, the summary it reads on every job it evaluates. The lesson list is built from the reasons the operator writes on CRM deals she rejects. Its pay lesson read "Pay below her floor — 8x", and the quoted examples were not opinions. They were the opening of a note that starts "The form pre-fills 'Your rate: $1/hour'. Change it before Next." That note is written by a separate staging script that prepares contract-platform applications for her. The judge had been carrying it as one of her most frequent reasons for saying no.
What was actually happening
The learner reads every note on a rejected deal and labels it as her reason, except notes that match a list of known agent templates. The list had grown by hand as agent note types were noticed: the document-kit notes on 29 September and a browser-prompt note on 1 October. The staging script that writes the form instructions had been writing since 23 September, from a different repository, and was never added to the list, so its note was trusted as hers. Its text repeats on every deal it stages, so the mislabel did not add noise: it produced one of the most frequent lessons in the file. A second half kept it there: the derived reasons are cached per deal, and a deal is only re-read when it changes, so even a corrected exclusion would not have touched the seven entries already learned.
The fix
Two changes inside the existing learner, no new component. The staging script's note type joins the existing list of agent templates. And a cached reason that now matches that list is derived again from the deal's notes on the next run, so the seven borrowed reasons are recomputed instead of kept. The judge itself, the lesson format and the operator's own notes were not touched.
How I know it worked
From the learner's own output on its next scheduled run after deploy. Its ledger line went from "389 rejections, 54 with her reason, refreshed 0" to "389 rejections, 47 with her reason, refreshed 7". The staging note's phrase occurred 7 times in the decisions file and 6 times in the lesson file before the run, and 0 and 0 after it. The pay lesson now reads "Pay below her floor — 1x", and its one example is her own sentence that the salary was too low. The deployed learner is byte-identical to the committed version on the laptop. The rest of the same audit was handled the same way: one change per proven gap, each double-checked by two independent reviewers before deploy, and two candidates held back because the review found that turning them on would have created a new problem.
The rule this earned
A learner that reads human feedback from a shared record must know who wrote each line. Every time a new agent starts writing where the learner reads, register that agent's note type in the same change, and re-derive the labels already cached from it. Check by reading the learner's top lessons with their quotes, not by counting lessons: a lesson whose quotes are instructions rather than opinions was borrowed from a machine.
The named concepts behind it
Naming a failure mode is what makes it possible to recognise the same shape somewhere new, before it costs another weekend.
Label provenance
A learner that reads "the human's reasons" from a shared record must know who wrote each line — otherwise another agent's text becomes the human's preference.
A feedback learner needs labels: the human's verdict and the reason behind it. In a real operation those reasons rarely live in a clean dataset. They live in the same place everything else lives — a CRM note, a ticket comment, a chat thread — and other software writes there too: a staging script, a document generator, an assistant leaving instructions for the human.
Label provenance is the property that every line the learner reads carries who wrote it. When it is missing, the learner does what any reader does with an unsigned note: it assumes the most likely author. On a record that a person decided on, that author is the person. So an agent's instruction ("change the rate field before you submit") is filed as the person's reason ("the pay was too low"), counted, summarised, and served back to a model as one of her strongest preferences.
Ordinary-life version: a manager learns what a client dislikes by reading the margin notes on the proposals the client rejected. The assistant who prepared the proposals also writes in those margins — reminders like "fix the price on page 2". After a month the manager is convinced the client always rejects on price. The client never said a word about price.
The usual shapes:
- The blocklist that fails open. The learner skips notes that match known agent templates. Every agent added later is trusted by default until someone remembers to register its template.
- The cache that keeps the wrong label. The exclusion is fixed, but the reasons already derived from the agent's note stay in the learner's memory, because the record itself never changed and nothing triggers a re-read.
- The lesson that looks strongest. Agent text is repetitive by nature (a template on every record), so a mislabelled note does not add noise — it adds the most frequent lesson, and frequency is exactly what a summariser ranks by.
It is a cousin of [[the-prompt-is-a-source]] — text you did not mean as evidence becomes evidence — and of [[advisory-feedback]]: both are about whether a feedback loop is learning what you think it is learning. Check it with [[verify-from-logs]]: read the learner's actual top lessons and the exact quotes behind them, not the count of lessons.
The defences. Mark authorship at write time where you can (a distinct note type or a stable marker in the visible text). Where you cannot, keep one registry of agent note types next to the learner, and add to it in the same change that introduces a new agent writer. When an exclusion is added, re-derive the cached labels it affects. And read the top lessons with their quotes after every new writer ships: a lesson whose quotes are instructions rather than opinions is borrowed.
Advisory feedback
Feedback that is recorded, summarised and shown to a model — but wired where it cannot change a decision — is logging, not learning.
A self-improving system needs three parts, and it is easy to build two. A sensor that captures the human's verdict and the reason for it. A memory that keeps those verdicts. And a switch — the point in the pipeline where the decision is actually made — that the memory is allowed to move.
Advisory feedback is the failure where the first two exist, work, and are proven end to end, while the third is missing. The verdicts are read, stored, summarised and even injected into a model's prompt, so every inspection of the loop comes back green: the file updates, the prompt contains the lessons, the logs show the sync running. And the outcome does not change, because the component that receives the lessons is not the component that decides.
The usual shapes:
- The lesson reaches the wrong box. The feedback is fed to a reviewer that sits on a side path, while the main path into the outcome runs on fixed rules that never read it.
- The lesson is told it cannot win. It arrives as "calibration" that must not override the base criteria — so a reason as crisp as a hard eligibility rule becomes a hint that loses every time it conflicts.
- The memory is a window, not a record. "The most recent N" feels like memory. With rising volume the window shrinks until the system remembers a week of a person's judgement and forgets the rest.
It is a cousin of [[silent-failure]] — nothing errors — and of [[verify-from-logs]]: the tell is that you can show the lesson arriving but not the decision it changed.
The defences. Trace from the outcome backwards, not from the sensor forwards: for the thing the human keeps rejecting, find the exact line that let it through, and check whether the lesson can reach that line. Turn crisp lessons into enforced rules with provenance, and leave only fuzzy judgement to the model. And prove it by replay — run the new logic over the human's past decisions and report two numbers: rejections it now catches, and approvals it now wrongly blocks, which must stay at zero. Re-run the replay after every prompt change, because prompt pieces interact ([[the-prompt-is-a-source]]): two harmless additions can combine into a new failure.
Verify from logs, not config
Configuration tells you what somebody intended. Logs tell you what happened.
A setting, an environment variable or a present API key is a statement of intent. It is evidence that somebody meant for a behaviour to occur. It is not evidence that the behaviour occurs.
The gap between the two is where the longest outages live, because reading the configuration feels like verification. It produces confident, wrong statements: the key is set, so the provider works; the schedule says every fifteen minutes, so it runs every fifteen minutes; the file was deployed, so the new code is running.
Each of those has a cheap, decisive check that costs seconds:
- Probe the dependency, do not read its credential. A key that exists proves nothing about the balance behind it.
- Grep for the action line, not the setup line. A startup banner proves the process started, not that it ever did its work.
- Compare timestamps after a deploy. If the running process is older than the file on disk, it is still executing the previous version from memory.
The rule this earns: never report a system's behaviour from its configuration. Grep the line that proves the behaviour happened, and quote it.
---
This note is one entry in a running wiki of production engineering lessons — every concept linked to the incident that taught it — at aideazz.xyz/ai-ops-wiki.html.
No customer data, credentials, hostnames or internal record identifiers appear in these write-ups.