An audit read the code and found the proposal that specifies it. Go reaches
all 122 capability proposals and 64 of the 121 other Standards Track ones;
Rust has 35, mostly the operator and the CLI; C++ has three, because the
complete original C++ in the estate is a ZAP handler, a bot nothing specifies,
and authored kernels inside forked CUDA and Metal crates.
| | shipped | partial | none | not assessed |
| Go | 146 | 33 | 1 | 80 |
| C++ | 1 | 2 | 0 | 257 |
| Rust | 10 | 25 | 1 | 224 |
The large "not assessed" columns are the point rather than a gap. The model and
training specs are Python, the frontend and design-system proposals are
TypeScript, and recording `none` against those would read as a search that
came up empty when the honest statement is that the runtime was never the
question. Governance, Meta and Process are not graded at all.
Six proposals are Final with nothing found in Go and are left unwritten rather
than demoted: 0065, 0089, 0098, 0103, 0521 and 0902. HIP-0521 answers itself,
its own section reading "Not yet implemented". Three of the others name a
canonical Go file in consensus/protocol/auth that nobody wrote, in a package
where the four neighbouring proposals' files all exist with tests beside them.
Co-authored-by: Hanzo Dev <[email protected]>
6.7 KiB
hip, title, author, type, category, capability, status, implementation-go, created, requires
| hip | title | author | type | category | capability | status | implementation-go | created | requires |
|---|---|---|---|---|---|---|---|---|---|
| 1262 | Reference — Lookup Sets | Hanzo AI | Standards Track | Application | reference | Final | shipped | 2026-08-20 | HIP-0026, HIP-0106, HIP-0139 |
HIP-1262: Reference — Lookup Sets
Abstract
/v1/reference is the lookup data a risk decision needs but cannot derive:
which email domains hand out throwaway inboxes, which addresses belong to a
datacentre or a Tor exit, which card scheme an issuer prefix belongs to, which
browsers the fleet sees everywhere, and how current the designation lists the
screening engine holds actually are (apps/reference/reference.go:15-19). It is
implemented in hanzoai/cloud at apps/reference. This HIP is where HIP-1046
§8's subtree now lives; HIP-1046 keeps the cross-plane invariants.
Motivation
Every one of these facts could be hard-coded where it is consulted, and each copy would go stale on its own schedule with nobody noticing — a designation list that answers "not listed" because it was never loaded is indistinguishable from a clean world. Making the lookup a capability puts freshness on the wire and makes staleness a reported condition rather than a silent one.
Specification
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.
Two stores, one precedence
The Hanzo-maintained BASELINE lives in the shared warehouse —
hanzo.reference_source and hanzo.reference_entry, tables with NO tenant
column at all, so a cross-tenant write is unrepresentable rather than merely
forbidden (apps/reference/store.go:47-49). A tenant's OWN allow and deny
entries live in that organization's own SQLite file, opened per organization
through cloud.OrgStore under the name reference
(apps/reference/override.go, apps/reference/reference.go:34-40).
Resolution MUST be override first, then baseline; first hit wins.
Nothing derived from one organization's rows may enter the baseline, ever. The
only fleet-derived set is an aggregate published above a k-anonymity floor no
single organization can reach alone (apps/reference/set.go:297-299).
The address
The capability answers under /v1/reference: the set list at the root, one set
read, written and cleared at /{set} — a SET, which is why the name is singular
— resolve, and refresh (apps/reference/reference.go:507-525). Every
operation is typed. refresh writes the shared baseline every organization
reads and is therefore SuperAdmin only (apps/reference/reference.go:1328-1329);
it MUST stay one operation under this prefix, never an address family of its own. Today's router still serves
this surface under /v1/risk/reference; that pair is carried by
hanzoai/cloud openapi/misfiled.txt and closes by fold.
A version, a refusal, and freshness on the wire
Every set is a VERSION — the content digest of what was taken, so the same
data is the same version whoever fetched it, and a decision records one string
an auditor resolves back to a publisher, a licence and a date. A set that has
never loaded MUST REFUSE rather than answer "not listed"
(apps/reference/resolve.go:157), and a set whose source needs a licence we do
not hold is declared as a seam that refuses (apps/reference/set.go:93-95).
Freshness rides every answer: the version, when its oldest contributing
publisher was current — the oldest, because a set is exactly as fresh as its
weakest source (apps/reference/resolve.go:71-73) — how old that is, and
whether it is past bound. A stale set still answers, and says that it did.
Tenant, meter, events, observability, stage
Reads and override writes resolve the organization from the validated
principal (apps/reference/reference.go:549) and a request without one is
refused; the baseline is readable by every validated org and writable by none
of them. The capability is free, in those words
(plugin/reference/main.go:21, Price: cloud.Free). It publishes no events on
the bus. Beyond the request span it registers nothing; staleness and refusal —
the two ways this plane can be quietly wrong — are reported on the wire rather
than in a private metric. Its stage is whatever its manifest row declares —
HIP-0139 §8 keeps that in one place, and the beta this line used to assert had
already drifted from it.
Upstreams
It forks no code; the refusal discipline generalises what luxfi/aml
pkg/reference states (apps/reference/reference.go:25-28). What it MIRRORS
is published data, and the catalog declares each source's licence as a fact
beside its origin (apps/reference/set.go):
disposable-email-domains— CC0-1.0 (set.go:221-223);crawler-user-agents— MIT (set.go:255-257);- the Tor bulk exit list — CC BY 3.0 US (
set.go:242); - the IANA special-purpose address and AS-number registries — the registries of
record (
set.go:243-244,:269-271); - cloud and CDN operators' self-published IP feeds — machine-readable by intent,
no licence stated and none claimed (
set.go:234-241); - issuer prefixes — computed here from ISO/IEC 7812 structural facts; no issuer
database is licensed or held (
set.go:283-285); - sanctions designations — receipt only; they stay with the engine that screens
(
set.go:310-313).
A new source MUST enter through this catalog with its licence basis declared, or as a seam that refuses.
Rationale
The alternative was to file these operations under the model-serving plane, and
an earlier cut did exactly that (manifest/apps.go:231-238): lookup data in a
live product with different customers, where its growth reads as that product's
growth. The other alternative — folding into risk — fails on the store rule:
this capability owns two stores of its own, and the baseline's no-tenant-column
shape is a property risk's per-tenant planes cannot host.
Security Considerations
The baseline is consulted by every organization's decisions, so poisoning it is
the high-value attack: refresh is held to the platform's own identity, a
version is a content digest so a tampered take is a different version by
construction, and nothing an organization sends can reach the baseline tables —
their shape has nowhere for it to go. The override plane is the tenant-side
exposure: a per-org file reached only through the validated principal, so one
organization's allow-list cannot bleed into another's decisions. The remaining
risk is absence — an unloaded, unlicensed or stale set silently passing for a
clean answer — closed by refusing the first two and reporting the third.
References
- HIP-0026 — Identity and Access Management
- HIP-0106 — The Hanzo Plugin Contract
- HIP-0139 — Capability
- HIP-1046 — Risk
Copyright
Released under CC0 1.0 Universal Public Domain Dedication.