Skip to content

privacy notes

july 2026
report 02

← Back to the live test

We tried five ways to filter a coding session. Two made it into the demo.

Some runs scored well and still turned "how is kashyab" into a secret. This is how we rebuilt the data, what failed, and what now runs in the public demo.

arca engineeringtrial deploymentinternal sealed evaluation

what it has to do

Coding sessions mix private data with identifiers that must stay intact. A good filter removes a password and leaves the adjacent Git commit, UUID, stack trace, and syntax alone.

This report covers one job: finding and removing exact strings of sensitive text. Deciding whether a whole section is too personal to share is a separate problem, not evaluated here. We do not claim that this filter anonymizes a session.

14,647
training sections
1,429
development sections
2,700
sealed test sections
2
parallel models

01 / data

How we built the training set

We built a catalogue of 18,457 realistic sensitive values: provider secrets, weak and strong passwords, default and database credentials, and network identifiers. SecretBench showed us the formats real secrets take. PWLDS and SecLists supplied public password lists. Every value is synthetic; we never copied live leaked credentials.

Five larger teacher models then wrote fresh coding scenarios around those values, rotating the ecosystem, developer role, incident type, and leak mechanism. No sentence gets reused with a different value swapped in. That template habit is what broke the earlier corpus.

InputTrainDevTestRole
Public PII7,9181,0512,300A split-disjoint sample derived from AI4Privacy OpenPII.
Grounded secrets2,262280300Provider keys, passwords, database credentials, network identifiers, and matched clean controls.
Short names49598100Lowercase and diverse names inside short, independently written conversations.
Session-style sections3,972n/an/aConversation, source code, logs, configuration, terminal output, and rushed writing. Train only.
12,145
cross-split sensitive-value collisions removed
0
duplicate texts in the final assembly
62,016
split-scoped sensitive values audited

02 / experiments

Pitfalls

three models
we did not ship

The first dataset taught a bad shortcut. The next model scored tokens instead of complete spans. Bidirectional attention made that model better, but names still broke apart. Each result looked reasonable until we checked the exact text it removed.

note 01failed

More examples taught the wrong shortcut

An earlier model looked strong on broad test suites and still turned "how is kashyab" into a secret. The old corpus held 3,354 lowercase single-word secrets and just one comparable person name, so the model learned that a lone lowercase word is probably a secret. Repetitive template sentences around the values made that shortcut even easier to learn.

We stopped treating corpus size as the fix. The replacement data plants realistic values inside independently written scenarios and mixes in harmless lookalikes and short conversational names, so the model has to tell them apart instead of guessing by shape.

3,354 : 1
lowercase secrets per person name in the old corpus
note 02failed

A 4B token classifier had excellent token accuracy and poor spans

We trained a Qwen3-4B LoRA to label every token with one of 33 BIOES tags, on 77,044 train rows. Validation token accuracy reached 98.48%. That number looked reassuring and was nearly useless: most tokens are not sensitive, so a model can score high while missing the ones that matter.

Measured on complete spans, exact typed F1 was 37.07% on OpenPII and 4.91% on names. It scored zero on eight user-reported probes and kept splitting names and credentials into fragments. We rejected it.

4.91%
exact name F1
note 03failed

Bidirectional attention helped, but not enough

We replaced Qwen's causal mask with true banded bidirectional attention, so the model could read both directions around each token, and kept the same labeling head. In a controlled comparison, exact F1 improved from 35.66% to 45.78%, a real 28% relative gain.

The full 2,700-row sealed test landed at 45.62% typed F1. Person F1 was 19.30% and secret F1 was 44.91%. It processed 98.44 rows per second, but speed could not rescue broken boundaries. We rejected this model too.

45.62%
sealed exact typed-span F1

03 / result

What finally worked

note 04kept

Generating exact values worked better than predicting every token

The Qwen design that worked writes answers instead of labeling tokens. It reads the section and returns a short JSON list of the exact sensitive strings it found, each with a label. The server accepts a value only when that exact string exists in the source, so a hallucinated value redacts nothing.

On the same sealed set it reached 94.48% precision, 96.69% recall, and 95.57% typed F1. A more compact values-only variant was faster in bulk evaluation, but it failed the long payment-configuration probe. We kept the typed extractor.

95.57%
sealed exact typed-span F1
note 05shipped

The two models cover different failures

The live Extra mode runs our OpenAI Privacy Filter checkpoint and the Qwen extractor in parallel. The OpenAI model returns the first usable redaction fast. Qwen adds its exact-matched spans as they arrive, without blocking the interface.

On the sealed set, their union reached 97.14% character precision, 99.66% recall, and 98.39% character F1. Typed exact-span precision was lower at 85.52%. The union favors catching leaks and can redact too much, which is why the UI exposes feedback and model status.

99.66%
sensitive-character recall

04 / deployment

What runs in the demo

server-side
private deployments

OpenAI Privacy Filter runs in our private RunPod worker. The Qwen3-4B LoRA runs as a private Fireworks deployment. Browser code never receives either provider key. Extra mode launches both requests at once and shows each model’s state.

Qwen returns copied values rather than character offsets. The server finds those values in the original text and discards any proposal that does not match exactly. A narrow structural guard covers high-confidence credentials such as database passwords embedded inside connection URLs.

Demo inputs are not added to the training corpus. Both services can scale to zero, so a cold request can be much slower than a warm inference. The interface reports that separately instead of hiding the wait inside the first model’s timing.

05 / limits

What still goes wrong

The test is internal

The final split is value- and text-disjoint, but earlier failures shaped later datasets. Treat these numbers as engineering evidence, not an independent certification.

The data is mostly synthetic and English

Public PII and external Loghub probes help, but they do not establish equal quality across languages, communities, or real organizations.

The union can over-redact

High character recall is useful for leak prevention. It also means the two-model union sometimes removes more context than a strict exact-span scorer would prefer.

Redaction is not anonymization

A missed secret is still possible, and surrounding context can remain identifying. This filter lowers exposure risk; it is not a compliance guarantee.

06 / sources

Data sources