Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@

All notable changes to traust-contracts are documented here.

## [0.63.0]

### Added

- **The provider `connection` block in the model registry**
(`config/v1/model-registry.schema.json`). Optional, so existing
registries load unchanged. sci#287 (source-code-intelligence) routes the
runner pool's model delivery through it; the Go executor parses the block
leniently, but the engine's config-completeness audit validates the
registry against this schema, so a registry carrying one failed startup
with `Additional properties are not allowed ('connection' was unexpected)`
(live on the dev cluster, 2026-11-06; a dev-only Containerfile patch
worked around it). The schema mirrors the executor's `validate()`:
- `type` (required): `anthropic`, `anthropic-compatible`, `gemini`,
`openai`, `openai-compatible` — the wire and credential format, not the
model family. Registered as `provider_connection_type`.
- `base_url`: required on the compatible types (they exist for endpoint
overrides), empty on the proprietary types (the default endpoint
serves; an empty string reads as absent, as the executor does).
- `harness`: the harness a gateway connection fronts its wire with
(`omp`, `claude`); empty keeps the default.
- `credential` (required): `{source: env | secret, name?, key?}` — a
reference, never the credential itself. `source: secret` requires the
Secret's non-empty `name` and `key`. Registered as `credential_source`.
- The block is routing data only, never credentials: the typed sections
stay permissive (`ProviderSpec` keeps it as an extra field) and the
schema refuses any other key on the block.
- traust-core/engine pin bumps pick this up (a parallel engine PR notes
the dependency).

## [0.62.3]

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.62.3
0.63.0
129 changes: 129 additions & 0 deletions config/v1/model-registry.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,135 @@
"type": "string",
"minLength": 4
},
"connection": {
"type": "object",
"description": "Provider routing: the wire this provider speaks, its endpoint, its harness and where its credential lives. Routing data only, never the credentials themselves \u2014 a secret credential names the Secret and the key within it, and the credential reaches the worker on the deployment's existing mechanism. Absent keeps the default routing (the Anthropic wire, the pod's existing credential).",
"required": [
"type",
"credential"
],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"enum": [
"anthropic",
"anthropic-compatible",
"gemini",
"openai",
"openai-compatible"
],
"description": "The wire and credential format, not the model family: proprietary endpoints (anthropic, gemini, openai) or compatible gateways speaking an incumbent's wire (anthropic-compatible, openai-compatible). A gateway serving both wires appears as two providers."
},
"base_url": {
"type": "string",
"description": "The gateway endpoint. Required on the compatible types, which exist for endpoint overrides; empty on the proprietary types, whose default endpoint serves."
},
"harness": {
"type": "string",
"description": "The harness a gateway connection fronts its wire with (omp or claude); empty keeps the default."
},
"credential": {
"type": "object",
"description": "Where the provider's credential lives \u2014 a reference, never the credential itself. Source env reads the pod's existing environment; source secret names a Kubernetes Secret and the key within it, both required.",
"required": [
"source"
],
"additionalProperties": false,
"properties": {
"source": {
"type": "string",
"enum": [
"env",
"secret"
]
},
"name": {
"type": "string",
"description": "The Secret's name (source secret)."
},
"key": {
"type": "string",
"description": "The credential's key within the Secret (source secret)."
}
},
"if": {
"properties": {
"source": {
"const": "secret"
}
},
"required": [
"source"
]
},
"then": {
"required": [
"name",
"key"
],
"properties": {
"name": {
"minLength": 1
},
"key": {
"minLength": 1
}
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"type": {
"enum": [
"anthropic-compatible",
"openai-compatible"
]
}
},
"required": [
"type"
]
},
"then": {
"required": [
"base_url"
],
"properties": {
"base_url": {
"minLength": 1
}
}
}
},
{
"if": {
"properties": {
"type": {
"enum": [
"anthropic",
"gemini",
"openai"
]
}
},
"required": [
"type"
]
},
"then": {
"properties": {
"base_url": {
"maxLength": 0
}
}
}
}
]
},
"models": {
"type": "object",
"minProperties": 1,
Expand Down
16 changes: 16 additions & 0 deletions enums/v1/credential-source.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "credential_source",
"source_schema": "model-registry.schema.json#/properties/providers/additionalProperties/properties/connection/properties/credential/properties/source",
"description": "Values of `connection.credential.source` in model-registry.schema.json \u2014 where a provider's credential lives.",
"values": [
"env",
"secret"
],
"used_in_schemas": [
"model-registry.schema.json"
],
"definitions": {
"env": "The pod's existing environment (the model Secret's EnvFrom where the deployment wires one).",
"secret": "A Kubernetes Secret in the Job's namespace; the Secret's name and the key within it are both required."
}
}
22 changes: 22 additions & 0 deletions enums/v1/provider-connection-type.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "provider_connection_type",
"source_schema": "model-registry.schema.json#/properties/providers/additionalProperties/properties/connection/properties/type",
"description": "Values of `connection.type` in model-registry.schema.json \u2014 the wire a registry provider speaks.",
"values": [
"anthropic",
"anthropic-compatible",
"gemini",
"openai",
"openai-compatible"
],
"used_in_schemas": [
"model-registry.schema.json"
],
"definitions": {
"anthropic": "The proprietary Anthropic endpoint; no base_url (the default endpoint serves).",
"anthropic-compatible": "A gateway speaking the Anthropic wire; requires a base_url endpoint override.",
"gemini": "Google's proprietary API; no base_url (the default endpoint serves).",
"openai": "The proprietary OpenAI endpoint; no base_url (the default endpoint serves).",
"openai-compatible": "A gateway speaking the OpenAI wire; requires a base_url endpoint override."
}
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "traust-contracts"
version = "0.62.3"
version = "0.63.0"
license = "Apache-2.0"
description = "Contract surface for the AI security ledger ecosystem: schemas and shared enums"
requires-python = ">=3.11"
Expand Down
Loading