尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Blanktick, your antivirus built for AI. Free, offline Windows security that finds where bad AI can get into your PC, with a read-only MCP server so your own AI agent can help. Kotlin/Compose.
翻译准备中
正在加载完整 README。
查看完整 README ↗Antivirus looks for bad files. Bad AI usually isn't one. An AI assistant that a web page can talk into running commands, a model server anyone on your network can use, an API key in a plain-text settings file: none of these is a file to scan. Blanktick looks at how the AI on a PC is set up and what it is doing, and lets your own AI agent help you close the gaps.
| What it looks for | Rule |
|---|---|
| An AI assistant that can both read outside content and act on the computer (prompt-injection reach) | DSK-AI-006 |
| AI model servers listening on the network | DSK-AI-001 |
| Which tools an AI assistant is allowed to run (MCP servers) | DSK-AI-002 |
| API keys stored in plain text in AI settings files | DSK-AI-003 |
| AI tools that download and run code | DSK-AI-005 |
| Windows Recall keeping a searchable record of the screen | DSK-AI-004 |
| Live: an AI assistant starting a shell (cmd, PowerShell, mshta) | DYN-AI-001 |
| Live: an AI agent acting right after reading outside content | DYN-AI-003 |
Your AI on your side. Blanktick.exe --mcp is a stdio MCP server with eight
read-only tools (docs/mcp.md). Connect Claude or another agent and it
can explain what is exposed and how to fix it. It cannot change anything: there are
no fix tools by design, and a test enforces that. The agent explains; you act.
What it does not do: delete or quarantine anything, block every attack, or replace Windows Security. The live rules run while the app is open and flag by default; they stop a process only if you turn that on.
The rest of this README covers the other half (the whole-PC scan, the 75 Windows settings checks) and the design rule behind all of it: "not checked" is a result. When Blanktick can't look at something, it says so instead of showing a green tick.
A security checkup for your phone and your computer that runs entirely on the device it is checking.
The app has no INTERNET permission. Not "we choose not to send data" — the
operating system will not let it open a socket, because it never asked for one.
That is verifiable in ten seconds against any build:
$ aapt dump permissions app-debug.apk
package: com.blanktick.app.debug
uses-permission: name='android.permission.READ_MEDIA_IMAGES'
uses-permission: name='android.permission.READ_EXTERNAL_STORAGE' maxSdkVersion='32'
uses-permission: name='android.permission.PACKAGE_USAGE_STATS'
$ aapt dump permissions app-debug.apk | grep INTERNET
$
The build enforces it: assertNoNetworkPermissionDebug reads the merged
manifest and fails if any network permission appears — including one injected by
a transitive dependency, which is the realistic way it would happen.
A desktop JVM has no permission model to opt out of. A process started by the user can open sockets and nothing inside that process can make that untrue. So the desktop build makes a narrower claim and enforces it differently:
$ gradlew :desktop:check
Blanktick: no Blanktick class references a networking API.
Blanktick: scanned 43 runtime jars, 0 contain networking code.
Blanktick: dependency network surface unchanged (0 jars).
assertNoNetworkBytecode scans the compiled classes of :core and
:desktop for any reference to java.net.Socket, HttpURLConnection,
SocketChannel and friends, and fails the build if one appears. Exactly one
class is exempt, by exact name: NoNetwork, whose job is to break them.auditDependencyNetworkSurface pins every third-party jar on the
runtime classpath — 42 of them — and flags those containing networking code.
As measured on 2026-08-29, none of the 43 runtime jars (Compose
Multiplatform, Skiko, coroutines, the Kotlin stdlib) contains a single
reference to a networking API. The build fails if the set changes.
An earlier version recorded only the jars that did contain networking code,
which meant a new clean dependency passed silently. That was a false assurance
and is fixed.NoNetwork additionally blocks java.net.Socket and http/https URLs
at runtime. This is defence in depth, not the guarantee: java.nio.channels
cannot be intercepted after startup and native code is out of reach. The
About screen lists both gaps rather than implying total coverage.The scanner is positive-controlled, because a broken scanner and a clean codebase produce identical output:
$ gradlew :desktop:assertNoNetworkBytecode -PblanktickNetworkGateSelfTest
> Task :desktop:assertNoNetworkBytecode FAILED
com/blanktick/desktop/NoNetwork$BlockedSocketImpl.class -> java/net/Socket, java/net/InetAddress
If that passes, the gate is dead and its silence means nothing.
| Component | State |
|---|---|
core/ — scoring engine, rules, filters, URL analysis, EXIF | Builds. 350 tests, 0 failures. |
app/ — Android, Compose | Builds. 26.6 MB APK produced. 30 tests, 0 failures. |
desktop/ — Compose Multiplatform | Builds and runs. Blanktick.exe produced. 77 tests, 0 failures. |
| Windows collector | Runs on real hardware. 70 of 92 checks answered on the dev machine, 0 not checkable, 22 that do not apply to it (re-measured 2026-11-03 on the packaged 0.1.3 build). |
| macOS collector | Written, never executed. No Mac available. |
| Linux collector | Written, exercised only under WSL. Not a real desktop session. |
| Intel bundle pipeline (Python → Kotlin ×2) | Working. Cross-language parity proven. |
web/ — marketing site + live link checker | Working. 30/30 logic parity tests. |
design/ — tokens, interactive prototype | Working. |
ios/BlanktickCore/ — Swift mirror | Written, not compiled. No Swift toolchain on Windows. |
457 tests across the three JVM modules, 0 failures. core (350) and desktop (77) re-run on 2026-11-03 for the 0.1.3 release; the Android app (30) was last run with gradlew check on 2026-09-25.
Honest caveats. The Swift sources mirror the Kotlin line for line and pin the
identical hash vectors, but have never been through a compiler — a reviewed
draft, not working code. The macOS collector is in the same position: it
compiles, its parsers are tested against captured output, and no one has watched
it run on real hardware. Both fail safe rather than fail silent: every query
returns null on anything unexpected, so an untested guess produces "not
checkable", never a green tick.
The intel bundle currently shipping is synthetic placeholder data
(synthetic=true in manifest.txt). Both apps detect this and say so on screen
rather than presenting meaningless password and link verdicts as findings.
Your whole PC. Scan whole PC hands every fixed and removable drive, from
its root, to Microsoft Defender's engine (MpCmdRun -Scan -ScanType 3 -DisableRemediation): every file, reported, nothing quarantined. It is separate
from the score because a full drive takes 30 minutes to hours. Without Defender
it says nothing was scanned rather than calling the PC clean.
92 checks in total. Coverage per platform, measured by PlatformCoverageTest
rather than estimated:
| Platform | Eligible | Run on an idealised device | Not checkable |
|---|---|---|---|
| Android | 29 | 29 | 63 (rules with no Android equivalent) |
| iPhone | 15 | 12 | 80 |
| Desktop | 75 | 74 | 18 |
Those are fixture numbers — a device that answers every question it can. A real machine answers fewer. On the development laptop (Windows 11 Home, standard user, no elevation) the packaged 0.1.3 build ran 70 of 92, with 0 not checkable and 22 that do not apply to that computer — 18 written for a phone, plus 4 verified with a reason (such as macOS-only SIP, Credential Guard on a Home edition, or no USB drive plugged in). Measured 2026-11-03. (The earlier measurement, 50 of 81 with 13 unanswered, came from probes looking in the wrong place on Windows 11.) The dashboard states both numbers and separates the two causes, because "permanent" and "might change next scan" are not the same fact.
The asymmetry is real and every app says so on screen — listing what it could not look at — rather than showing ticks in every column.
Highest-value, and impossible on iOS:
com.whatsapp but signed with a
different key is not that app. Detected against a bundled registry of genuine
signing certificates — no server has an advantage here, and cloud scanners
routinely miss it because they match file hashes, which a repacker changes for
free.Desktop only — 63 rules that have no phone equivalent:
Offline network anomalies (new in 0.1.3), read from this PC alone, nothing sent anywhere: a second device answering for your router's address (ARP impersonation), hosts-file entries that redirect real sites, a look-alike Wi-Fi network with your network's name (evil twin), and a proxy auto-config script.
Host firewall, per profile. The common failure is not "firewall off", it is "Public profile off since that printer thing", which disarms it precisely when the laptop leaves the house.
Services listening on every interface, with the ports the OS always binds (SMB, mDNS) excluded — a rule that fires on every machine is a rule people learn to dismiss.
Inbound remote control (RDP, SSH, Screen Sharing), scored lower when it is hardened, because a considered choice is not an accident.
Real-time malware protection and definition age, attributed to whichever product is actually active rather than assuming Defender.
Secure Boot, SIP on macOS, automatic updates, update staleness.
Accounts: passwordless sign-in (critical), the guest account, and whether your everyday account holds administrator rights.
Programs that start themselves, read from twelve places: the Run and
RunOnce keys (per-user, machine, and the 32-bit views of both), the Startup
folders, Winlogon's Shell and Userinit, Image File Execution Options
debugger hijacks, scheduled tasks, auto-start services outside the system
directories, WMI event subscriptions, COM registrations, AppInit DLLs, and
Active Setup. Reported as unsigned only when the platform positively says so —
an unverifiable signature is not an unsigned one, and a binary inside a
Store package carries the package's signature rather than its own.
Each source reports its own coverage. If one cannot be read — several Image File Execution Options subkeys are ACL'd against a normal user, which is ordinary — the app names it rather than quietly returning a shorter list. And the finding only ever says "starts automatically", never "this is everything that does": persistence has more corners than any fixed list closes.
Removable media. Two things about a USB stick are answerable offline and Blanktick checks exactly those: whether the AutoRun policy has been explicitly weakened from the Windows default (absent means hardened — Microsoft turned autorun off for removable drives in 2011, so a rule that warned about plain AutoPlay would fire on every machine alive), and whether a drive that is attached right now is encrypted. Nothing plugged in reports as , never as a pass. It also shows every drive and phone the computer still remembers — not a finding, never scored, just your machine's memory of you.
Everywhere: screen-lock strength, disk encryption (named per OS — BitLocker, FileVault, LUKS), lock timeout, breached and reused passwords, photo GPS metadata, extra certificate authorities, DNS and proxy inspection, and an offline phishing-link checker.
core/ Pure Kotlin/JVM · no I/O · no Android · no network
model/ DeviceSnapshot, DesktopFacts, Finding, Severity, Category
scoring/ ScoringEngine + ScoringPolicy (the normative one)
rules/ 92 rules, stable IDs, platform-gated
filters/ BloomFilter, SortedHashSet64, Hashing
analysis/ UrlAnalyzer, Punycode, Confusables, PublicSuffix, ExifGps
app/ Android · Compose · collectors only
desktop/ Compose Multiplatform · Windows/macOS/Linux collectors
collect/ Shell, WindowsProbe (one readable script), 3 collectors
NoNetwork.kt Runtime socket + URL blocks, with their gaps documented
ios/BlanktickCore/ Swift mirror — same rule IDs, same vectors
design/ tokens.json (source of truth) + interactive prototype
web/ Marketing site with a live, offline link checker
tools/ Python, build-time only — bundle builder, token codegen
docs/ Kickoff panel, ADR-002 (offline), design panel
null contractEvery observable field on DeviceSnapshot is nullable, and null means "this
platform cannot observe this" — never false, never a guess. A rule whose
inputs are null returns NotApplicable and is shown to the user as not
checkable, never as a passing check.
That one convention is what stops the iPhone build from displaying green ticks
for things iOS is incapable of inspecting. It is enforced by tests
(NullContractTest, DesktopRulesTest), not by discipline.
It earned its keep during the desktop build. Half the Windows queries in the first version were returning nothing because of a shell-quoting bug — and the app dutifully reported seventeen checks as "not checkable" instead of inventing answers. The bug cost coverage. It could not cost correctness.
BaseRule defaults to the two mobile platforms. Adding Platform.DESKTOP to the
enum therefore enrolled no existing rule automatically; each of the 59
desktop-only rules had to opt in by name, and
PlatformCoverageTest asserts that the Android and iOS numbers did not move.
| Data | Structure | Why |
|---|---|---|
| 2M breached passwords | Bloom filter, p=0.1%, 3.4 MiB | Its only error is a false positive — telling someone to change a safe password. Annoying, harmless. False negatives are impossible, so a breached password can never be reported as safe. |
| 2M blocked domains | Exact sorted u64 + prefix index, 15.3 MiB | A false positive blocks a site the user needs. The feature looks broken, they switch it off, and lose all its protection. There is no safe direction to be wrong in. |
Every point traces to one finding, per-finding integers sum exactly to
100 − score (largest-remainder apportionment, so the column on screen really
adds up), categories are capped so one bad area cannot dominate, and repeat
findings decay geometrically so ten small issues never outweigh one serious one.
Requires JDK 17 and the Android SDK (platform 35, build-tools 35).
# 1. Generate design tokens for every platform
python tools/gen_tokens.py
# 2. Build the intel bundle. --demo makes a small synthetic one;
# supply real corpora for a shipping build.
python tools/build_intel.py --demo
python tools/build_intel.py --passwords pwned-top2m.txt --domains hosts.txt
# 3. Build and test everything, including both network gates
gradlew check
# 4. Android APK
gradlew :app:assembleDebug
# 5. Desktop app
gradlew :desktop:run # run it
gradlew :desktop:createDistributable # native app + bundled JRE
gradlew :desktop:packageMsi # or packageDmg / packageDeb
On a machine where JAVA_HOME points at a JDK older than 17 (Gradle 9 needs
17+), set it for the invocation rather than globally:
JAVA_HOME="/c/Program Files/Eclipse Adoptium/jdk-17.0.20.8-hotspot" ./gradlew check
Bundle sizing is a flag, not an architecture decision:
python tools/build_intel.py --password-limit 10000000 --domain-limit 4000000
The default is 2M/2M (~20 MiB). Breached-password reuse is brutally long-tailed, so the top 2M covers essentially every real case; 10M costs 14 extra MiB, does nothing about the actual limitation (freshness), and makes the install heavier for people on expensive mobile data.
tools/seeds/signers-seed.txt ships empty on purpose. A wrong entry there
tells someone their real banking app is malware. Populate it mechanically:
python tools/extract_signer.py /path/to/genuine.apk >> tools/seeds/signers-seed.txt
python tools/extract_signer.py --from-device com.whatsapp com.android.chrome
With no entries, APP-CLONE-001 reports not checkable — the correct behaviour
for a check we have no data to run.
The desktop build wrote nothing to disk until Settings existed — no config,
no cache, no history. Settings spends part of that deliberately, and is bounded
by rule: settings.conf may hold UI preferences and nothing else. No scan
results, no scores, no findings, no machine identifiers. The Settings screen
prints the file's full path and its entire contents, because "nothing leaves
this computer" was never the same claim as "nothing is written" and the
difference should be visible rather than argued.
The one exception is scan history (history.jsonl, beside settings.conf),
which exists so an MCP client can ask about past scans. It is off by default,
has its own switch and a Delete button on the Settings screen, and stores rule
outcomes only — never finding details, evidence or paths. The Settings screen
previously said "the only file Blanktick writes … no history" while a history
switch existed in the file below it; it now states both files and whether
history is on.
It also carries the Reduce motion switch, which exists because Compose Desktop exposes no API for the OS preference — verified against the toolkit and against Windows itself — so a manual switch is the only way to honour DD-10 at all.
The desktop build ships two modes whose only purpose is to let you check it:
Blanktick --script # prints the exact PowerShell it runs on your machine
Blanktick --probe # prints every field it read, including the nulls
--script output is one readable block you can paste into a terminal and
compare against what the app displayed. WindowsProbeTest asserts that the
script contains no mutating cmdlet, no network cmdlet, and no cmdlet needing
elevation — Blanktick reports, you decide and act. It never changes a setting.
--probe is how a "not checkable" is diagnosed: a field printed as null is
either an honest platform limit or a collector bug, and this is how the two are
told apart.
Do not use powershell -EncodedCommand. It solves the argument-quoting
problem perfectly and gets the entire application killed by Microsoft Defender:
spawning encoded PowerShell is behaviour signature Behavior:Win32/PShellEnc.A,
and Defender terminates the parent process silently with exit code 0. Which is
fair. Base64ed PowerShell issued by another program is a malware technique, and
a security product has no business using one. The script goes in a temp file and
runs with -File.
Do not list Cert:\CurrentUser\Root and call it "user-installed". Windows
mirrors the machine root store into every user, so that query returned 52
certificates on the development machine — all legitimate — and the app would
have reported 52 critical TLS-interception findings on a healthy computer. The
collector now reports the difference between the user and machine stores.
Machine-wide interception certificates are consequently not detected on
Windows in this build; that gap needs a bundled list of Microsoft root
thumbprints and is stated in the About screen rather than papered over.
Python writes the intel bundle. Kotlin reads it on Android. Swift reads it on iOS. All three implement one specification:
h1(x) = splitmix64( fnv1a64(utf8(x), OFFSET_A) )
h2(x) = splitmix64( fnv1a64(utf8(x), OFFSET_B) ^ 0xD6E8FEB86659FD93 )
A one-bit divergence in any of them does not crash. It silently returns wrong membership answers — and for the password filter, "silently wrong" means telling someone a compromised password is safe.
So the agreement is tested two ways:
shared/hash-vectors.json, generated by
tools/gen_hash_vectors.py) asserted identically in HashVectorsTest.kt and
HashParityTests.swift. The 🔒emoji vector is the important one: it is a
surrogate pair in UTF-16, so an implementation that hashed UTF-16 code units
instead of UTF-8 bytes fails on that line and passes every other.IntelBundleParityTest.kt): Kotlin opens the file
Python wrote and looks up values Python inserted.If these fail, do not "fix" the test. Find out which implementation moved.
python -m http.server 8910
?screen=ios, ?screen=ledger, ?theme=dark.node web/verify.mjs # 33 tests: the site's checker matches UrlAnalyzer.kt
Stated here because the app says the same thing on screen:
bit.ly/… is reported unknown, never safe.ACCESS_NETWORK_STATE is on the
forbidden-permission list, so NET-WIFI-001, NET-PROXY-001, NET-VPN-001
and NET-DNS-001 report not checkable on the phone. The desktop build does
run them. This is a real cost of the permission policy and is written down in
AndroidCollector.kt rather than left to be rediscovered.Passing every check does not mean you are safe. It means these particular problems are not present. The app says that too.
| File | What it is |
|---|---|
docs/kickoff-meeting-2026-08-28.md | Cross-functional panel; decisions D-01…D-12 |
docs/architecture-offline.md | ADR-002 — the zero-network architecture |
docs/architecture-desktop.md | ADR-003 — the desktop build; D-13…D-15 |
docs/design-meeting-2026-08-28.md | Design panel; decisions DD-01…DD-13 |
docs/design-meeting-2026-08-29.md | Desktop dashboard panel; DD-14…DD-20, and what the shipped code was not delivering |
Blanktick speaks MCP over stdio, so any model with
an MCP client can ask about this computer and get real answers rather than
guesses: Blanktick.exe --mcp. Eight tools, all read-only — a scan, the raw facts
including the nulls, the exact script it runs, its coverage on this platform,
three that query the stored scan history, and one that reviews an exported
network capture. docs/mcp.md has the full table, and there is a
one-minute video of the setup.
Claude Desktop users can install the one-click extension (tools/build-mcpb.sh
builds Blanktick-0.1.3.mcpb). In Claude Code:
/plugin install blanktick --marketplace opemaid/blanktick
Stdio, not HTTP: your client launches Blanktick and talks to it over standard input and output. No socket is opened and the bytecode gate that forbids networking code still passes. And every tool is a question — nothing there fixes, removes, disables or quarantines anything, which is the same promise the app has made since its first commit and is enforced by a test.
Setup and the reasoning: docs/mcp.md.
Programs pretending to be Windows. A real svchost.exe lives in the
system folder. Anything else with that name, running out of your personal
folders, is not a borderline case — there is no innocent reason to do it.
Blanktick checks the programs running right now against a per-binary table of where
each one actually belongs. That table has to be per binary: a single "must be
in System32" rule reports explorer.exe on every Windows machine alive,
because Explorer genuinely lives in C:\Windows.
This is the one part of Blanktick that looks for malware, and it is worth being precise about what it means. It carries no signatures of its own — that is the antivirus you already have, and it needs a server Blanktick does not talk to. (Scan whole PC is the exception that proves it: every file on every drive is read by Defender's engine, not ours.) What it detects is a technique, which is a property of your machine rather than a fact someone else has to tell you about a file. A dormant installer sitting in a downloads folder will not be found here, and nothing in this section should be read as "your computer is clean".
Roughly a third of running processes will not reveal their path to a program without administrator rights — 179 of them on the development machine. That number is shown, because "I checked everything" would not be true.
Which services are actually reachable — asked of the firewall, not guessed. "25 things are listening on every interface" is true on a stock Windows machine and tells you almost nothing, because Windows blocks inbound by default. The firewall knows which programs it lets through, so Blanktick asks it: on the development machine, 2 of 25 — and both were the developer's own web servers. The old check called that "17 services reachable from the whole network". Sockets whose owning program cannot be identified are counted and reported as unattributed rather than assumed either way.
Certificate authorities the whole computer trusts that Windows did not install. This was previously a documented blind spot: telling Microsoft's roots from an injected one looked like it needed a bundled list of thumbprints. It does not — Windows already records which roots it delivered, and when each one was written. A root that appeared after the OS was installed, did not come through Microsoft's update channel, and was not deployed by workplace policy was put there by somebody.
Updates waiting to install, without asking Microsoft. Also previously refused, because enumerating pending updates means the Windows Update Agent and the Agent contacts Microsoft. It does not have to: the Agent keeps a local catalogue of what it already knows applies to this machine, and it can be searched offline. A test asserts the offline flag can never be dropped.
The verdict of the antivirus you already have. Windows ships a scanner whose signatures are hours old, and it is already installed. Blanktick asks it about the sixty-odd files it has identified as worth asking about — the programs that start themselves and the ones running from personal folders — and reports what it says.
This is the useful division of labour. Real-time protection checks files as they are written and opened; a file that arrived before its signature existed can sit on disk unflagged until something touches it, and the full scan that would find it is the one nobody runs. Blanktick contributes the shortlist, not the verdict. Measured at 33 milliseconds a file.
The scan is requested with remediation disabled, so nothing is quarantined or moved: without that flag the scanner deletes what it finds, and Blanktick would become a program that silently changes your computer as a side effect of asking a question. A test asserts the flag can never be dropped.
One honest caveat, because it touches the central claim: Blanktick still makes no network connection. It asks a component that is already running and already scanning these files. That component then behaves as it always does, which — depending on your own cloud-protection setting — may include contacting Microsoft. "We never touch the network" and "we never cause anything to touch the network" are different claims, and only the first is true.
A bundled list of known-malicious files. The closest thing here to conventional antivirus, and worth being exact about. Blanktick ships a table of SHA-256 hashes and compares it against the programs that start themselves and the ones running from your personal folders — about sixty files. The whole disk is Scan whole PC, which hands every drive to Defender instead.
It is stale the day it is built, it will never approach a real scanner, and it is defeated by recompiling the file: one changed byte, different hash. It earns its place because it costs about eight bytes an entry and catches the commodity case — a file that has been sitting unchanged on a disk since somebody else already identified it.
The table is an exact sorted set rather than a Bloom filter, unlike the password corpus. A false positive there means "change a password that was fine"; a false positive here tells someone a legitimate program on their computer is malware, which is the one output this product must never produce by accident.
It ships containing the EICAR test signature — a 68-byte string every scanner
has recognised since 1991, and not malware — so the feature can be proven to
work by anyone, on any machine, with nothing dangerous on disk. To load a real
corpus: python tools/build_intel.py --malware hashes.txt, where the file
holds one SHA-256 per line (or CSV with the hash first). Any line that is not
64 hex characters is skipped.
The AI surface — new, and as far as this project can tell, unaudited by anything else on a consumer machine. Two things arrived on ordinary computers in the last couple of years:
A local model server is an HTTP API with no authentication, because it is meant to be reachable only from the machine it runs on. Bound to every interface instead — on office, hotel or café Wi-Fi — anyone who scans the subnet can use your hardware and read whatever the models are handling. Blanktick matches on the program rather than the port, because people move these to other ports and a port list would flag whatever else was on 8080.
A tool configuration is a plain JSON file naming programs a language model is allowed to run. That is the more interesting one: an entry in it executes commands, and it appears in no Run key, no scheduled task and no service — so every autorun checker ever written looks straight past it, including the twelve-source sweep above. Blanktick does not judge whether the tools are appropriate; you chose them. It reports what was granted, because hardly anyone has reread that file since the day they pasted something into it.
Also: API keys sitting in plain text in those files (counted, never read — the same rule the auto-logon password follows), and Windows Recall keeping a searchable record of your screen. Recall reports as not checkable on hardware that does not have it, which is most machines, rather than passing.
Machine hardening: User Account Control, whether sign-in credentials are left readable in memory, SMBv1, LLMNR, remote-administration services, and whether an auto-logon password is sitting in the registry in cleartext. Blanktick never reads that password — only whether one exists. An app that copied a stored credential into its own report would have made the problem worse in the course of describing it.
An audit of the antivirus you already have. Blanktick is not an antivirus and cannot become one: no network means no reputation lookup, and it has no file scanner. What it can do is check whether the scanner already installed has been quietly switched off in part — a disabled behaviour monitor, tamper protection off, or a threat the product found and never resolved. Malware disables one component rather than the whole suite, because the whole suite going dark gets noticed, and from the outside a partly-disabled antivirus looks exactly like a working one.
Installed software, read from the OS's own uninstall registry. Two things are checkable offline and Blanktick checks exactly those: software past its vendor's security support (matched against a catalogue of products whose EOL has already happened and is final, so the list can go stale by becoming incomplete but never by becoming wrong), and software installed somewhere it needed no permission to reach while naming no publisher. Neither half is a finding alone — measured on the development machine, 11 programs live in user-writable folders and all 11 name a publisher, so this fires zero times there while a naive "installed under AppData" rule would fire seven.