Skip to content
Merged
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
55 changes: 55 additions & 0 deletions docs/sourceos-model-carry-ref.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SourceOSModelCarryRef

Status: additive carry-layer projection fixture

## Purpose

`SourceOSModelCarryRef` is the SourceOS typed-contract projection for an approved on-device reference to a governed model or model-service profile. It complements the existing `SourceOSCarryRef` service reference examples and the existing `LocalModelProfile` laptop-safe local model profiles.

The object is intentionally reference-only. It must not embed mutable model weights, mutable adapters, credentials, user tuning data, or runtime authorization grants.

## Current fixture

```text
examples/sourceos-model-carry-ref.local-llama32-3b.json
```

This fixture links the local `llama32-3b` style profile into the broader Prophet Foundry path:

```text
model-governance-ledger
→ model-router
→ sourceos-model-carry
→ agent-machine
→ agentplane
```

## Validation

Run:

```bash
python3 tools/validate_sourceos_model_carry_refs.py
```

The validator checks:

- `type == SourceOSModelCarryRef`
- `id` uses `urn:srcos:model-carry-ref:`
- `specVersion == 2.1.0`
- `governanceRef` is present
- `routerProfileRef` uses `urn:srcos:model-router-profile:`
- `mutableModelState` is false
- release and fallback references use the expected URN namespaces

## Boundary rules

1. A carry reference is not a model promotion decision.
2. A carry reference is not a runtime route decision.
3. A carry reference is not a permission grant.
4. SourceOS may carry approved references, cache policy, launch profile references, fallback references, and evidence references.
5. SourceOS must not become authority for model lifecycle, model promotion, personal tuning authorization, or runtime side effects.

## Follow-up

After the SourceOS projection contracts stabilize, this validator should be wired into the default `make validate` target alongside existing carry-reference and CLI checks.
15 changes: 15 additions & 0 deletions examples/sourceos-model-carry-ref.local-llama32-3b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": "urn:srcos:model-carry-ref:local-llama32-3b-office-assist",
"type": "SourceOSModelCarryRef",
"specVersion": "2.1.0",
"modelRef": "urn:prophet:model:llama32-3b-local-office-assist",
"governanceRef": "urn:prophet:model-release-decision:local-llama32-3b-office-assist-20260504",
"routerProfileRef": "urn:srcos:model-router-profile:local-first-office-assist",
"releaseSetRefs": ["urn:srcos:release-set:sourceos-workstation-m2-20260504"],
"launchProfileRefs": ["urn:srcos:model-launch-profile:llama-cpp-local-office-assist"],
"fallbackRefs": ["urn:srcos:model-carry-ref:local-llama32-1b-router"],
"carryPolicy": "download-on-demand",
"cachePolicy": "weights-cache-allowed",
"mutableModelState": false,
"evidenceRefs": ["sha256:2e7f1c7f0a6a4bbd9ef000000000000000000000000000000000000000000"]
}
71 changes: 71 additions & 0 deletions tools/validate_sourceos_model_carry_refs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
"""Validate SourceOSModelCarryRef projection examples.

This validator is intentionally lightweight and stdlib-only. Full JSON Schema
validation belongs in SourceOS-Linux/sourceos-spec; this repository validates the
carry-layer invariants it must preserve locally.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path
from typing import Any

ROOT = Path(__file__).resolve().parents[1]
EXAMPLES = sorted((ROOT / "examples").glob("sourceos-model-carry-ref.*.json"))


class ValidationError(Exception):
pass


def load_json(path: Path) -> Any:
try:
return json.loads(path.read_text(encoding="utf-8"))
except FileNotFoundError as exc:
raise ValidationError(f"missing file: {path.relative_to(ROOT)}") from exc
except json.JSONDecodeError as exc:
raise ValidationError(f"invalid JSON in {path.relative_to(ROOT)}: {exc}") from exc


def require(condition: bool, message: str) -> None:
if not condition:
raise ValidationError(message)


def validate_ref(path: Path, ref: dict[str, Any]) -> None:
rel = path.relative_to(ROOT)
require(ref.get("type") == "SourceOSModelCarryRef", f"{rel}: type must be SourceOSModelCarryRef")
require(str(ref.get("id", "")).startswith("urn:srcos:model-carry-ref:"), f"{rel}: id must be a model-carry-ref URN")
require(ref.get("specVersion") == "2.1.0", f"{rel}: specVersion must be 2.1.0")
require(ref.get("modelRef"), f"{rel}: modelRef is required")
require(ref.get("governanceRef"), f"{rel}: governanceRef is required")
require(str(ref.get("routerProfileRef", "")).startswith("urn:srcos:model-router-profile:"), f"{rel}: routerProfileRef must be a model-router-profile URN")
require(ref.get("carryPolicy") in {"reference-only", "download-on-demand", "preload-reference", "disabled"}, f"{rel}: invalid carryPolicy")
require(ref.get("cachePolicy") in {"none", "metadata-only", "weights-cache-allowed", "kv-cache-allowed", "embedding-cache-allowed"}, f"{rel}: invalid cachePolicy")
require(ref.get("mutableModelState") is False, f"{rel}: mutableModelState must be false")
for release_ref in ref.get("releaseSetRefs", []):
require(str(release_ref).startswith("urn:srcos:release-set:"), f"{rel}: releaseSetRefs entries must be release-set URNs")
for fallback_ref in ref.get("fallbackRefs", []):
require(str(fallback_ref).startswith("urn:srcos:model-carry-ref:"), f"{rel}: fallbackRefs entries must be model-carry-ref URNs")


def main() -> int:
if not EXAMPLES:
print("ERR: no SourceOSModelCarryRef examples found", file=sys.stderr)
return 2
try:
for example in EXAMPLES:
validate_ref(example, load_json(example))
print(f"ok: {example.relative_to(ROOT)}")
except ValidationError as exc:
print(f"ERR: {exc}", file=sys.stderr)
return 1
print("SourceOSModelCarryRef validation passed")
return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading