Skip to content

docs: which models an installation can run is its own answer - #667

Merged
JArmandoAnaya merged 4 commits into
mainfrom
docs/provider-contract
Aug 18, 2026
Merged

docs: which models an installation can run is its own answer#667
JArmandoAnaya merged 4 commits into
mainfrom
docs/provider-contract

Conversation

@JArmandoAnaya

@JArmandoAnaya JArmandoAnaya commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Four pages under docs/ still described the set of model families VisionSet can run as a
property of the release. It has been a property of the installation since drivers began
arriving through the visionset.providers entry-point group, and this brings the documentation
to that. It also adds the page a driver author needs, which is the last piece of the provider
contract and plugin architecture epic (#498) — the four slices before it shipped the two ports
and discovery, the three in-tree drivers migrated onto the contract, the conformance suite, and
the server-supplied catalog.

What was false, and what is true instead

docs/inference.md carried a capability table whose third column named the families answering
each capability — "the SAM 2 and SAM 3 families", "the grounding-dino family" — as though the
release decided them. That column is gone, and a paragraph beneath the table says the capability
vocabulary is closed while the set of models answering to it is not, naming what this
distribution's own drivers serve as an illustration rather than as the definition. Two paragraphs
further down, an empty capabilities was explained partly by a config having "declared one this
build has no adapter for"; it now says no installed driver serves it. That sentence wrapped
across a line break, which is why a phrase grep never found it.

INFERENCE_CONNECTION_NOT_RUNNABLE is raised for two unrelated reasons and both error tables
described only one of them. provider_for raises it for an http connection, which is a fact
about the build and remains true as written; _local raises it through _no_adapter_for when no
installed driver serves the family the downloaded config declares, which is a fact about the
installation and changes the moment somebody installs a driver. The rows in docs/inference.md
and docs/api.md now name both, and docs/api.md's own paragraph on an empty capabilities
takes the same correction.

docs/architecture/backend/inference.md still pointed at inferenceCatalog.ts for the curated
entries and still said each records a download size. Neither survived the served catalog: the
entries are CuratedModel tuples on each driver's curated member, the server hands the whole
installed set over GET /inference/providers, and CuratedModel carries no size at all, because
what a download costs is read live for the exact pair while somebody is still deciding. That page
and docs/architecture/backend/wire.md each also described a model_type set as something "this
build serves"; both now say the installation.

The new page

docs/architecture/backend/providers.md covers the two protocols, the entry-point group, the
packaging pin, the trust that installing a driver asks for, and the conformance suite a driver
has to pass. It opens by stating that it is not a public extension API in this release and may
change without notice or a migration path: this epic's own body puts the stable contract and its
publication under "Later", so a page describing the contract is allowed where a page announcing
an extension API would not be.

Two things it states that an author cannot work out alone. A prerelease floor is mandatory while
this project is pre-1.0 — 0.0.1b2 sorts before 0.0.1, so an ordinary-looking
visionset>=0.0.1 excludes the very build the plugin targets, and the compatibility backstop
skips the driver with a sentence naming both versions; the pin has to be >=0.0.1b1. And
installing a provider is trusting its author with code execution in the server process and in
every worker, exactly as installing any pip package is.

It sits in the architecture tree rather than among the behavioural pages because that is where
plugin-declaration guidance already lives — architecture/backend/formats.md documents what an
exporter plugin declares — and because docs/README.md describes the architecture tree as the
map and the pages beside it as the behavioural reference.

Its sidebar entry is in the same commit as the page, which is not tidiness.
tests/scripts/docs_sidebar.test.mjs holds every tracked document under docs/ to
docs-site/src/sidebar.mjs, and that gate runs inside the frontend group — so a page added
without its entry reddens a check that reads as having nothing to do with documentation. The gate
was confirmed to fail on the page before the entry was added, and to pass after.

Test plan

bash scripts/check.sh — exit 0, PASSED ran=python,frontend,generated,browser skipped=docs.

==> python tests            3772 passed, 24 skipped in 46.48s
==> ruff (lint)             All checks passed!
==> ruff (format)
==> mypy
==> import contracts
==> frontend build
==> frontend tests          annotator  37 files, 1061 tests passed
                            ui-core    52 files, 1099 tests passed
==> frontend lint
==> openapi drift
==> generated client drift
==> mcp tool reference drift
==> version sync
==> annotator + app e2e (chromium)          277 passed (1.2m)
==> browser cycle, real server (chromium)     1 passed (26.3s)

bash scripts/check.sh docs — exit 0, the opt-in group the default run skips and the one that
actually reads what this branch wrote:

==> docs site build
==> docs projection is deterministic
==> docs site internal links
check.sh: PASSED  ran=docs  skipped=python,frontend,generated,browser

The second half of the inference matrix — uv sync --locked --extra local-inference with
VISIONSET_REQUIRE_LOCAL_INFERENCE=1 — was not run, and it is named here rather than left to
inference: no Python changed on this branch, so no test behaves differently between the two halves
of that matrix. The CI inference smoke job covers it either way.

Beyond the gates, each claim the new page makes about the code was checked against the source
rather than against the plan that proposed it: the entry-point group and pinned distribution name
in inference/registry.py, the >=0.0.1b1 floor in _incompatible, the committed VERSION, both
ModelCapability members, the 40-character commit rule on CuratedModel, the contested-family
refusal, and the two discovery timings. The four documentation pages were then read end to end.

The built site was then driven in a real browser, because the gates prove that links resolve
and that the projection is deterministic — not that a page renders. Against astro preview over
docs-site/dist:

  • The new page serves at /architecture/backend/providers/ with Writing a provider as its
    title, taken from the # H1 as every other page's is.
  • Its sidebar entry appears in the Backend group between inference and formats, and the
    previous/next pair chains inferenceprovidersformats.
  • Both member tables render as tables, the TOML, Python and shell blocks render as highlighted
    code with their language labels, and every source reference resolves to a GitHub blob link.
  • The reduced capability table on /inference/ renders with its two columns and no loose
    | --- | anywhere on the page, which is what a malformed table would leave behind.
  • Each corrected sentence is present in the rendered text of all four pages and each stale one is
    absent. The one phrase that survives — "the SAM 2 and SAM 3 families" — is in the new
    illustrative sentence and in no table cell, which was confirmed rather than assumed.
  • The new page logs no console errors. The single error on /architecture/backend/inference/ is
    pre-existing and unrelated: it appears identically on /architecture/backend/jobs/, which this
    branch does not touch, and both are pages carrying a mermaid diagram.

Found, not fixed

installed() cannot report two drivers claiming one provider_id. The second silently replaces
the first in the returned mapping, and no registration comes back as skipped, so the condition is
invisible to anyone reading a discovery result. The conformance suite characterises this rather
than fixing it.

Four geometry schemas — BboxGeometry, PolygonGeometry, PolylineGeometry and
ClassificationGeometry, reachable only from SuggestedRegion — publish
additionalProperties: false from a response body, which contradicts the generated client's
deliberate tolerance of unknown keys on a response. Pre-existing, unfiled, and untouched here.

A note for whoever rebases next

The capability table this branch reshapes in docs/inference.md is also being edited by in-flight
work on batch pre-labeling (#425), which adds a Consumed by column to the four-column shape. The
resolution that keeps both is to carry that new column onto the two-column table this branch
leaves behind; restoring the Families column would put back the claim removed here.

Closes #498

@JArmandoAnaya
JArmandoAnaya merged commit a201546 into main Aug 18, 2026
15 checks passed
@JArmandoAnaya
JArmandoAnaya deleted the docs/provider-contract branch August 18, 2026 04:26
JArmandoAnaya added a commit that referenced this pull request Aug 21, 2026
* docs(inference): which families answer a capability is the installation's answer

* docs: the not-runnable refusal names both things nothing here runs

* docs(architecture): a curated entry is the driver's declaration, and carries no size

* docs(architecture): what a provider declares, and what it must prove
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Open providers over closed capabilities: the provider contract and plugin architecture

1 participant