BlvkWare.
A registry of identifiers that do not exist, but that models confidently believe do. Check a package name against its registry before anything installs it, and find out whether the name is one that language models invent.
An agent writes pip install requests-oauth2-helper. The name is plausible, the agent is confident, and the package has never existed. Either the install fails and the agent burns a retry loop, or somebody has already registered that name because they watched a model emit it a thousand times.
The second case is called slopsquatting. It is the only supply-chain attack where the attacker's target list is generated for them, for free, by the victims' own tooling.
No account, no key, no signup. One command:
curl https://api.blvkware.dev/hallux/v1/check/pkg.pypi/requests-oauth2-helper
{
"namespace": "pkg.pypi",
"value": "requests-oauth2-helper",
"verdict": "absent",
"confidence": 1,
"evidence": {
"registryStatus": "not_found",
"nearestExisting": [
"requests-oauthlib",
"requests",
"requests-toolbelt"
]
},
"recommendation": "do_not_install",
"successor": "requests-oauthlib"
}
| Verdict | Meaning | What to do |
|---|---|---|
| exists | Present in the authoritative registry now. | Proceed. |
| deprecated | Exists, but retired, yanked or superseded. | Proceed with the replacement given. |
| absent | Not present, and no record of a model inventing it. | Stop. Probably a typo or a private name. |
| phantom | Not present, and models emit it repeatedly. | Stop. A hallucination with a track record. |
| squat | Was a phantom, and somebody has since registered it. | Block. Treat as hostile until proven otherwise. |
| unknown | Registry unreachable, or outside coverage. | Your policy decides. Never read it as permission. |
unknown, with a reason code. That is enforced in the code rather than promised in a document: a registry saying no and a registry not answering are different values of different types, so one cannot be mistaken for the other.
Every registry publishes what it contains. None publishes what it does not, because absence is unbounded. The useful part of absence, the names models actually reach for, can only be accumulated over time by sampling production models and confirming against the registry that the name is not there.
Once the ledger has recorded a name that models keep inventing, the same check carries that history. This is the example from the specification, not a live response:
{
"namespace": "pkg.pypi",
"value": "requests-oauth2-helper",
"verdict": "phantom",
"confidence": 0.97,
"evidence": {
"registryStatus": "not_found",
"attestations": 412,
"observedFrom": ["gpt-class", "claude-class", "llama-class"],
"nearestExisting": ["requests-oauthlib"]
},
"recommendation": "do_not_install",
"successor": "requests-oauthlib"
}
That record is what makes the fourth verdict possible. A name that models invent, that a stranger then registers, is a supply-chain attack visible before the first install. Every other tool looking at that package sees a real package in a real registry and says install it.
How a name becomes a phantom. One attestation is one model, on one prompt class, on one day. A name becomes a phantom at ten attestations from at least two model families, and only after its absence has been independently confirmed twice, at least 24 hours apart, against the authoritative registry. Phantoms with no attestation in 180 days are archived rather than deleted, and still answer.
The method is published in full, because credibility is the product here. The specification carries the verdict semantics, the namespaces, the receipt format and the corpus methodology.
7 namespaces answer today: cite.doi, pkg.crates, pkg.go, pkg.maven, pkg.npm, pkg.nuget, pkg.pypi.
Namespaces named in the specification but not yet live return unknown with a reason, never an error. An agent's control flow does not break when HALLUX grows a namespace, and does not break when it meets one that has not been built.
The batch endpoint takes up to 100 identifiers in one round trip, which is the shape a CI pipeline or an agent framework wants. Responses on a paid tier carry an Ed25519 receipt over the result, so an operator can prove after an incident that the check happened and what it said.
There is also an MCP server exposing the same capability as tools, so a coding agent can check a command before running it without anyone wiring an integration. It answers at https://api.blvkware.dev/hallux/mcp over Streamable HTTP, with no account and no key:
claude mcp add --transport http hallux https://api.blvkware.dev/hallux/mcp
Any other MCP host takes the same address. The tools are hallux_check_command, to call before an install, hallux_check_manifest, after editing a dependency file, and hallux_check for identifiers; hallux_watch is refused until durable storage is configured. Every identifier a tool resolves counts against the open tier, like any other check.
That is not a promise, it is a property. The function that prices a request takes a count of identifiers and has no parameter through which a verdict could reach it, and the test suite resolves the same batch under four different registry states and asserts a single charge.
Only the open tier is available today. The paid tiers and watches below are priced and documented, but no payment rail is connected yet, so none of them can be bought. The open tier needs no account and no key.
| Tier | Who it is for | Price |
|---|---|---|
| Open | Any agent or developer, with no account | Free, 500 identifiers a day |
| Metered | An individual agent or a small team | $0.0008 per identifier |
| Team | A company putting it in CI | $299/month or $2,990/year |
| Feed | Registries, IDE vendors, CI platforms, security vendors | $1,500/month or $15,000/year |
| Embedded | A platform shipping it inside its own product | from $2,500/month |
The open tier is 500 identifiers a day for each client, and all free traffic together draws from one pool of 50,000 a day. The pool is what keeps a free tier with no account honest: nobody can make it bigger by pretending to be many clients. Paid traffic never touches it, and the limits page says how both are reported.
Metered spend stops at the Team price. Above 373,750 identifiers in a calendar month the account moves to Team and is no longer metered. A build pipeline asks about the same few thousand established packages all day, those answers cost nothing to serve, and an invoice made of them would read as a tax on doing the right thing.
Watches are $0.02 per watched identifier per month, 100 included on Team and unlimited on Feed. They are priced on what you chose to watch, never on whether one fired. An annual commitment is twelve months charged as ten.
Machine-readable prices, identical to the numbers above and generated from the same source, are at /hallux/v1/pricing and in the agent catalog.
HALLUX folds in pkgguard, an open-source package security gate you can run in front of your own package manager, and takes its supply of observations from slopbench, which measures how often a model names a dependency that no package answers to. Both are Apache 2.0 and free to use on their own.