hank-model-authority
The model authority every product repository reads: which models exist (registry entries with their execution identity and per-family request facts), which model each capability uses (selection policy), and what each model costs (rate tables). The distribution depends on PyYAML and pydantic only, so Risk, Investment and Edgar take it without the gateway.
Design and rollout: docs/design/model-authority-registry-as-data-artifact-design-2026-09-29.md
and its implementation plan.
Layout
| Module | Owns |
|---|---|
authority/model-authority.yaml, authority/rates/*.json |
the packaged artifact: one model-authority/2.x document (registry models, selection.capabilities, one revision) and per-provider prices |
schema.py |
the version rule (SCHEMA_MAJOR/SCHEMA_MINOR), ModelAuthorityError and its message, protocol families and each family's compat: key set |
loader.py |
HANK_MODEL_AUTHORITY_DIR resolution, the strict load, the directory digest |
current.py |
the process's one import-time load: INITIAL_MODEL_REGISTRY, INITIAL_MODEL_SELECTION_POLICY, RATE_TABLES, HEALTH_FACT, health_fact() |
registry.py, selection.py |
registry entries and selection policy |
capabilities.py |
capability IDs and the process that executes each (a release, not data) |
binding.py, bind.py |
the single resolver and CapabilityBind |
rates.py, thinking.py |
rate tables; effort vocabulary |
The package root imports types and the loader, never current, so
python -m model_authority check <dir> can check a candidate directory while the
host directory is broken.
Which directory a process loads
HANK_MODEL_AUTHORITY_DIR set: that directory, resolved once at start; missing or
unreadable fails the start. Unset: the packaged authority/ directory. Every
loading unit sets it — /etc/hank/model-authority in production,
~/.config/hank/model-authority on this Mac — so the packaged copy is what tests
and unwired tools load. Every process reports what it admitted through
health_fact(): {"revision", "schema", "sha256", "source", "loader", "admits"};
source is the resolved release path (…/model-authority.d/<revision>-<sha12>/…)
or packaged:<path>.
Schema
This loader implements model-authority/2.1 and admits 2.0 and 2.1 artifacts
(health_fact()["admits"] is model-authority/2.0-2.1). Each entry's compat:
key set is its protocol family's (schema.py, design §4d). 2.1 adds two
anthropic.messages keys, each derived when absent so 2.0 artifacts load
unchanged, and each refused when it contradicts the 2.0 key it refines:
| Key | Values | Absent | Must agree with |
|---|---|---|---|
thinking.off_value |
disabled, between_tools, null (cannot be turned off) |
disabled if can_disable, else null |
can_disable is true exactly when off_value is disabled |
tool_choice_forcing |
any, thinking_off_only, never |
thinking_off_only if forced_tool_choice_requires_thinking_off, else any |
that flag is false exactly when forcing is any |
The 2.0 keys stay required (a minor removes nothing), so an adapter that still
reads can_disable or forced_tool_choice_requires_thinking_off keeps working;
the gateway's Anthropic adapter reads both new keys. Sonnet 5.5 uses
can_disable: false, off_value: between_tools: the legacy bool still means
whether the literal thinking.type: disabled is legal.
Changing it
- A data change (a model, a default, a price, a compat value) edits
authority/and ships byscripts/deploy_model_authority.sh, not by a release (runbook). Declare the lowest schema minor that covers the fields the artifact uses. - A schema change is a release: a new optional field or literal is a minor
(
SCHEMA_MINOR), a removal or redefinition a major. Deploy loaders before data that uses a new minor: a loader refuses an artifact whose minor is newer than its own, naming both. - A capability or its executing process is a release (
capabilities.py).
Check a candidate directory with the ordinary load:
python -m model_authority check <dir> # prints the health fact, or exits 1 with the refusal
Tests: .venv/bin/python3 -m pytest packages/model-authority/tests -q
(make test-area AREA=model_authority).
Metadata
Release files for hank-model-authority 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hank_model_authority-1.2.0.tar.gz | 51.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hank_model_authority-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 92.0 kB