§6.4's mitigations all address one direction: a site misleading an agent (input-length limits, shared attack evals, untrustedContentHint). §6.3.2 Current Gaps ends with "no verification mechanism … no behavioral contracts … agents must assume good faith from site developers."
The reverse direction has no listed mitigation: an agent, misled or simply over-eager, exceeding the scope a person delegated on a site that exposed write tools. That is the direction prompt injection actually exploits: the injected instruction lives in the site's content, and the damage lands on the site's own data.
Proposal
Name, in §6.4, a mitigation that does not depend on the model resisting injection. The page enforces, in the tool implementations:
- (a) a person-owned write scope. Writes outside it are refused with a structured error naming the allowed targets.
- (b) optimistic concurrency against the person's own edits. Writes over changes the agent has not read are refused with a diff.
- (c) page-owned cancellation for long-running writes, so a stop reports what landed.
The point is that none of these ask the model to behave. They are ordinary preconditions in the tool body, and they hold whatever the agent believes.
Measured
scripts/guardrail-eval.mts hands a model the same tool contracts the page registers and dispatches to the same implementations, with the guards on and off. Scale, stated plainly: one task, one site, two models, ten runs per arm.
| arm |
wrote over an unread hand edit |
task completed |
| gpt-4.1 · guards ON |
0/10 |
10/10 |
| gpt-4.1 · guards OFF |
10/10 |
10/10 |
| gpt-5.4 · guards ON |
0/9 |
9/9 |
| gpt-5.4 · guards OFF |
8/8 |
8/8 |
gpt-5.4 lost 3 of 20 runs to network errors, which were excluded; hence 9 and 8.
Two honest notes on the injection scenario. First, on gpt-4.1 the model followed the injected instruction in 0/10 runs with the guards on and 0/10 with them off, so it did not distinguish the arms, so that run says nothing about the guards. That is why a second, model-free arm exists: a scripted agent that follows the injection by construction rewrote 8 of 9 unmarked slides with the guards off and 0 of 9 with them on. The claim is about the page refusing the write, not about a model resisting a prompt.
Raw results (including a handEditSurvived field that is false in both arms, because the task is to rewrite that very field): https://github.com/minjikim89/redline/tree/main/evals/results
Where this sits, and what it does not cover
Implementation and error shapes: https://github.com/minjikim89/redline/blob/main/docs/pattern.md
Full notes from building against the spec: https://github.com/minjikim89/redline/blob/main/docs/findings.md
Live: https://minjikim89.github.io/redline/
§6.4's mitigations all address one direction: a site misleading an agent (input-length limits, shared attack evals,
untrustedContentHint). §6.3.2 Current Gaps ends with "no verification mechanism … no behavioral contracts … agents must assume good faith from site developers."The reverse direction has no listed mitigation: an agent, misled or simply over-eager, exceeding the scope a person delegated on a site that exposed write tools. That is the direction prompt injection actually exploits: the injected instruction lives in the site's content, and the damage lands on the site's own data.
Proposal
Name, in §6.4, a mitigation that does not depend on the model resisting injection. The page enforces, in the tool implementations:
The point is that none of these ask the model to behave. They are ordinary preconditions in the tool body, and they hold whatever the agent believes.
Measured
scripts/guardrail-eval.mtshands a model the same tool contracts the page registers and dispatches to the same implementations, with the guards on and off. Scale, stated plainly: one task, one site, two models, ten runs per arm.gpt-5.4 lost 3 of 20 runs to network errors, which were excluded; hence 9 and 8.
Two honest notes on the injection scenario. First, on gpt-4.1 the model followed the injected instruction in 0/10 runs with the guards on and 0/10 with them off, so it did not distinguish the arms, so that run says nothing about the guards. That is why a second, model-free arm exists: a scripted agent that follows the injection by construction rewrote 8 of 9 unmarked slides with the guards off and 0 of 9 with them on. The claim is about the page refusing the write, not about a model resisting a prompt.
Raw results (including a
handEditSurvivedfield that is false in both arms, because the task is to rewrite that very field): https://github.com/minjikim89/redline/tree/main/evals/resultsWhere this sits, and what it does not cover
Implementation and error shapes: https://github.com/minjikim89/redline/blob/main/docs/pattern.md
Full notes from building against the spec: https://github.com/minjikim89/redline/blob/main/docs/findings.md
Live: https://minjikim89.github.io/redline/