Answer within the boundary, and show its shape
Tags: privacy, permissions, trust
Restricting what a model can see is ordinary and increasingly common β redaction, row-level permissions, tenancy, tool scopes, an air gap. The problem is that the model does not know what it is missing. It answers from what it has, fluently, in exactly the same register it would use if it had everything.
A different failure from being wrong
A wrong answer can be caught. Someone reads it, it contradicts something they know, they check.
An answer that is incomplete because of a boundary has no such tell. It is composed entirely of true things. It is confident, well-formed, and quietly missing the part that would have changed the conclusion β and the reader has no way to detect the absence, because absence has no shape unless someone draws it.
That failure lands hardest where restriction is used, which is not a coincidence. Context gets restricted in legal, medical and financial work precisely because the material is consequential. So the setting that most needs the boundary is the setting where an invisible gap costs the most.
Give the gap an object, not a softer sentence
The weak fix is a hedge: the model, sensing thinness, writes something vaguer. That is worse than nothing, because vagueness is indistinguishable from a cautious style.
The strong fix is to keep the withheld thing present as an object in the answer. A marked redaction the reader can see and reason around holds a place in the sentence: they know something was there, they know what kind of thing it was, and they can go and find it through a channel that is allowed to tell them. A sentence that got quieter holds nothing.
The same move generalises past redaction:
- Permissions. "This covers the 12 documents shared with you" is an object. Silently answering from 12 of 40 is not.
- Tool scope. An agent that names the repository it could not read gives you a next step. One that reasons around the gap gives you a conclusion built on a hole.
- Time. A model answering from a corpus that ends in March should say so where the answer depends on it, not in a footer.
Mark it where it applies, on the specific claim that was affected. A blanket disclaimer at the top of the session is a legal notice: it is present, it is true, and nobody reads it as information about the paragraph they are currently acting on.
When naming the gap leaks the thing
"I can't tell you about the Henderson acquisition" reveals that there is a Henderson acquisition. This is the real limit on the pattern, and it is why the resolution is show its shape rather than name what is missing: the shape can be described at a grain that is honest without being disclosive β the category, the count, the fact that a restriction applied at all.
The one thing that is never acceptable is the third branch left undone: a user who does not know a boundary exists, reading an answer that does not mention one.
Grounded in
DocRobot's whole premise was that the model only ever saw a scrubbed copy of a document. It is worth being honest about the bill for that: because the model only saw a scrubbed copy, the answers came back scrubbed too. Ask who remains liable on termination and the reply names a black bar, because the party's name was the thing that could not be sent.
That reads as an answer rather than a malfunction for one reason. Redaction was the first screen of the flow, not a setting β search for a client name, a date, an account number, and every match lit up in the document itself with a count beside it, and the user confirmed the pass and watched it happen. So by the time they asked anything, they already knew the shape of what was missing. The black bar in the answer is the same object they had put there.
That is the general lesson, and it is a sequencing one: a boundary is legible in the output when the user participated in setting it. A boundary applied invisibly upstream produces an answer nobody can read correctly, however carefully the gap is marked.
Anti-patterns
- Silent degradation. The default, and the worst of these. Nothing in the answer indicates that anything was withheld.
- A blanket disclaimer instead of a mark. True, present, unread, and unattached to the claim it applies to.
- Hedged prose in place of a marked gap. Vagueness reads as style, not as absence.
- An apology instead of a description. "I'm sorry, I don't have access to that" tells the user about the model's feelings. "This covers the 12 documents shared with you, of 40 in the matter" tells them what to do next.
- Naming the withheld item so precisely it leaks. The failure in the other direction, and the reason for the coarser-grain branch.
- A boundary the user never agreed to and cannot see. Then the answer is unreadable in principle, because the reader has no model of what is absent.
The smallest version worth building
Pass the model a description of what was withheld β not the content, the shape: how many items, of what kind, and why. Then require the answer to carry it wherever it applied.
If the redaction is structured, and it should be, you already know which spans were removed. Render them as objects in the output rather than letting them dissolve, and you get most of this for the cost of not throwing information away.
Related patterns
- Redaction moves to the export β the sibling: where the boundary sits once local inference moves it, and why the craft survives the constraint that created it.
- Mark what the product vouches for β the same question one level up, about claims rather than gaps.
- Design the failure state first β "nothing to say, because I was not allowed to see it" is a distinct failure mode and needs its own screen.