Locked decisions¶
Nine decisions settle most arguments before they start. They are locked: they can be revisited with an argument, never routed around.
D1 — Plausible surrogates, never sentinels¶
[HOST_1] and <IP_3> destroy the agent's ability to reason. A surrogate is
plausible and type-faithful, and the invariant is stated once:
A surrogate must be indistinguishable in nature from what it replaces, and must never designate a real-world entity.
Both halves matter. The first was breached when a /24 came out as a word.
The second when varying an octet of a documentation range walked out of
reserved space into somebody's routed network — a command the model proposes
would then reach a stranger's machine. See Surrogates.
D2 — No resolution inside a stream¶
Restoring surrogates inside partial_json fragments cuts values in half.
Accumulate, wait for the block to close, parse, resolve atomically.
D3 — Signed blocks stay opaque¶
thinking and redacted_thinking are signed by the API. Rewriting them
invalidates the signature. The list of deltas to resolve is therefore
positive, not an exclusion list: an unknown future delta is left alone
rather than modified.
D4 — A secret is a reference, never restored¶
Tokens, passwords and keys are replaced by a reference and are never restored into model output. Restoring one would put a live credential back into a command the model just generated. This is why URL credentials are stripped before anything else touches the URL.
D5 — Fail-closed¶
An unknown surrogate is never guessed. A detector outage is a 503, not a best-effort pass-through. A hallucinated surrogate resolves to nothing rather than to a plausible neighbour — a fictional host wearing a real zone is worse than an unresolved name.
D6 — Strict injectivity¶
Two real values never share a surrogate, enforced by uniqueness in the store and checked in CI. Measured on 10 000 values: zero collisions, byte-for-byte determinism, and 50 threads writing at once without a duplicate.
D7 — The detector is a separate process¶
AnonShield is GPL-3.0 and is reached over HTTP only. Nothing imports across the boundary, in either direction, and a test enforces it. See Licensing.
D8 — Read-only MVP¶
No SCIM, no RBAC. A permission model that nobody administers is a false guarantee.
D9 — The proxy is the only network path¶
This is the one decision not met on a workstation, and it is stated as
such. Four destinations out of five do not honour ANTHROPIC_BASE_URL. The
answer is deployment shape — an internal network with the proxy alone
straddling both sides — not a local firewall: api.anthropic.com and
mcp-proxy.anthropic.com resolve to the same address, so no IP rule can
separate them. See Network isolation.
The answers that came with them¶
| Question | Answer |
|---|---|
| Determinism scope | per project by default; session, tenant or global on request |
| Tool coverage | nothing hard-coded per tool — generic detection plus custom patterns |
| Preserved attributes | environment, /24 co-membership, human vs service, internal vs external, and the interval between two dates — accepted leaks, all five |
| Vault location | local, same user; outside the repository; treated as a secret |
The five preserved attributes are deliberate: they are what makes the pseudonymised text still readable as infrastructure — and, since dates are shifted by one constant rather than drawn, still readable as a chronology. They are also, precisely, what a re-identification attack would use — which is why they are listed here and analysed in the re-identification analysis rather than left implicit.