# Operational Model Registry ## M9 installation rationale Installed state is derived from verified artifact locations. The installation-rationale projection joins models to exact revisions/artifact sets, RuntimeProfiles, deployments, capability contracts, project bindings, gateway use and evaluation evidence. This powers deletion blockers and the Models “Why is this installed?” panel without treating operator prose as evidence. ## Scope M2 turns the registry into PostgreSQL-backed operational state without starting discovery, download, runtime, scheduler, benchmark, advisor or project-production binding work. The initial 15 candidates are materialized from the validated seed manifest and remain unverified candidates. M3 extends this foundation with `UpstreamSnapshot`, `UpstreamFile`, `ArtifactSet`, `DownloadPlan`, `ArtifactJob`, `ArtifactJobAttempt`, `ArtifactInspection`, and `ArtifactSetMember`. Metadata refresh does not change candidate verification. Only a complete promoted set creates verified artifacts and locations; the model lifecycle still remains `candidate` pending later approval. M4 references, but never collapses, those identities through RuntimeEnvironment, RuntimeProfile, RuntimeCompatibilityAssessment, ExecutionApproval, RuntimeProbe and DeploymentCandidate. A verified ArtifactSet remains only a statement about local bytes until the later gates succeed. ## Domain boundaries | Entity | Identity | Mutable operator data | Immutable provenance | |---|---|---|---| | `Model` | local UUID, stable key, unique upstream source | display name, description, `local_metadata`, `interpretation_metadata`, lifecycle | none until represented by a revision | | `ModelRevision` | model + exact resolved commit SHA | deprecation/archive timestamps | upstream revision label, resolved SHA, metadata snapshot | | `ModelArtifact` | revision + SHA-256 | lifecycle/verification state | filename, type, serialization, digest, byte size | | `DerivedArtifact` | output SHA-256 | lifecycle/verification state | ordered source hashes, transformation, tool/version, configuration, environment, output hash | | `ArtifactLocation` | storage root + relative path | observed presence/hash/size | never used as content identity | | `UpstreamSnapshot` | observation UUID | staleness by new observation | provider/repository/resolved SHA and captured evidence | | `ArtifactSet` | revision + variant key | availability/completeness/security state | selected files and immutable selection time | | `DownloadPlan` | UUID/canonical idempotency hash | lifecycle status only | exact SHA, file payload, target and preflights | | `ArtifactJob` | one per plan | lease/progress/result | target ownership and plan relation | Upstream facts, locally entered governance metadata and local interpretation are separate JSON documents. Seed-derived capability/role/runtime hints are marked `unverified_seed_claim`; they are not promoted into upstream facts. License data defaults to `unknown` with no invented SPDX ID or usage right. ## Service boundary FastAPI routes call `RegistryService`; domain orchestration calls `RegistryRepository`; only the repository and service own SQLAlchemy access. The UI never derives registry truth from the YAML manifest. Compose enables the idempotent startup seed, while tests and explicit maintenance code can call the same seed operation directly. ## API - `GET/POST /api/v1/models` - `GET/PATCH/DELETE /api/v1/models/{id}` - `POST /api/v1/models/{id}/deprecate` - `POST /api/v1/models/{id}/archive` - `GET/POST /api/v1/models/{id}/revisions` - `DELETE /api/v1/revisions/{id}` - `GET/POST /api/v1/revisions/{id}/artifacts` - `DELETE /api/v1/artifacts/{id}` and `POST /api/v1/artifacts/{id}/verify` - `GET /api/v1/revisions/{id}/derived-artifacts`, `POST /api/v1/derived-artifacts` - `DELETE /api/v1/derived-artifacts/{id}` - `GET/POST /api/v1/storage-roots` plus observation/capacity/delete endpoints - M3 discovery, upstream, artifact-set, download-plan and artifact-job endpoints documented in `ARTIFACT_ACQUISITION.md` List endpoints are typed and paginated. Models support search plus lifecycle/source-type filters. Invalid UUIDs and payloads use the normalized error envelope. ## Lifecycle and deletion Deprecation is a first-class, auditable operator action. Physical deletion first queries dependent revisions, artifacts, lineage edges, locations and runtime digest references. A dependency returns HTTP 409 with exact resource type, ID and relation; no cascade is used to erase provenance. ## Seed contract The operation inserts missing candidates by stable key/source and updates seed-owned display/source interpretation only. It never overwrites `local_metadata`. The M2 production seed result was 15 inserts followed by 0 inserts on the immediate repeat run.