Chapter 2 of 8 · 15 min read
An account boundary is not a privacy boundary
On this page
An internal IT helpdesk agent at a 4,000-person insurer shipped organisation-scoped memory in March with a reasonable justification: when one employee discovered that the VPN client needed a manual DNS entry after the Windows update, everyone who hit the same problem that week should benefit from it rather than re-deriving it eleven times. The feature worked. Deflection on the VPN issue — the share of conversations the agent closed without a human ever picking them up — went from 34 percent to 71 percent over nine days, and the promotion rule that moved a thread-scoped finding up to organisation scope — the finding had to be confirmed by a successful resolution, and it had to be stated as a fact about a system rather than about a request — looked defensible in review.
In June a support engineer looked at an org memory dump while debugging a retrieval complaint and found the record Employee is on a phased return following an occupational health referral; approve shorter shifts in the rota tool. It had been written five weeks earlier from a conversation where someone asked how to record reduced hours in the rota system. The promotion rule had fired because the conversation ended in a successful resolution and the extracted sentence described a configuration in the rota tool. The record had been retrieved twice since, both times into conversations with other people in the same department who had asked how phased returns are handled. Nobody complained, because nobody outside the retrieval pipeline knew it had happened, which is the part that made the incident review uncomfortable rather than merely awkward.
The account boundary held perfectly throughout. No record crossed from the insurer to another customer, every query carried the right tenant, and the isolation tests that chapter 6 will describe would all have passed. What failed is the assumption underneath organisation-scoped memory: that everything reaching the agent through one account is a fact the account may redistribute internally.
How a health disclosure passed a rule written to stop it
The promotion rule is worth taking apart step by step, because it was not careless and the way it failed is the way this class of rule always fails.
A promotion rule is the predicate that decides whether a fact learned inside one conversation is copied up to a wider namespace, in this case from the thread to the organisation. The insurer's had two conditions. The conversation had to end in a successful resolution, and the extracted sentence had to describe a system rather than a request. Take them in order against the phased-return conversation. The employee asked how to record reduced hours in the rota system, somebody answered, the ticket closed as resolved — first condition satisfied, and satisfied honestly, because the conversation really did resolve. The extractor then produced a sentence that named the rota tool and an action to take in it, which reads as a statement about a configuration — second condition satisfied, and again not by accident, because the sentence genuinely does describe something you do in a piece of software. Both conditions true, so the record was promoted.
Nothing in that chain is a bug. Each link holds. The defect is in what the two conditions are properties of. Resolution is a property of the conversation, and system-versus-request is a property of the sentence's grammatical shape. Neither is a property of the person the sentence is about, and the sentence was about a person.
That is the shape worth carrying out of this chapter, because it recurs. The rule held one quantity fixed — the outcome of the conversation — and treated it as a proxy for safety. Outcome is constant with respect to the thing that actually determines the risk. A conversation about a DNS entry and a conversation about an occupational health referral both resolve successfully, so the resolution test returns the same verdict for both, while the property that varies between them — whether the extracted sentence has a human being at the centre of it — moves from absent to present without the rule registering anything at all. A defence whose signal does not move when the danger moves is not weak. It is measuring something else.
Two different questions arrive at the same table
The insurer's schema could not distinguish the DNS fix from the occupational health record because it only ever asked one question about a memory: which namespace does this belong to. The question it needed to ask first is who the fact is about — the person it describes, whom data protection law calls the data subject. A fact about a system, a contract, a configuration or a process has no data subject, so sharing it inside the account redistributes nothing that belongs to a person. A fact about a person has a subject, and the account is not that subject, no matter that the account signed the contract and pays the invoice.
The commercial relationship and the privacy relationship run between different pairs of parties, which is why they produce different boundaries. Your contract is with the insurer. The occupational health information is about an individual, who has interests in it independent of their employer's, and in most jurisdictions those interests are protected regardless of whose laptop the conversation happened on. Data protection law makes the split explicit: the insurer is the controller and you are the processor, so the insurer decides what happens to employee data — and yet the individual retains rights against the controller, and the controller's own lawful basis for processing does not extend to broadcasting a health disclosure to the person's colleagues through a chat interface. A vendor who reasons "the customer owns the data, so internal sharing is their call" has answered the contractual question and left the privacy question untouched.
Even when the customer's admin genuinely does have the authority to permit internal sharing, the permission is per purpose, not blanket. An admin may reasonably authorise sharing operational findings across their staff and have no authority at all to authorise sharing what an employee said about a grievance, because the employee disclosed it to a helpdesk tool in the expectation that it was going to a support ticket rather than into a corpus their manager's chat window draws from.
The expectation is doing real work in that sentence, and it is worth showing that it is a measurable property of the system rather than a soft consideration. People calibrate what they say to who they believe is listening, and a helpdesk conversation reads as a private channel to a single handler even when the interface is a chat box with a model behind it. The insurer's own numbers made this visible after the incident: when they added a one-line notice above the composer saying that findings might be shared with colleagues, changing nothing else, two numbers moved. Average conversation length in the HR-adjacent categories dropped from 7.4 turns to 4.1, and the proportion of conversations abandoned before resolution went from 9 percent to 22 percent.
Read those two numbers together rather than separately. Shorter conversations on their own would be ambiguous, since a notice might simply have made people more efficient. Shorter conversations alongside more than double the abandonment rate rules that reading out: people were not getting to the answer faster, they were stopping before they got there. What the notice changed was the disclosure, and the only new information it carried was who would eventually read the result. Users who understand that memory is shared behave differently, which means a system relying on their not knowing has extracted a disclosure they would not have made informed. That is a workable definition of the boundary this chapter is about, and it is independent of what the contract says.
The gate that decides shareability
The promotion decision that failed at the insurer was a single boolean applied to conversations. What it needed was a classification applied to each extracted record, at write time, before anything is stored at organisation scope.
The second question in that flow — whether the fact survives the author leaving the company — is the practical version of the ownership test from chapter 1, and it does most of the work. "The VPN client needs a manual DNS entry after build 22631" survives; the person who found it is incidental. "I need shorter shifts" does not survive, because the sentence has no meaning without the person it refers to.
It is worth being explicit about why a survival test answers a subjecthood question, since the two sound unrelated. A sentence with a data subject is one whose truth conditions include a particular person: remove that person and there is nothing left to be true or false about. A sentence about a system has truth conditions that mention only the system, so the people around it can all be replaced and the sentence's status does not move. Asking whether the fact survives the author leaving is a way of running that substitution without needing a definition of personal data — it takes a judgement a reviewer would find slippery and turns it into a counterfactual an extractor can be asked about directly.
The branch on the right catches the awkward middle: facts that are about a person but are also legitimately organisational, such as who administers the SAP integration. Those are usually available from a directory or an on-call schedule that already has an access policy, and copying them into memory replaces a governed source with an ungoverned one, so the better move is to look them up at query time rather than remember them.
The re-identification branch matters more than its size in the diagram suggests. The reason is arithmetic rather than legal. Stripping the name from "Employee is on a phased return" does not anonymise it, because what is left is a sentence true of some member of a set, and the set is whoever the reader could plausibly be thinking of. Anonymity is a property of how large that set is. At population scale the set has thousands of members and naming one of them is guesswork; in a six-person team where one person's hours visibly changed, the set has one member and the redaction has removed nothing. Going the other way and generalising it to "some employees are on phased returns" shrinks the information rather than the identifiability, which makes it useless. Anonymisation as a way to make personal facts shareable works at population scale and does not work at team scale, which is the scale most organisation-scoped memory operates at.
Encoding the outcome takes two fields, and the reason to store both rather than a single shareable flag is that an auditor asking why a record is visible needs the reason, not the verdict:
{
"id": "mem_9f3a21",
"text": "VPN client requires a manual DNS entry (10.4.0.53) after Windows build 22631.",
"namespace": ["org_insurer", "org", "org_insurer"],
"subject": { "type": "system", "ref": "vpn-client" },
"shareable": true,
"shareable_reason": "no_data_subject",
"source_thread": "thr_88f012",
"source_user": "usr_4471",
"promoted_by": "gate:v3-subject-classifier",
"promoted_at": "2026-03-11T09:14:22Z"
}The namespace array is chapter 1's key with the tenant first, the scope second and the owner third, and at org scope the tenant appears twice because the account owns the record. subject records what the gate decided the sentence was about, shareable_reason records why, and promoted_by names the version of the gate that decided it, so a later change to the gate can be replayed against records it already admitted.
The classifier behind shareable_reason is a separate call from the extraction that produced the text — the model pass that reads a finished conversation and proposes candidate sentences worth storing — and keeping the two apart is what made the insurer's rewrite work. The reason is that the two components want opposite error preferences and a single component can only have one. Extraction is asked to be generous, because a fact it fails to notice is simply lost and cannot be recovered later; the subject classifier is asked to be conservative, because a personal fact it lets through is an incident. When they were one prompt, the model traded the two objectives against each other at an operating point nobody chose, in ways nobody could inspect. Split, each component can be pushed to its own end of the trade, and each can be measured on its own.
Measuring it is what the split buys. The classifier could be evaluated on a labelled set of its own — 600 extracted candidates hand-labelled by two reviewers — where it reached 98.5 percent recall on personal-subject records at the cost of routing about one in nine genuinely organisational facts down to user scope. Those two error rates are not comparable quantities and should not be balanced. A shareable fact wrongly kept private costs one repeated conversation, paid once by one person, and it is self-correcting because the next employee to hit the problem re-derives the answer. The reverse costs an incident review: a disclosure that cannot be un-made, discovered late if at all, and arriving with a regulator attached. When the two sides of an error trade differ by that much, the operating point belongs far towards recall, and one in nine organisational facts demoted is the price of getting there.
source_user staying on an organisation-scoped record looks like a contradiction and is the field that makes the rest possible. The record is readable by everyone in the account; the provenance is readable only through the control path chapter 7 describes. Keeping the link is what lets you honour a deletion request from that user against records they caused to be written, and what lets an incident review answer "how did this get here" in one query rather than by grepping conversation logs.
Where the line genuinely is fuzzy, and what to do about it
There is a category this framework does not resolve cleanly, and pretending otherwise sets you up to be surprised. Consider a sales agent used by a customer's account team, where one rep records "the buyer at Meridian said their CFO hates annual prepay and will veto it." The subject is an identifiable person, so the flow above routes it away from org scope. The fact is also unambiguously commercial intelligence that the account team exists to share, the buyer stated it in a business meeting, and no CRM in existence would treat it as personal data requiring per-subject consent. The honest answer is that the subject test is a strong default that needs an escape hatch: an explicit, per-workspace policy that permits sharing facts about third-party business contacts in a business context, recorded as a policy decision with a named owner rather than as a code path someone added quietly.
The other fuzzy case runs the opposite way. A fact with no data subject at all can still be one you must not share internally, because the customer's own access control says so. "The production Postgres credentials rotate through Vault path secret/prod/db" is a fact about a system that survives its author leaving, and it belongs at organisation scope by every test in this chapter, and it should be visible to eleven people rather than four thousand. Organisation scope is the coarsest useful boundary and it is not a substitute for the role-based filtering that 9.15 established over documents; when memory records inherit sensitivity from the systems they describe, they need the same treatment, which usually means carrying a required-role field and filtering on it alongside the namespace.
Those two cases are the same defect seen from both sides, and naming it keeps the framework honest. The survival test detects subjecthood, and subjecthood is being used as a proxy for shareability. The proxy holds for the overwhelming majority of records, which is why it is worth building on. It comes apart wherever the subject of a fact and the audience for it are set by different things: a third-party business contact has a subject and an audience the business legitimately defines, and a production credential has no subject and an audience its own access control defines. Both residuals need a field the gate does not produce, which is why the design carries a required-role column alongside the namespace rather than trying to fold everything into one decision.
What this chapter does not give you is a reason to avoid organisation-scoped memory. The insurer's VPN record was worth having, the deflection improvement was real, and a product that refuses to let colleagues benefit from each other's findings is throwing away the main advantage of memory in a multi-user account. The correct position is that org scope is a privileged destination that records are promoted into by a gate with a stated reason, rather than a default that thread-scoped records drift towards because the promotion rule looked at the conversation instead of the sentence.
Deciding the policy is the easy half. The insurer had a written rule that personal health information must never be promoted, and the rule was in the prompt of the extraction model, and the record was promoted anyway — and separately, once it existed, the nightly re-embedding job copied it into the shared vector index without ever consulting the gate that was supposed to govern it. A policy applied at one point in the system is not applied at the points that never call it, and the next chapter inventories exactly which ones those are.
Memory — scope and privacy — read the current version at https://daviddominguez.dev/learn/en/memory-scope-and-privacy/an-account-boundary-is-not-a-privacy-boundary