Verification

De-identification is not a setting you turn on once. Every claim below is a lower bound from planted or synthetic truth, never a proof about your un-planted real data, and each is labelled as such in the code and in the report it produces.

Per-batch tripwires

The default canaries are obviously synthetic: Liam Whitaker, the NHI ZBX4417, 021 555 0182 with its collapsed form, 14 March 1986 with 14/03/1986, and Twizel. Re-detection reuses the gate’s detector, so it is detector liveness over the output, not an independent gate.

Qualify a model first

qualify_model(deps, config) runs three checks against the model wired into deps and returns a verdict per check: a clean synthetic transcript must cross with at least one beat (a model that refuses everything is safe but useless); every planted canary must be stripped; and a planted singling phrase with no named entity (a sole role at a site) must be caught by the judge. Approve a model only when all three pass, and re-run when the model or its configuration changes. A mock model passes trivially, so run it with real in-boundary credentials.

The simulated client

Tacit runs the SDK the way a customer would, inside a boundary it can observe, and sends only artifacts into a real Tacit org. One run yields three layers of evidence: The egress proxy is mitmproxy with an addon that logs every request and refuses any host off the allowlist; the client is routed through it. The report asserts that the only hosts contacted are the in-boundary model and Tacit, and that no planted literal, raw or reformatted, appears in any body sent to Tacit. A run without the proxy reports egress: FAIL (not observed), because an unobserved wire is not evidence. The Docker variant puts the client on a network whose only exit is the proxy, so the boundary is enforced, not just observed. The corpus is planted truth, so every number below is a lower bound on an un-planted corpus.

What the measurements say today

Each row is an observation over a small number of runs.