# Installation Model Catalog Status: implemented on 2026-09-02. ## Outcome `thothii-installation.yaml` is the only operator-authored source for models used by interactive sessions, metadata generation, and embedding. Runtime-specific files are deterministic projections, not additional configuration sources. Workspace descriptors contain database and Evidence concerns and no model, provider, allowlist, default, embedding, or vector-store configuration. This design does not merge execution lifecycles. Pi continues to run interactive sessions, the short-lived LiteLLM helper continues to perform metadata generation, and the internal Ollama service continues to provide embeddings. They share model declaration, not execution machinery. ## Canonical installation shape The following example covers all currently required cases: a Pi built-in model, an authenticated custom endpoint, a keyless internal endpoint, metadata generation, and the single embedding model. ```yaml schemaVersion: 2 profile: server projectDirectory: /srv/thothii envFile: /srv/thothii/operator.env workspaceRepository: remote: git@git.example.com:organization/workspaces.git branch: main access: ssh modelCatalog: defaults: session: zai/glm-5.3 metadataGeneration: local-qwen/qwen3.6-35b-a3b embedding: id: ollama/qwen3-embedding:0.6b dimensions: 1024 providers: deepseek: authentication: mode: pi_auth session: mode: pi_builtin models: deepseek-v4-pro: session: {} deepseek-v4-flash: session: {} zai: endpoint: baseUrl: https://api.z.ai/api/coding/paas/v4 authentication: mode: secret_env apiKeyEnv: ZAI_API_KEY session: mode: openai_compatible metadataGeneration: litellmProvider: openai models: glm-5.3: label: GLM-5.3 session: reasoning: true contextWindow: 200000 maxTokens: 131072 metadataGeneration: {} local-qwen: endpoint: baseUrl: https://ml-aritmolab.policlinicosandonato.it/v1 authentication: mode: none session: mode: openai_compatible metadataGeneration: litellmProvider: openai models: qwen3.6-35b-a3b: label: Qwen3.6 35B A3B session: reasoning: false contextWindow: 131072 maxTokens: 16384 compatibility: supportsDeveloperRole: false supportsReasoningEffort: false supportsStore: false maxTokensField: max_tokens metadataGeneration: disableThinking: true authentication: configDirectory: /srv/thothii/auth-canonical runtimeProjection: directory: /srv/thothii/auth-runtime uid: 10001 gid: 10001 ``` The catalog uses maps instead of repeated IDs. The canonical identity of a model is always derived as `/`. `upstreamModel` may be added to a model only when the endpoint uses a different identifier. `label` is optional and falls back to the canonical identity. Model eligibility is not repeated in an `usages` array. A `session` block makes the model eligible for sessions; a `metadataGeneration` block makes it eligible for metadata generation. The embedding is a single required installation value rather than a list plus default. ## Provider and authentication rules A provider owns one endpoint, one authentication mode, and zero or one adapter for each runtime. Model entries cannot override provider endpoint or credentials. If the same upstream service needs different endpoints or credentials, the installation declares two provider identities. Supported session modes are intentionally closed: - `pi_builtin`: Pi already owns the model's technical descriptor; the model's `session` block is empty and ThothII does not copy context-window or compatibility facts. - `openai_compatible`: ThothII generates a Pi custom-provider descriptor; each session model supplies the technical values required by Pi. Metadata generation uses the provider-level `litellmProvider`. A model-level `metadataGeneration.disableThinking: true` is permitted only for an explicit compatible endpoint. There is no generic adapter or plugin abstraction in schema version 2. Exactly one provider authentication mode is allowed: - `secret_env` requires an approved API-key environment reference present in the protected secret bundle. Secret values never enter YAML, generated files, logs, arguments, or API responses. - `pi_auth` is valid only for session-only `pi_builtin` providers and resolves through Pi's protected authentication projection. - `none` is valid only for an explicit endpoint. Runtime projections may supply a fixed non-secret compatibility placeholder when a client library requires a non-empty key. ## Defaults and selections `defaults.session` and `embedding` are required. `defaults.metadataGeneration` is required exactly when at least one model has a `metadataGeneration` block; metadata generation may otherwise be absent and its UI controls are disabled. `modelCatalog.defaults.session` is the only configured session-model default. `PI_PROVIDER`, `PI_MODEL`, and provider/model fields in installation-default settings are removed. A user choice is a Model Selection containing only the canonical model identity and runtime controls such as thinking level. A session manifest pins the selected canonical identity. Removing the currently selected model causes new-session selection to fall back to the catalog default with an explicit administrative warning. An existing session is never silently moved to a different model; resume fails with `model_unavailable` when its pinned identity can no longer be resolved. ## Generated runtime projections Before Compose starts, `tht` strictly validates schema version 2 and generates installation-local artifacts below `deploy//generated/`: - a normalized catalog JSON consumed defensively by the backend; - Pi `models.json` for custom providers; - Pi `settings.json`, combining fixed product settings with the session-eligible canonical IDs; - a Compose override that mounts the projections and supplies embedding identity and dimensions to core, preprocessing, and `embedding-model-init`. Generation is deterministic and published only after every candidate artifact validates. A failed generation aborts start before Compose is invoked. `tht doctor` recomputes expected bytes and reports differences; no digest manifest or separate apply command exists. When projection bytes change, `tht start` recreates the affected services so they cannot continue with an older bind mount. Generated projections are not backed up. Restore validates the canonical installation descriptor, regenerates every projection, and only then starts services. Base Compose files and `operator.env` must contain no model identities, defaults, endpoints, or dimensions. ## Workspace schema v4 Workspace schema v4 removes both top-level `llm_policy` and `semantic_index`. The entire latter block is redundant today: its engine and distance are product constants, its collection duplicates the workspace ID, and its model and dimensions are installation facts. The runtime derives: - Qdrant collection identity from the workspace ID; - engine and distance from the supported product contract; - embedding identity and dimensions from the Installation Model Catalog. The published index generation records the canonical embedding identity and dimensions that created it. A mismatch makes the index explicitly incompatible and requires operator-triggered preprocessing. No existing index is deleted or rebuilt automatically. The v3-to-v4 workspace migration is deterministic: set `workspace.schema_version` to `4`, remove `llm_policy`, and remove `semantic_index`. It does not alter database, Evidence, diagnostics, or binding data. ## Installation migration Legacy installation migration must inspect all three former sources: 1. `metadataGeneration` in `thothii-installation.yaml`; 2. `deploy/pi/models.json`; 3. `deploy/pi/settings.json`. The migrator emits a version-2 candidate only when it can reconcile identities, endpoints, credentials, and runtime-specific facts without guessing. Ambiguous aliases such as `glm-53`, `zai/glm-5.3`, and `openai/glm-5.3` are not silently equated. A conflict produces a field-level report and leaves every input unchanged for operator resolution. After migration, the strict loader rejects `metadataGeneration`, workspace `llm_policy`, workspace `semantic_index`, legacy Pi source files, unknown fields, duplicate YAML keys, invalid defaults, and incompatible authentication/adapter combinations with an actionable `migration_required` or validation error. ## Final simplicity audit The accepted design removes every configuration duplication that can be removed without inference: - one authored installation file instead of an installation block plus two Pi files; - one canonical `provider/model` identity instead of display IDs and runtime IDs; - per-use blocks instead of a duplicated usages list; - one embedding entry instead of a selectable embedding catalog; - one catalog session default instead of environment and settings defaults; - no model or vector-store fields in workspace descriptors; - provider-level credentials instead of per-model credentials; - no generic runtime-plugin abstraction; - no persisted digest, apply command, or backup of generated projections. The remaining generated files are necessary boundary adapters, not configuration concepts. Making the backend parse the authoring YAML independently would remove one file but restore two semantic validators. Hard-coding embedding values in Compose would remove one projection but restore a model source outside the catalog. Inferring authentication from missing fields would save one YAML key but turn a safe explicit choice into ambiguity. These apparent simplifications are therefore rejected. No further reduction was found that preserves one authority, strict validation, explicit security, session determinism, and model-free workspaces. ## Implementation surface Implementation must update the host `tht` installation loader, setup and lifecycle projection, doctor, backup/restore, Compose mounts and embedding inputs, backend catalog/settings/session model resolution, workspace schema and migration, runtime rendering and diagnostics, frontend workspace drafts and model filtering, examples, fixtures, and documentation. Existing session manifests remain readable and keep their pinned provider/model identity; only resume resolution changes to the new catalog. Implementation completed after explicit approval. The installation schema, deterministic runtime projections, migration path, model-free workspace schema v4, backend consumers, operator UI, fixtures, and documentation now enforce this contract.