Minimize private data in local decision state
Choose the fields a local model needs, trace downloads and request handling, and test whether redaction preserves the decision before sharing inputs.

Local execution still needs a smaller payload
I would ask what the decision needs before passing a whole customer record to a local model. It gets every detail we include. The documented ticket example asks where to route a message and whether the customer requests a refund. The customer’s statement supports those questions, but does not verify what happened in the payment system.
Ardana does not choose a smaller input for us. Its decider recursively serializes every field in a JSON value, and string input passes through unchanged. Nested objects therefore do not keep their contents out of the prompt. The wording of each question and its answer criteria also enter the prompt, so I would review those alongside the input.
Running the request locally changes where execution happens. Ardana’s server plans the request and queues local execution, with model weights loaded from a filesystem path. NIST’s privacy framework treats local processing, limiting identification, and selective disclosure as separate outcomes. I would treat those as separate engineering questions when building the request.
I would choose fields before submission, starting with the question I want answered and including only the evidence needed to answer it.
Build the state from the question
The documented ticket request below asks where to route the ticket and whether the customer wants a refund. When choosing evidence for those questions, I would keep in mind that the customer reports a duplicate charge. That report is not an independently verified payment record.
{
"model": "decider:2b",
"state": "My card was charged twice for order A-104. Please refund the duplicate.",
"questions": {
"department": {
"type": "choice",
"instructions": "Which department should handle this?",
"criteria": ["billing", "technical", "sales"]
},
"refund": {
"type": "noul",
"instructions": "Does the customer ask for a refund?"
}
}
} For those questions, I would build a fresh payload from an allowlist owned by the application. It would include the customer’s description and leave out unrelated account fields. The request type accepts JSON state but provides no redaction setting. Selecting which fields reach the model belongs in the caller, before submission.
Inside the description, I would replace an unnecessary order identifier with a consistent placeholder, using the same replacement for every mention of that order. The reported duplicate charge and refund request would stay because they are evidence for these questions. That replacement is a candidate to test, not a guarantee that the decision stays the same.
The response needs the same attention as the input. Our answer implementation returns caller-supplied question identifiers and option names, and score responses carry caller-supplied descriptions. I would keep private identifiers out of those labels and review the question instructions too. A typed answer can still carry sensitive text supplied by its caller. Once I have chosen the payload, I would trace where it goes.
Trace provisioning separately from inference
I would provision the model before sending the minimized request. The documented installers and model downloads use the network, and first use can download an unpulled library model automatically. Pulling explicitly makes that step visible.
curl -fsSL https://ardana.ai/install.sh | sh irm https://ardana.ai/install.ps1 | iex ardana pull decider:2b Next I would bind our server explicitly to loopback. The request handler resolves the model, plans the request, and queues local execution using filesystem weights. Binding to all interfaces opens the listener to the network; the optional API key checks bearer authorization on versioned API routes.
ardana serve --host 127.0.0.1 --default-model decider:2b From another terminal, I would submit the prepared request file to that listener. This keeps the HTTP destination explicit. Local inference still leaves provisioning and background checks to inspect.
curl http://127.0.0.1:8000/v1/systemone -H 'content-type: application/json' -d @request.json Serving normally refreshes the model catalog at startup and every hour. Those catalog requests do not attach decision state, but they still contact a remote endpoint. Installer-managed runs and servers can also check releases once daily.
After provisioning, I would stop that server and restart it with these three controls. Each addresses a different path. They depend on the required model files already being available locally.
ARDANA_LIBRARY=off HF_HUB_OFFLINE=1 ARDANA_NO_UPDATE_CHECK=1 ardana serve --host 127.0.0.1 --default-model decider:2b The first setting disables library reads and limits serving to pulled models. The second makes Hub lookups use local files and fail when files are missing. The third disables automatic release checks and notices, while leaving explicit updates available:
ardana update I would keep the storage boundary separate too. Weights and supporting files use the Hugging Face cache, while registry entries and library metadata have their own home directory. These settings cover the identified downloads and checks; they do not establish machine-wide isolation. With those paths accounted for, I would test what the smaller input does to the decision.
Test the evidence that redaction leaves behind
I would pair each original request with its minimized version, keeping the model and questions fixed. Both need a reviewed expected answer before I compare their predictions. For the ticket example, I would check department routing and expressed refund intent, without treating the customer’s statement as verified payment evidence.
Following CheckList’s invariance tests, I would test identifier removal where it should preserve the correct label. I would include cases with negation, relationships between people, and temporal order. Each minimized version must preserve who did what, who a pronoun refers to, and which event happened first.
For each member of a pair, I would put that request in the file below and run the command. It evaluates locally without contacting an inference server. JSON gives me the option probabilities and input-token count.
ardana run decider:2b --request request.json --json Matching labels would be the first check. I would also inspect probability shifts and whether they cross an application’s decision threshold. JSON probabilities are rounded to 4 decimal places, so matching values cannot prove identical underlying logits. I have run no new equivalence measurement here and have no measured tolerance to recommend.
I would also review the minimized text for sensitive spans before sharing it, even when the predictions agree. Presidio separates detection from replacement or removal. Its FAQ documents false positives and false negatives, so I would check both missed private text and useful evidence removed by mistake.
Treat logs and share links as input copies
I would review a playground link as carefully as a copied request. Ardana compresses the supplied text, questions, and selected models into the link, then decodes them when it opens. The link carries another copy of those inputs, even when its contents are unreadable at a glance.
For ordinary logs, I would start with counts, durations, and error categories. NIST’s privacy framework treats minimization in audit and log records as a separate outcome from testing privacy measures. Replaying a decision can still justify retaining a complete request. I would keep those records separately, with restricted access, a stated replay purpose, and a retention limit.
Memory lifecycle needs its own check. The keep-alive setting defaults to 5 minutes and controls idle model unloading. llama.cpp clears its KV cache before decoding each prompt. I would not treat either behavior as evidence of secure erasure of private data.
Inspect a request fixture and the playground sharing implementation in Ardana’s GitHub repository. Trace what the link preserves before using private inputs. I would like to hear how you decide which replay records deserve to be kept.