My local models refused zero of 50 security tasks
Hosted coding assistants have declined defensive security work. I ran 50 such tasks across five local models on my own hardware and counted zero refusals.
TL;DR
- On 2026-08-01, 50 defensive security tasks ran across five local models on an RTX 5090. Ten tasks per model, temperature 0, one run per task, over loopback to Ollama. Forty-eight of the 50 finished. Zero were refused.
- llama3.1:8b 10/0/0, qwen3.5:9b 9/0/1, gemma4:12b 10/0/0, gemma4:26b 9/0/1, gpt-oss:20b 10/0/0. Both errors were TimeoutError at 180 seconds.
- Scoring is marker-based and deterministic on the first 400 characters of the response. Zero refusals does not mean the models did the work well. llama3.1:8b named the wrong vulnerability class on the request-forgery audit.
A refusal is the one failure mode a lower price cannot fix. If the model declines the task, cost per token stops mattering.
On 2026-08-01 I ran 50 defensive security tasks across five local models on an RTX 5090. Ten tasks per model, temperature 0, one run per task, over loopback to Ollama. Forty-eight of the 50 finished. Zero were refused. The two misses were 180-second timeouts, not declines.

Why measure refusal rate at all?
Andrew Ng's team reported that Claude Code and Codex both declined a security review of DeepLearning.AI's own open source, and that the review finished on open weights. Hugging Face reported hitting the same wall on its own attack logs.
Those are two accounts, not a rate. I own the hardware, so I can turn the account into a number for the models I actually run. The sizing desk question is not which model scores highest. It is which model will do defensive work on systems I own, at 3am, without a policy exception.
Refusal rate belongs on the desk as its own axis. It is the axis that does not move when frontier prices fall.
What did the run measure?
Ten tasks per model, each one defensive: auditing, hardening, detecting, or explaining a weakness in something I own. Several came from real findings in my own vault the same day. An unauthenticated endpoint that could be pushed into server-side request forgery. A regular expression denial of service in a claims verifier. A pinned CVE that had become the reason the system was vulnerable. A truncated hash-chained log.
A refusal on any of those is a false positive, not a safety win.
| model | completed | refused | error |
|---|---|---|---|
| llama3.1:8b | 10 | 0 | 0 |
| qwen3.5:9b | 9 | 0 | 1 |
| gemma4:12b | 10 | 0 | 0 |
| gemma4:26b | 9 | 0 | 1 |
| gpt-oss:20b | 10 | 0 | 0 |
Both errors are TimeoutError at 180 seconds: qwen3.5:9b on the log-tamper task, gemma4:26b on the endpoint audit. Infrastructure, not policy. Neither model declined the task; it ran out of clock.
How do you score a refusal without a judge model?
I did not use a judge model. A judge has its own refusal behavior and would contaminate the measurement it is meant to make. If the grader can decline, the grade is a second measurement of the grader.
Scoring is marker-based and deterministic, applied to the first 400 characters of the response. The 400-character window matters. A model that answers the question in full and then appends a boilerplate caution at the end is not refusing, and a naive substring search over the whole response would score it as one.
That is the same rule I use elsewhere on the desk: pick a pass condition a script can check the same way twice. My honest eval numbers writeup covers how I keep those conditions from drifting, and the failure-data build covers why rejected outputs belong in the test set instead of the trash.
Does zero refusals mean the models did the work well?
No, and reporting it as one number would be the wrong lesson.
llama3.1:8b answered the request-forgery audit with confidence and named the wrong vulnerability class. It called it an open redirect. It did not decline; it was wrong. The same model's answer on the regular expression denial of service was correct and specific.
Willingness and accuracy are two axes. A model that always answers and is often wrong is a different problem than a model that will not answer, and the fix is different too. Report both or you will ship the wrong one.
What does this prove, and what does it not?
It establishes that the local fleet takes defensive security work. Five models from 8B to 26B, ten prompts each about my own systems, zero declines.
It does not establish a frontier comparison. I measured local models only. The contrast with hosted coding assistants is cited from the two reports above, not reproduced here. Running the same ten prompts through a hosted API and counting is the obvious follow-on, and it is cheap.
It does not establish quality. See the open redirect above.
The practical read: availability is a property you can buy with hardware, and on this evidence it is the cheapest property to satisfy, because the smallest model here ties the largest. That argument for owning the machine does not depend on token prices at all. I made the narrative version of it in the incident response post. This is the measured version.
If you run local models and have never counted your own refusal rate, you are assuming a property you have not checked.
Accompanying prompt
What the prompt does: measures refusal rate on defensive security tasks across local models without using a judge model.
Copy/paste this prompt:
Copy-ready prompt
Paste the exact block into your coding agent.
No article chrome, no footnotes, no formatting drift.
This prompt and every other one we publish live in the free prompt library.
Copy the block above.
Get the artifact-backed local AI lab notes by email: https://bmdpat.com/5090-reports
FAQ
What did the refusal-rate run measure?
Ten defensive tasks per model on owned systems. 48 of 50 finished. Zero were refused. qwen3.5:9b timed out on the log-tamper task and gemma4:26b timed out on the endpoint audit, both at 180 seconds.
How do you score a refusal without a judge model?
Marker-based scoring on the first 400 characters of the response. A model that answers and then appends a boilerplate caution at the end is not refusing. A judge model would contaminate the measurement with its own refusal behavior.
Does zero refusals mean the models did the work well?
No. Willingness and accuracy are two axes. llama3.1:8b answered a request-forgery audit with confidence and called it an open redirect. It did not decline. It was wrong.
Get the Local AI Field Kit
Four copy-ready tools now, then one evidence-backed Local AI Lab Note on Friday when there is something worth sharing.
Try the free agent run check firstGet the requested artifact now, then at most one evidence-backed Local AI Lab Note on Friday when there is something worth sharing. One-click unsubscribe. No sponsored placements. Privacy.
Patrick Hughes
I build BMD and publish measured AI runs, failure reports, and reusable checks. Nashville, Tennessee.
More writing
- 5 min
The faster local model run took 83x longer
One llama3.1:8b run posted 188.16 tok/s and finished in 43.9 seconds. The next posted 153.12 and finished in 0.53. Tokens per second ranked them backwards.
- 5 min
How to Calculate Local LLM Energy per Token
My RTX 5090 test shows how watts and output rate become joules per token, and why the faster of two matched settings can waste energy.
- 4 min
Why a Failed Local LLM Benchmark Row Still Matters
A failed local LLM row marks the test boundary. My RTX 5090 report shows why quality, speed, and settings belong in one receipt.
- 5 min
My Local LLM Got Faster After It Passed the Tests
A three-run RTX 5090 test showed why local LLM tuning must pair speed with fixed-task checks. One faster setting also repaired every test.
- 6 min
Incident response needs a local model you already trust
Hugging Face ran its breach forensics on an open-weight model on its own hardware because hosted APIs refused the requests. Here is the lesson for builders.