The question that has an answer
Do not try to decide whether a document is malicious. You cannot do it reliably, and every hour spent there is an hour not spent on the question that is answerable:Which parts of this trajectory came from somewhere we do not control, and does the action about to happen require that they had not?Provenance is a fact about your architecture, not a judgement about content. You know whether a document arrived from a customer upload or from your own curated store.
Marking it
Retrieval and tool steps carry atrusted flag, and it defaults to false.
The default matters: an integration that forgets to think about provenance
records the safe answer rather than the convenient one.
Taint propagates forward
If step 0 read an unverified document, step 4 is downstream of unverified content whether or not it looks like it. Once that is tracked, a policy becomes expressible without detecting anything:This agent may summarise a document containing untrusted content. It may not initiate a payment in the same trajectory.A grant sets that requirement in
conditions. When the action arrives, gate 5
checks it and returns gated if the trajectory is not clean.
Not every action needs a clean context
Treating all taint as fatal is the mistake in the other direction. Reading a customer’s email in order to answer it is the job, and refusing on those grounds is refusing to work. The requirement belongs on the action, not on the agent. Summarising is fine. Moving money, changing configuration, disclosing data, closing a case without review: those are where the question deserves an answer before rather than after.Discharging taint
Where a sanitisation step genuinely removes the risk, record it:What the record says
Three fields, and the third is the one teams forget:- which content was untrusted, by source, not a boolean on the trajectory
- where it entered, by step index
- whether the decision downstream of it was allowed to stand

