release: freeze Nexus One AI 1.0.0-rc1
This commit is contained in:
1 parent
63acefd890
commit
4f1419ca93
152 files changed
+9445
-828
No files matched your search
@@ -0,0 +1,62 @@
|
||||
# Installer Architecture Decision Package
|
||||
|
||||
**Status**: Recommended defaults for approval; no implementation authority.
|
||||
**Evidence basis**: Current repository license verification, offline payload inputs, product matrix,
|
||||
and installer artifact contract.
|
||||
|
||||
## Decisions That Can Be Fixed Now
|
||||
|
||||
| Area | Recommended decision | Basis |
|
||||
|---|---|---|
|
||||
| Manifest format | Canonical UTF-8 JSON conforming to `schemas/artifact-manifest.schema.json`; keys serialized in lexical order, no insignificant whitespace, final newline excluded from signed bytes | Deterministic offline verification and cross-language support |
|
||||
| Signature envelope | Detached JSON envelope conforming to `schemas/signature-envelope.schema.json` | Separates immutable manifest identity from transport |
|
||||
| Artifact signing algorithm | Ed25519 for release artifacts; retain current RSA license signatures as a separate compatibility trust domain | Small offline verifier and no forced license migration |
|
||||
| Object integrity | SHA-256 per object plus whole-artifact SHA-256 | Matches current repository checksum practice while adding signed enforcement |
|
||||
| Version compatibility | Explicit category/tier allowlists and platform version range; default deny; deterministic reason order in `compatibility-evaluation.md` | Prevents accidental tier/category expansion |
|
||||
| Staging | Verify trust, schema, compatibility, capacity, then every object before mutation | Fail-closed contract |
|
||||
| Offline licensing | Signed license imports locally; field staging is an explicit restricted allowlist, never a tier; invalid/expired/revoked/time-uncertain/binding-failed licenses never silently become valid | Tightens current evaluator gaps without changing the compatible RSA license trust domain |
|
||||
| Clock uncertainty | Record local time source and uncertainty; signed artifact verification is time-independent unless policy metadata explicitly expires; license validity remains subject to its signed dates and produces an operator-visible blocked/staging state when trustworthy time cannot be established | Avoids hidden network time dependency |
|
||||
| Workstation baseline | One universal hardware-adaptive Workstation payload per CPU architecture. First implementation is AMD64 across CPU-only/low/mid/high GPU profiles; DGX Spark requires later ARM64 media or removal from support | GPU capability must not fragment media or create tiers; DGX Spark still cannot boot an AMD64 ISO |
|
||||
| Starter models | Immutable Ollama manifests and the Hugging Face commit are recorded in `workstation-hardware-model-baseline.md`; file/layer inventory and owner approval remain required | Current payload inputs use mutable names, now mapped to evidence-backed candidate pins |
|
||||
| AMD GPU scope | Excluded from the first release. AMD64 hosts may use CPU-only fallback; ROCm/Strix Halo acceleration requires a future approved workstream | Product direction confirmed; prevents unsupported acceleration claims |
|
||||
|
||||
## Decisions Requiring Named Cezen Approval
|
||||
|
||||
| Decision | Recommended default | Required owner |
|
||||
|---|---|---|
|
||||
| Offline release-key custody | Private root offline under dual/threshold custody; separate purpose-constrained artifact-signing subordinate isolated from builders; signing happens after independent digest verification | Security owner |
|
||||
| Key rotation | Annual subordinate rotation; root rotation only by ceremony; old trusted keys retained through supported artifact lifetime | Security owner |
|
||||
| Revocation | Root-signed revocation list distributed as a trust bundle; 90-day maximum age for new imports; installed healthy versions remain operable but warn when list is stale | Security + support owners |
|
||||
| Emergency revocation | Block new import/update immediately; do not brick an already-running appliance; publish signed recovery/trust bundle through controlled media | Security + product owners |
|
||||
| Update retention | Retain current and one last-known-good platform inventory plus a compatible verified pre-update data/config backup; never delete recovery state automatically to make room | Product + support owners |
|
||||
| Health window | Ten minutes after all required services are ready, restarting after reboot/unexpected restart, plus required data/service/model checks | Delivery/support owner |
|
||||
| Downgrade | Default deny below signed security floor; break-glass requires signed authorization artifact, reason, actor, and verified backup | Security + product owners |
|
||||
| Evidence approval | Product owner plus delivery/support approver per artifact; security approval whenever trust or security floor changes | Product owner |
|
||||
| Online acquisition | Dedicated HTTPS endpoint and signed manifest index, certificate validation plus artifact signature, resumable content-addressed downloads, no mutation until complete verification | Platform/security owners |
|
||||
|
||||
## Workstation Payload Baseline Derived From the Repo
|
||||
|
||||
Included classes currently evidenced are Ubuntu packages from `apt-packages.txt`; backend,
|
||||
ChromaDB, Jupyter and AI Python wheelhouses; Miniconda; Ollama; platform source; container images for
|
||||
Open WebUI, vLLM, DCGM exporter, Prometheus, node exporter, and Grafana; local license public key;
|
||||
starter models; and K3s/MinIO tooling described by the offline README. This is an inventory candidate,
|
||||
not an accepted release payload.
|
||||
|
||||
Before approval, replace every mutable input: `Miniconda3-latest`, container tags `main`/`latest`,
|
||||
Ollama model tags without content digests, and the Hugging Face model without an immutable commit.
|
||||
Record license and redistribution permission for every package, image, runtime, and model.
|
||||
|
||||
## Gate 1 Approval Record
|
||||
|
||||
| Item | Owner | Decision/date | Status |
|
||||
|---|---|---|---|
|
||||
| Manifest, signature, and compatibility contracts | Platform + security | — | Drafted with structural, compatibility and real test-only Ed25519 positive/negative vectors; approval pending |
|
||||
| Signing/custody/rotation/revocation | Security | — | Awaiting approval |
|
||||
| Workstation hardware/architecture baseline | Product + delivery | — | Universal per architecture defined; approve AMD64 profile matrix and decide later ARM64/multi-architecture/DGX Spark scope |
|
||||
| Starter-model immutable revisions and licenses | AI/platform + legal | — | Candidate pins recorded; artifact inventory and approval pending |
|
||||
| Online acquisition contract | Platform + security | — | Detailed contract drafted; production endpoints, credentials, proxy/CA, retry/cache policy undecided |
|
||||
| Update/rollback/license policies | Product + security + support | — | Detailed update and offline-license policies drafted; open values and approval remain |
|
||||
| Lab method and evidence approvers | Delivery/support | — | Awaiting assignment |
|
||||
|
||||
The authoritative consolidated approval worksheet is `../analysis/gate-1-decision-dossier.md`. Gate 1
|
||||
remains blocked until all mandatory rows there are approved and the consistency analysis is re-run.
|
||||
@@ -0,0 +1,62 @@
|
||||
# Artifact Compatibility Evaluation Contract
|
||||
|
||||
This contract defines deterministic pre-mutation evaluation for ISO payloads, model packs, update
|
||||
bundles, and trust bundles. Signature and object verification occur separately; compatibility cannot
|
||||
turn an untrusted artifact into a trusted one.
|
||||
|
||||
## Installed Context
|
||||
|
||||
The evaluator receives a locally derived, non-secret context containing product category, internal
|
||||
tier, platform version, Ubuntu release, architecture, hardware profile/capabilities, available bytes,
|
||||
installed security floor, current revocation-list version/age, and current artifact inventory. Missing
|
||||
required context fails closed; it is never replaced by a network lookup.
|
||||
|
||||
## Evaluation Order
|
||||
|
||||
Evaluation stops at the first failure in this order so every implementation returns the same primary
|
||||
reason:
|
||||
|
||||
1. `ARTIFACT_SCHEMA_UNSUPPORTED` — manifest or signature-envelope schema is not supported.
|
||||
2. `TRUST_POLICY_UNSUPPORTED` — declared trust policy cannot be evaluated.
|
||||
3. `KEY_UNKNOWN`, `KEY_REVOKED`, or `REVOCATION_POLICY_STALE` — signer is not currently acceptable.
|
||||
4. `MANIFEST_DIGEST_MISMATCH` — envelope digest does not match canonical manifest bytes.
|
||||
5. `SIGNATURE_INVALID` — detached signature does not verify the canonical manifest bytes.
|
||||
6. `OBJECT_DIGEST_MISMATCH` — any declared object is absent, different in size, or fails SHA-256.
|
||||
7. `ARCHITECTURE_INCOMPATIBLE` — target architecture is neither installed architecture nor `multi`.
|
||||
8. `CATEGORY_INCOMPATIBLE` — installed category is not explicitly allowed.
|
||||
9. `TIER_INCOMPATIBLE` — installed internal tier is not explicitly allowed.
|
||||
10. `PLATFORM_VERSION_INCOMPATIBLE` — current/from/to rules reject the installed version.
|
||||
11. `SECURITY_FLOOR_VIOLATION` — activation would move below the installed signed floor.
|
||||
12. `UBUNTU_RELEASE_INCOMPATIBLE` — base release is outside the declared target.
|
||||
13. `HARDWARE_PROFILE_INCOMPATIBLE` or `CAPABILITY_MISSING` — required local hardware is absent.
|
||||
14. `SPACE_INSUFFICIENT` — available staging/rollback space is below `required_free_bytes`.
|
||||
15. `ROLLBACK_PREREQUISITE_MISSING` — required snapshot/backup/last-known-good state is not verified.
|
||||
16. `ACTION_GRAPH_INVALID` — actions are unordered, duplicated, cyclic, or reference absent objects.
|
||||
|
||||
Only a result of `COMPATIBLE` permits staging. Staging still cannot mutate the active installation;
|
||||
activation is a separately authorized durable operation.
|
||||
|
||||
## Category and Tier Invariants
|
||||
|
||||
- `workstation` category accepts only tier `workstation`.
|
||||
- `server` category accepts only `starter`, `basic`, `pro`, or `max`.
|
||||
- A Workstation artifact listing a Server tier, or Server artifact listing `workstation`, is invalid
|
||||
even when both values separately appear in their allowlists.
|
||||
- Offline Server S/M permits only `starter` and `basic`; Offline Server L/Max permits only `pro` and
|
||||
`max`. Online Universal Server may permit all four Server tiers.
|
||||
- Compatibility never grants entitlement. License evaluation can further restrict an otherwise
|
||||
compatible artifact.
|
||||
|
||||
## Version Rules
|
||||
|
||||
`platform_versions` and update `from_versions` use a single approved semantic-version range grammar;
|
||||
prerelease versions match only when explicitly named. `to_version` is exact. Downgrade is any target
|
||||
lower than current and is rejected unless both the manifest and a separately signed break-glass
|
||||
authorization permit it. String or lexical version comparison is forbidden.
|
||||
|
||||
## Test Vector Policy
|
||||
|
||||
Files under `test-vectors/` are intentionally non-production examples. Repeated hexadecimal values,
|
||||
`example.invalid`, test key IDs, and zero-value signatures MUST never be accepted as release data.
|
||||
Structural/compatibility vectors may use them; cryptographic positive vectors require a dedicated
|
||||
published test key and real signature before Gate 1 approval.
|
||||
@@ -0,0 +1,138 @@
|
||||
# Installer Artifact Contract
|
||||
|
||||
## Release Matrix and Order
|
||||
|
||||
| Order | Bootable product | Network contract | Selection | Embedded model boundary |
|
||||
|---|---|---|---|---|
|
||||
| Existing | Online Universal Server ISO | Network required and preflighted | Server S/M/L/Max, constrained by license and hardware | No promise of offline models |
|
||||
| 1 | Offline Workstation ISO | Zero network from boot through acceptance | Fixed `workstation` category; universal hardware-adaptive capability profile within the artifact CPU architecture; no Server tier | Approved Workstation starter set with capability-based activation |
|
||||
| 2 | Offline Server S/M ISO | Zero network from boot through acceptance | Server S or M only | Approved S/M starter set only |
|
||||
| 3 | Offline Server L/Max ISO | Zero network from boot through acceptance | Server L or Max only | Approved platform/bootstrap set only; large models separate |
|
||||
|
||||
The four products share source, trust, manifest, model-pack, update, evidence, and lifecycle
|
||||
contracts. They are separate release artifacts: passing one does not imply another passed.
|
||||
|
||||
GPU model or VRAM does not create additional Workstation ISO products. One AMD64 Workstation artifact
|
||||
MUST cover the approved AMD64 CPU-only and low/mid/high GPU matrix through hardware-adaptive runtime
|
||||
selection. ARM64 DGX Spark is a CPU-architecture variant requiring separate build identity and full
|
||||
evidence unless a future multi-architecture artifact is independently proven.
|
||||
|
||||
## Exact Zero-Network Acceptance
|
||||
|
||||
For an offline acceptance run, all physical and virtual network interfaces other than loopback MUST
|
||||
be disabled or disconnected before boot and remain so through OS installation, first boot, platform
|
||||
installation, reboot persistence, local portal access, readiness evaluation, starter-model inference,
|
||||
local help, and evidence export. The test environment MUST provide no DNS, default route, package
|
||||
mirror, container registry, source repository, NTP, license endpoint, telemetry sink, or simulated
|
||||
successful network response.
|
||||
|
||||
Acceptance requires all of the following:
|
||||
|
||||
1. Dependency acquisition counters and packet capture show zero successful external fetches; any
|
||||
attempted external fetch is a failure even if a fallback later succeeds.
|
||||
2. Installation completes solely from verified embedded payloads and records every selected object.
|
||||
3. After reboot, required services, portal, entitlement evaluation, local help, and at least one
|
||||
declared starter-model inference work locally.
|
||||
4. Remote-only optional connectors are explicitly `unavailable (network required)` and do not block
|
||||
platform readiness.
|
||||
5. Three clean runs pass on representative supported hardware; one run includes a controlled
|
||||
interruption at a reboot or activation boundary and follows the declared recovery path.
|
||||
|
||||
## Payload Boundaries
|
||||
|
||||
Every offline ISO embeds: the pinned Ubuntu base; boot/autoinstall data; platform source/package at
|
||||
one recorded revision; required apt packages and Python wheels; required container images by immutable
|
||||
digest; runtime binaries; category/tier deployment roles; license public keys and offline validation
|
||||
logic; local documentation; recovery tooling; SBOM/provenance; and the approved starter-model set.
|
||||
|
||||
The Online Universal Server ISO embeds only what is required to boot, preflight, authenticate the
|
||||
license/tier choice, and securely acquire the selected Server payload. It MUST stop before mutation
|
||||
when required network endpoints, trust validation, or selected payloads are unavailable.
|
||||
|
||||
Bootable media MUST NOT embed customer licenses, private signing keys, customer data, large optional
|
||||
models, mutable credentials, or payloads for categories/tiers the image cannot select. Identical
|
||||
objects inside one artifact SHOULD be content-addressed or deduplicated; size evidence MUST distinguish
|
||||
unique payload bytes from filesystem/ISO overhead.
|
||||
|
||||
## Signed Artifact Envelope
|
||||
|
||||
ISOs, model packs, and update bundles have a versioned canonical manifest containing artifact type,
|
||||
artifact ID/version, creation time, source revision, builder identity, target OS/architecture,
|
||||
compatible categories and tiers, minimum platform version, payload object path/size/digest, total
|
||||
unpacked-space requirement, signing-key ID, and policy version. Model packs additionally declare model
|
||||
identity/revision, runtime compatibility, minimum RAM/VRAM/disk, license/capability requirements, and
|
||||
activation action. Updates additionally declare from/to versions, ordered actions, service/reboot
|
||||
impact, migration identifiers, downgrade rules, and rollback classification.
|
||||
|
||||
The canonical manifest is signed with an offline release key; the artifact carries the detached
|
||||
signature and certificate/key chain but never a private key. Verification order is: trusted key and
|
||||
policy, signature, manifest schema, compatibility, capacity/preconditions, then every object digest.
|
||||
Any failure blocks staging/activation and emits a non-secret reason and evidence record. Key rotation
|
||||
uses a cross-signed trust update or a separately approved trust bundle. A signed, versioned revocation
|
||||
list MUST be importable offline; policy defines maximum age and the explicit operator-visible behavior
|
||||
when its age is exceeded. Rollback protection rejects versions below the installed security floor
|
||||
unless an auditable break-glass policy explicitly permits them.
|
||||
|
||||
The outer ISO is verified by published SHA-256 plus signature before flashing. The installed
|
||||
environment MUST independently verify the embedded payload manifest before platform mutation.
|
||||
|
||||
## Update, Activation, and Rollback
|
||||
|
||||
One update bundle format serves Workstation and all Server tiers. Compatibility rules select only
|
||||
declared actions; a bundle must never silently broaden entitlement or tier. Processing phases are
|
||||
`received`, `verified`, `staged`, `prechange_saved`, `activating`, `awaiting_reboot`, `validating`, and
|
||||
a terminal `succeeded`, `rolled_back`, `failed_safe`, or `recovery_required`.
|
||||
|
||||
Before activation the appliance records free-space checks, service impact, backup/snapshot identity,
|
||||
database compatibility, current artifact inventory, and rollback class. File/config updates use a
|
||||
side-by-side staged tree and atomic pointer/symlink swap where possible. Database migrations require
|
||||
an idempotent forward migration plus tested restore path. Container/model activation retains the
|
||||
previous digest until post-activation health validation passes. Updates that cannot be automatically
|
||||
rolled back MUST say so before confirmation and require a verified backup and explicit authorization.
|
||||
ISOs are refreshed with accepted updates for future clean installs, but installed appliances update
|
||||
through bundles rather than reinstalling the OS.
|
||||
|
||||
## Interruption and Recovery Matrix
|
||||
|
||||
| Interruption point | Required outcome |
|
||||
|---|---|
|
||||
| ISO download/flash | Whole-artifact verification fails; re-download/reflash; target untouched |
|
||||
| OS install before disk commit | Restart clean install; no platform-ready claim |
|
||||
| OS install after disk commit/before first boot | First boot resumes idempotently or blocks with local recovery guidance |
|
||||
| Embedded payload verification | No platform mutation; reverify/recreate media |
|
||||
| Package/image extraction or staging | Delete/reuse verified staging safely; active version unchanged |
|
||||
| Model-pack copy or verification | Incomplete pack quarantined; current models unchanged |
|
||||
| Update after pre-change save/before activation | Resume staging or discard it; active version unchanged |
|
||||
| Activation before health validation | Automatic rollback where declared; otherwise `recovery_required` with backup identity |
|
||||
| Reboot required | Resume same durable operation after reboot; never start a duplicate operation |
|
||||
| Rollback/restore | Preserve evidence and both failure causes; retry only from a verified checkpoint |
|
||||
|
||||
Power-loss tests MUST cover every mutating boundary. Recovery is successful only when active version,
|
||||
data/schema version, selected tier/category, service state, and evidence agree.
|
||||
|
||||
## Media Sizing Policy
|
||||
|
||||
Record exact bytes for the base ISO, each unique payload category, starter models, manifest/signature,
|
||||
and final artifact. Published USB minimum is the next commonly available capacity above final bytes
|
||||
plus at least 20% headroom and flashing/filesystem overhead. Recommendation may use the next larger
|
||||
capacity for field reliability and forecast growth. Current 35-50 GB Workstation and 2-4 GB online
|
||||
figures remain estimates until measured. Offline Server S/M and L/Max have no publishable size until
|
||||
their complete payloads are built and deduplicated. Large-model-pack media is sized independently.
|
||||
|
||||
## Evidence Gates
|
||||
|
||||
1. **Architecture-ready**: matrix, boundaries, threat model, trust ownership, manifest schemas,
|
||||
compatibility rules, recovery matrix, and test inventory approved.
|
||||
2. **Implementation-ready**: all architecture blockers resolved; pinned payload inventory and license
|
||||
mapping exist; signing/revocation and rollback operators are named.
|
||||
3. **Artifact-ready**: reproducible build record, SBOM, manifest/signatures, digests, measured size,
|
||||
static checks, and tamper/incompatibility negatives pass.
|
||||
4. **Offline-install-ready**: three zero-network clean runs, reboot persistence, starter inference,
|
||||
interruption recovery, and evidence export pass on representative hardware.
|
||||
5. **Update/model-ready**: successful import/update plus tamper, wrong tier/category, insufficient
|
||||
space, interruption, rollback, revoked key, and stale revocation-policy tests pass.
|
||||
6. **Release-ready**: no critical findings; source-to-artifact comparison, support runbook, product
|
||||
owner and delivery/support approval recorded separately for each artifact.
|
||||
|
||||
Offline Workstation may enter implementation only after Gate 1. Server offline implementations stay
|
||||
blocked until Workstation passes Gates 1-5 and the shared contract is amended from actual evidence.
|
||||
@@ -0,0 +1,125 @@
|
||||
# Installer Release Threat Model
|
||||
|
||||
## Scope and Security Objectives
|
||||
|
||||
This model covers production source through build, signing, publication, removable-media handling,
|
||||
boot/install, Online Universal acquisition, offline license import, model/update/trust import,
|
||||
activation, rollback/recovery and evidence export. It applies to all four bootable products and their
|
||||
shared signed artifacts.
|
||||
|
||||
Security objectives are to ensure that an appliance installs and runs only authorized, intact and
|
||||
compatible content; entitlement cannot be broadened; offline operation has no hidden network
|
||||
dependency; customer data and secrets are not disclosed or destroyed by lifecycle operations; and
|
||||
release/recovery evidence remains attributable and tamper-evident.
|
||||
|
||||
This contract does not claim protection against a fully compromised running OS with extracted
|
||||
administrator control, invasive hardware attacks, denial through physical destruction, or malicious
|
||||
firmware outside the approved hardware/Secure Boot baseline. Those risks require platform hardening,
|
||||
physical controls and incident recovery beyond installer verification.
|
||||
|
||||
## Assets and Adversaries
|
||||
|
||||
Protected assets include source revisions, build inputs/outputs, release/license private keys, public
|
||||
trust state, signed manifests/channel indexes/revocation lists, customer licenses and binding data,
|
||||
artifact payloads, active/last-known-good platform state, model weights, customer-created data,
|
||||
credentials, audit/evidence and recovery media.
|
||||
|
||||
Considered adversaries include:
|
||||
|
||||
- an internet/on-path attacker controlling DNS, proxy, mirror or download responses;
|
||||
- a malicious or compromised build dependency, source account, builder, signing operator, publisher
|
||||
or support insider;
|
||||
- an attacker who can replace or modify USB/removable media before or during customer use;
|
||||
- a local unprivileged user, malicious administrator action, or malware attempting unsafe import;
|
||||
- a customer/operator mistake, power loss, disk exhaustion or clock manipulation;
|
||||
- an attacker replaying an older valid artifact, trust bundle, license or evidence package; and
|
||||
- a party attempting to infer customer identity, entitlement, model use or data from diagnostics.
|
||||
|
||||
## Trust Boundaries and Data Flows
|
||||
|
||||
| Boundary | Untrusted input crossing it | Required decision before trust |
|
||||
|---|---|---|
|
||||
| Source/dependency to builder | Source tree, packages, images, models, toolchains | Immutable revision/digest, license and inventory approval; isolated reproducible build |
|
||||
| Builder to signing boundary | Artifact, manifest, SBOM, provenance, evidence | Independent digest reconciliation and approved signing request |
|
||||
| Signing to publisher/archive | Signatures, receipts, channel/trust metadata | Purpose/namespace/policy verification and immutable storage |
|
||||
| Network/removable media to appliance | ISO, payload, model/update/license/trust bundle | Local fail-closed signature, schema, compatibility, capacity and object verification |
|
||||
| Staging to active system | Extracted files, images, models, migrations, trust/license state | Safe archive handling, complete staged view, checkpoint, atomic activation and health validation |
|
||||
| Active system to recovery | Rollback snapshot, prior tree, backup, recovery trust | Exact checkpoint identity, compatibility, authorization and restore validation |
|
||||
| Appliance to evidence/support | Logs, manifests, packet capture, diagnostics | Allowlist/redaction, integrity index, actor authorization and bounded retention |
|
||||
|
||||
Network availability, transport encryption, a removable-media label, filename, mutable tag, local
|
||||
administrator assertion or checksum delivered beside an artifact are never sufficient trust anchors.
|
||||
|
||||
## Threat and Control Register
|
||||
|
||||
| ID | Threat / abuse case | Required prevention or detection | Acceptance evidence |
|
||||
|---|---|---|---|
|
||||
| TM-01 | Source or dependency substitution | Exact revision/digest inventory, approved licenses, SBOM/provenance, independent rebuild comparison | Tampered/mutable input rejected; inventory and rebuild reconcile |
|
||||
| TM-02 | Builder injects undeclared content | Builder cannot sign; signed manifest covers every object; extracted artifact reconciled independently | Undeclared/missing/changed object negatives fail |
|
||||
| TM-03 | Signing key theft or misuse | Separate trust domains, purpose constraints, offline root, dual control, receipts, rotation/revocation | Wrong-domain/purpose/operator/approval cases fail; ceremony evidence exists |
|
||||
| TM-04 | Publisher, mirror, DNS or proxy substitutes bytes | Appliance verifies embedded root, signature, manifest and object digests; signed channel mapping | MITM/mirror replacement and TLS/customer-CA cases fail before mutation |
|
||||
| TM-05 | USB is altered, partially written or mislabeled | Whole-media published digest/signature before use plus independent embedded-payload verification | Bit flip, truncation, wrong product/architecture/tier rejected |
|
||||
| TM-06 | Replay/downgrade of valid old content | Monotonic trust sequence, security floor, compatible from/to ranges and explicit break glass | Old artifact/trust/license replay cases fail or require evidenced recovery authority |
|
||||
| TM-07 | Malicious archive escapes staging or exhausts resources | Non-executable quarantine, path/link/device checks, declared size/count limits and reserved space | Traversal, link, device, duplicate path and decompression-limit vectors fail |
|
||||
| TM-08 | Category/tier/license bypass | One canonical entitlement evaluation, required binding, explicit staging allowlist, no compatibility default as entitlement | Wrong tier/category, absent binding, expired/revoked and staging abuse fail consistently |
|
||||
| TM-09 | Hidden network dependency or data egress | Exact zero-network contract, attempted-fetch capture, local-only required payloads, remote connectors unavailable | No-route plus air-gap runs classify attempts; any dependency fetch attempt fails acceptance |
|
||||
| TM-10 | Partial activation creates mixed trusted state | Side-by-side staging, complete verification, atomic switch, durable operation and health-gated commit | Power loss at every mutating boundary yields declared prior/new/recovery state |
|
||||
| TM-11 | Rollback restores incompatible or incomplete state | Full affected-surface checkpoint, schema/data compatibility, last-known-good retention and restore evidence | Rollback and rollback-failure cases reconcile application, data and trust state |
|
||||
| TM-12 | Shared model object deleted while referenced | Exact-digest reference graph, transactional decrement, holds and reconciliation | Shared/dependent pack uninstall and interrupted GC preserve all references |
|
||||
| TM-13 | Revocation or withdrawal bricks recovery/destroys data | New activation fails closed; signed behavior directive; diagnostics/export/recovery preserved | Stale/revoked/emergency cases preserve declared recovery and customer data |
|
||||
| TM-14 | Secrets/customer data leak through logs or evidence | Allowlisted fields, redaction at source/export, role-based access, retention/privacy policy | License, credentials, binding secrets, prompts and model data absent from evidence corpus |
|
||||
| TM-15 | Evidence is forged, omitted or reassigned | Signed/hash-indexed evidence, durable operation IDs, executor/reviewer separation, failed-run retention | Modification/missing-item/wrong-reviewer checks fail evidence gate |
|
||||
| TM-16 | Insider alone builds, signs and publishes | Separation of duties and two-person stable-release approval bound to exact digests | Role-conflict and approval-mismatch release requests fail |
|
||||
| TM-17 | Clock manipulation bypasses expiry/not-before | Signed policy, clock confidence/rollback detection, monotonic sequence and explicit disconnected-time rules | Future/expired/rollback/uncertain-time matrix produces identical fail-closed decisions |
|
||||
| TM-18 | Unsupported GPU/architecture is advertised as ready | Architecture boundary, hardware-adaptive profiles, signed compatibility rules and truthful degradation | AMD64/ARM64 mismatch and unsupported accelerator profiles cannot claim supported acceleration |
|
||||
|
||||
## Security State Invariants
|
||||
|
||||
At every durable operation boundary:
|
||||
|
||||
1. Active content maps to verified signed manifests and a non-revoked permitted trust path.
|
||||
2. No staged/quarantined object is runtime-visible.
|
||||
3. Entitlement can restrict signed content but signed content cannot broaden entitlement.
|
||||
4. Active, last-known-good, dependency and evidence-held objects cannot be garbage-collected.
|
||||
5. Trust/security-floor sequence never decreases through an ordinary import or rollback.
|
||||
6. A failure before activation leaves the prior state active; a failure after the switch either rolls
|
||||
back to an evidenced checkpoint or visibly enters `recovery_required`.
|
||||
7. Customer data, recovery access and non-secret evidence survive license/artifact rejection unless
|
||||
an approved, signed emergency rule explicitly requires a narrower action.
|
||||
8. Product readiness never hides unavailable required capability or an attempted external dependency.
|
||||
|
||||
## Abuse and Interruption Test Set
|
||||
|
||||
Gate evidence MUST include automated fixtures where possible and controlled physical runs where the
|
||||
boundary is physical. Minimum cases are:
|
||||
|
||||
- compromised/mutable dependency and undeclared build output;
|
||||
- tampered, truncated, unsigned, unknown-key, wrong-purpose, revoked, expired and replayed artifacts;
|
||||
- wrong product/category/tier/architecture/platform/runtime and insufficient disk/RAM/VRAM;
|
||||
- hostile archives, partial removable media and content-size mismatch;
|
||||
- DNS/proxy/mirror interception for Online Universal and no-route attempted-fetch capture offline;
|
||||
- license signature, binding, time, staging, expiry, revocation, replacement and rehost abuse;
|
||||
- power loss at verification, extraction, checkpoint, activation, reboot, validation and rollback;
|
||||
- model dependency/reference/GC failure and update rollback failure;
|
||||
- evidence tampering, role conflict, secret injection and missing independent review; and
|
||||
- signing subordinate compromise and compromised-root tabletop recovery.
|
||||
|
||||
Each case records threat ID, precondition, exact artifact/policy identities, expected safe state,
|
||||
observed state, non-secret reason code, packet/storage/service evidence, executor and independent
|
||||
reviewer. A failed control blocks the relevant artifact gate; manually repaired runs are not accepted.
|
||||
|
||||
## Residual Risks and Required Decisions
|
||||
|
||||
The following remain owner decisions rather than assumed controls:
|
||||
|
||||
- approved Secure Boot/firmware/TPM baseline and whether measured boot/remote attestation is required;
|
||||
- production build isolation, dependency-mirror governance and reproducibility target;
|
||||
- signing hardware, custody, revocation age and compromised-root recovery design;
|
||||
- administrator/root threat boundary, disk encryption and physical media chain-of-custody expectations;
|
||||
- offline evidence signing device/key and support evidence transport/privacy rules;
|
||||
- maximum archive object/count/expansion limits and quarantine quotas;
|
||||
- anti-rollback floor ownership and break-glass authorization; and
|
||||
- incident severity, notification, forensic retention and mandatory deactivation criteria.
|
||||
|
||||
Gate 1 cannot pass until Security, Platform, Release, Product and Support owners accept or amend the
|
||||
threat register, assign each residual risk, and approve the minimum test inventory.
|
||||
@@ -0,0 +1,118 @@
|
||||
# Model-Pack Lifecycle Contract
|
||||
|
||||
## Scope and Invariants
|
||||
|
||||
This contract governs separately signed optional model packs after an appliance has completed its
|
||||
base installation. It applies to Workstation and every Server tier. A model pack is data and runtime
|
||||
metadata, not boot media, a platform update, or a license. Installing or retaining a pack MUST NOT
|
||||
grant entitlement, change product category/tier, silently replace the platform runtime, or make the
|
||||
base appliance dependent on removable media.
|
||||
|
||||
All operations use the durable phases `received`, `verifying`, `quarantined`, `staged`, `activating`,
|
||||
`active`, `deactivating`, `removed`, `failed_safe`, or `recovery_required`. The appliance records the
|
||||
pack manifest digest, operation/correlation ID, actor, timestamps, compatibility decision, referenced
|
||||
content digests, storage changes and terminal result without recording license secrets or model data.
|
||||
|
||||
## Import and Quarantine
|
||||
|
||||
1. Copy incoming bytes into a non-executable, non-runtime-visible quarantine directory on the target
|
||||
filesystem. Partial copies use a unique operation path and are never content-addressed as trusted.
|
||||
2. Enforce configured quarantine capacity before copy and reserve activation plus rollback headroom.
|
||||
3. Verify trust/revocation policy, detached signature, schema, compatibility, entitlement,
|
||||
architecture/runtime prerequisites, every object digest and unpacked-size declaration before any
|
||||
object becomes usable by a model runtime.
|
||||
4. Reject archives with absolute paths, traversal, links escaping staging, special devices,
|
||||
duplicate/conflicting paths, undeclared content, decompression beyond declared limits, or unsafe
|
||||
ownership/mode metadata.
|
||||
5. On verification failure, preserve the manifest, reason code and bounded diagnostic evidence.
|
||||
Payload bytes remain quarantined for the approved investigation period or are securely deleted by
|
||||
policy; they MUST NOT enter the trusted object store.
|
||||
6. An interrupted copy or verification resumes only after revalidating the received extent and then
|
||||
repeats complete verification. The previously active model set remains unchanged.
|
||||
|
||||
Quarantine reason codes include `signature_invalid`, `key_untrusted`, `key_revoked`,
|
||||
`policy_stale`, `manifest_invalid`, `object_digest_mismatch`, `archive_unsafe`, `incompatible`,
|
||||
`not_entitled`, `insufficient_space`, and `interrupted_incomplete`.
|
||||
|
||||
## Content-Addressed Sharing and Activation
|
||||
|
||||
Verified immutable objects enter a trusted store keyed by algorithm and digest. A transaction creates
|
||||
or increments references only after all objects for the pack are present. Sharing is allowed only for
|
||||
byte-identical objects with the same digest; filenames, model names or upstream revisions alone are
|
||||
not identity. Each active pack has an immutable installation record that maps its manifest digest to
|
||||
all object digests and its activation metadata.
|
||||
|
||||
Activation writes a complete side-by-side runtime view and atomically publishes that view. Health
|
||||
validation MUST prove local discovery and the declared smoke inference without network access. Until
|
||||
validation passes, the prior active view and its references remain rollback-protected. Failure removes
|
||||
the candidate view/references or marks `recovery_required`; it never leaves a partly visible pack.
|
||||
|
||||
A pack MAY depend on another pack only through exact artifact ID plus accepted version range and
|
||||
required object/capability declarations in its signed manifest. Dependency cycles fail closed. The
|
||||
importer MUST show the full dependency and additional-space plan before confirmation and MUST NOT
|
||||
fetch a missing dependency from a network.
|
||||
|
||||
## Deactivation, Uninstall and Garbage Collection
|
||||
|
||||
Deactivation removes a pack from runtime selection without deleting its trusted objects. Uninstall is
|
||||
an explicit authorized operation and MUST:
|
||||
|
||||
1. show affected active profiles, dependent packs, freed-space estimate and whether model-created
|
||||
customer data is retained;
|
||||
2. block while active operations use the pack unless the operator safely drains/cancels them;
|
||||
3. block removal of a required dependency unless dependents are removed in the same approved plan;
|
||||
4. atomically publish a runtime view without the pack, validate the remaining model set, and only then
|
||||
decrement its object references; and
|
||||
5. retain audit/evidence and customer-created data according to policy. Uninstalling model weights
|
||||
MUST NOT silently delete prompts, indexes, fine-tunes, evaluations or other customer data.
|
||||
|
||||
Garbage collection deletes only trusted objects with zero active, staged, dependency, rollback,
|
||||
evidence-hold or support-hold references. It uses a mark-and-sweep plan recorded before deletion,
|
||||
rechecks references inside the deletion transaction, and records actual reclaimed bytes. Interrupted
|
||||
garbage collection is idempotent: immutable objects are either present and digest-valid or absent and
|
||||
unreferenced. Object-store reconciliation MUST detect missing referenced objects and orphaned objects;
|
||||
missing referenced content blocks model readiness, while orphans remain unavailable until reviewed.
|
||||
|
||||
## Entitlement and License Change
|
||||
|
||||
Entitlement is evaluated independently at every activation and runtime selection. A valid installed
|
||||
pack can therefore be `installed_inactive` when the current license, category, tier or policy does not
|
||||
authorize use.
|
||||
|
||||
| Change | Required behavior |
|
||||
|---|---|
|
||||
| License expires or is revoked | Stop new inference for affected packs after the approved continuity rule; safely finish/cancel in-flight work; retain weights and customer data during the approved grace/appeal period |
|
||||
| Replacement license restores entitlement | Re-evaluate installed pack without re-import; activate only after current trust, compatibility and health checks pass |
|
||||
| Tier/category downgrade | Disable affected packs; do not relabel them as a lower tier or delete them automatically |
|
||||
| Tier/category upgrade | Previously installed pack may become eligible but requires explicit activation and current checks |
|
||||
| Machine rehost | Pack bytes may be migrated only through an approved signed export/import or original media; entitlement is re-evaluated on the target |
|
||||
| Pack redistribution license changes upstream | Existing signed release remains governed by its captured license/notice and Cezen distribution decision; new distribution stops until legal approval, without remotely deleting customer content |
|
||||
| Security withdrawal | Signed withdrawal/trust policy blocks new activation and states whether deactivation or removal is mandatory; customer data and evidence remain recoverable |
|
||||
|
||||
Model media MUST carry the exact upstream license text, required notices, redistribution decision and
|
||||
source/revision attribution used for that release. A later license-text change cannot mutate an
|
||||
already signed pack; it requires a new pack version or withdrawal record.
|
||||
|
||||
## Interruption and Recovery Evidence
|
||||
|
||||
Acceptance tests MUST interrupt: media copy, archive extraction, object-store commit, reference
|
||||
transaction, runtime-view switch, health validation, uninstall view switch, reference decrement and
|
||||
garbage collection. For each point, evidence proves one declared result: safe resume, safe restart,
|
||||
automatic rollback, or `recovery_required` with an intact previous view. Tests also cover two packs
|
||||
sharing objects, dependency removal refusal, license downgrade/restore, malicious archives, partial
|
||||
media, insufficient quarantine/activation space, orphan reconciliation and a missing referenced
|
||||
object.
|
||||
|
||||
Gate 5 passes only when the installed-pack inventory, object reference graph, runtime-visible view,
|
||||
entitlement decision, actual disk usage and evidence record agree after every clean and interrupted
|
||||
scenario. Independent review is required before general release.
|
||||
|
||||
## Owner Decisions Still Required
|
||||
|
||||
- Quarantine location, byte quota, failed-payload retention and secure-deletion policy.
|
||||
- Trusted object-store layout, transaction mechanism, reference database and reconciliation owner.
|
||||
- Drain/cancel timeout, activation smoke inference and rollback retention window.
|
||||
- Customer-data classification and retention/export behavior for pack-created artifacts.
|
||||
- License expiry continuity/grace, downgrade and rehost behavior, plus legal owner for redistribution.
|
||||
- Security-withdrawal authority and mandatory-deactivation/removal conditions.
|
||||
- Garbage-collection schedule, low-disk trigger, evidence/support holds and break-glass recovery owner.
|
||||
@@ -0,0 +1,164 @@
|
||||
# Zero-Network License and Activation Policy
|
||||
|
||||
**Status**: Approval draft; no implementation authority.
|
||||
|
||||
## Goals
|
||||
|
||||
Nexus One AI licensing MUST be independently verifiable with no network, distinguish product category
|
||||
from Server tier, preserve customer data through license-state changes, and never convert missing,
|
||||
invalid, expired, time-uncertain, revoked, or machine-mismatched material into a valid entitlement.
|
||||
|
||||
Release artifact signatures and customer license signatures are separate trust domains. The current
|
||||
RSA-SHA256 `cezen.license.v2` format remains compatible until an approved migration changes it.
|
||||
|
||||
## Observed Existing Behavior and Gaps
|
||||
|
||||
- The canonical evaluator verifies RSA-SHA256, `issued_at`, `expires_at`, optional machine binding,
|
||||
tier and feature overrides locally.
|
||||
- A missing license returns `field-staging`, `needs_activation: true`, and compatibility tier `basic`.
|
||||
- Invalid signatures, future-issued, expired, and machine-mismatched licenses are not valid, but their
|
||||
normalized `allowed_tier` can still remain available to surrounding code unless every consumer also
|
||||
honors `valid/staging_only`.
|
||||
- Machine binding is enforced only when the caller supplies `machine_id`; current CLI flows can omit it.
|
||||
- No signed offline license-revocation list, trustworthy-clock state, backward-clock detection, or
|
||||
durable last-known-good license-evaluation time is defined.
|
||||
|
||||
These are planning blockers. A `basic` compatibility default is not evidence of a Server M
|
||||
entitlement, and an omitted machine ID cannot make a bound license portable.
|
||||
|
||||
## Required License Envelope
|
||||
|
||||
A production signed license MUST declare schema/version, unique license ID, customer/project ID,
|
||||
product category (`workstation` or `server`), exact Workstation entitlement or Server tier ceiling,
|
||||
issued-at, optional not-before, expiry/support policy, feature overrides, machine-binding mode/value,
|
||||
license-policy version, signing-key ID, and signature algorithm/signature. Optional fields never
|
||||
weaken the default policy.
|
||||
|
||||
Customer-visible and diagnostic views expose only an allowlisted summary. Raw signature, license key,
|
||||
customer identifiers beyond approved display fields, and machine-binding source values are excluded
|
||||
from logs and support exports.
|
||||
|
||||
## Offline Import and First Activation
|
||||
|
||||
1. Import from approved removable media or local browser/console input; copy to a protected staging
|
||||
path and never execute content from that media.
|
||||
2. Parse size-bounded canonical JSON and reject duplicate keys, unknown critical fields, unsupported
|
||||
schema/algorithm, malformed dates, and invalid category/tier combinations.
|
||||
3. Verify the license-signing key and signature using the embedded approved license trust store.
|
||||
4. Resolve a stable device identity locally and evaluate binding whenever the license declares one.
|
||||
Failure to obtain the identity is `binding_unavailable`, not a binding bypass.
|
||||
5. Evaluate trustworthy-clock state, issued/not-before/expiry, offline revocation policy, product,
|
||||
hardware/provisioning constraints, and feature overrides.
|
||||
6. Display the exact resulting state and allowed actions before activation.
|
||||
7. Persist the signed license atomically with root-owned least-privilege permissions, record only a
|
||||
redacted audit summary, then re-evaluate from the persisted copy.
|
||||
|
||||
No online activation callback is required for a license designed for offline use.
|
||||
|
||||
## License States and Behavior
|
||||
|
||||
| State | Meaning | Required behavior |
|
||||
|---|---|---|
|
||||
| `valid` | Signature, policy, time, revocation, category/tier and binding pass | Enable only licensed + provisioned + hardware-supported + healthy capabilities |
|
||||
| `missing` | No license supplied | Enter explicit field-staging mode only when operator chose it; never infer a purchased tier |
|
||||
| `invalid_signature` / `unsupported` | Untrusted or unreadable artifact | Reject import; do not alter active valid license or entitlement |
|
||||
| `not_yet_valid` | Trusted license before allowed start | Preserve existing valid entitlement if applicable; otherwise restricted/staging state |
|
||||
| `expired` | Trusted license beyond expiry policy | Preserve data, backup/export and license replacement; restrict gated operations per approved expiry matrix |
|
||||
| `machine_mismatch` | Bound identity differs | Reject activation; preserve existing valid license; provide redacted device/support reference |
|
||||
| `binding_unavailable` | Required identity cannot be derived | Fail closed for activation; allow local diagnostics/retry |
|
||||
| `revoked` | License ID or signing key is on trusted offline revocation data | Enter restricted recovery-safe state; never delete data/models |
|
||||
| `clock_uncertain` | Current time cannot be trusted sufficiently | Do not newly activate a time-bounded license; preserve safe existing state per continuity rule |
|
||||
| `clock_rollback` | Clock moved behind durable last-known-good evaluation beyond tolerance | Block new activation/renewal and gated mutations; require authorized clock recovery |
|
||||
|
||||
## Field-Staging Contract
|
||||
|
||||
Field staging is a deliberate installation state, not a free Server tier and not a fallback for an
|
||||
invalid license. It permits only the approved staging allowlist needed to configure network, inspect
|
||||
hardware, import a license, validate artifact identity, view local help, collect redacted diagnostics,
|
||||
perform backup/export, and prove core readiness.
|
||||
|
||||
General customer AI use, tier-gated Server capabilities, optional model packs, production data import,
|
||||
and update actions above the staging maintenance allowance remain disabled unless a valid signed
|
||||
license or separately signed time-bounded evaluation license authorizes them.
|
||||
|
||||
The current `STAGING_MAX_TIER=basic` remains an internal compatibility value only and MUST NOT be used
|
||||
as authorization. Product/security owners must approve the staging capability allowlist, duration,
|
||||
evaluation-license process, and whether an unsigned staging install may persist indefinitely in a
|
||||
non-production restricted state.
|
||||
|
||||
## Clock Confidence Without Network
|
||||
|
||||
The appliance records UTC reading, clock source/confidence, boot ID, and the highest trusted license
|
||||
evaluation time in tamper-evident local state. It compares RTC/current time with signed license dates,
|
||||
signed update/build times, and last-known-good evaluation. NTP is helpful but never mandatory.
|
||||
|
||||
- A normal forward clock continues evaluation.
|
||||
- A small approved tolerance accommodates RTC drift; the exact tolerance requires security approval.
|
||||
- A backward move beyond tolerance becomes `clock_rollback`.
|
||||
- No trustworthy time on first activation of a time-bounded license becomes `clock_uncertain`.
|
||||
- Manual clock correction requires an authorized local action and audit record.
|
||||
- Changing the clock never changes a bad signature, revoked key/license, category, tier or binding.
|
||||
|
||||
## Expiry and Continuity
|
||||
|
||||
Expiry MUST NOT erase customer data, uninstall services/models, invalidate backups, or prevent license
|
||||
replacement and recovery. The approved expiry matrix separately controls existing inference sessions,
|
||||
new sessions/jobs, data ingestion, model import, configuration, updates, user administration,
|
||||
backup/export, restore, diagnostics, and emergency security updates.
|
||||
|
||||
Recommended safe default: block new license-gated workload creation and commercial expansion while
|
||||
allowing read-only access, completion/cancellation of already-running safe work where feasible,
|
||||
backup/export, diagnostics, local help, and license replacement. Exact grace periods and emergency
|
||||
security-update rights require product/security/legal approval and MUST be encoded in the signed policy,
|
||||
not hard-coded differently by UI and backend.
|
||||
|
||||
## Machine Binding
|
||||
|
||||
Binding modes are `none`, `single_device`, or an explicitly approved cluster/appliance mode. Device
|
||||
identity must be stable across reboot and ordinary service/OS updates, replaceable only through a
|
||||
signed rehost/recovery artifact, and derived without exposing raw serials in customer-facing evidence.
|
||||
The binding algorithm/version and hashed identity components are part of license policy.
|
||||
|
||||
Hardware replacement never silently adopts the old binding. The recovery process preserves data,
|
||||
produces a redacted old/new device reference, imports a signed rehost authorization or replacement
|
||||
license, and records the actor and result.
|
||||
|
||||
## Offline Revocation and Trust Updates
|
||||
|
||||
A root-signed license trust/revocation bundle contains version, issued/expires policy, revoked license
|
||||
IDs, revoked signing-key IDs, reasons suitable for operators, replacement trust roots, and signature.
|
||||
It is imported through the shared trust-bundle mechanism and verified before replacing active policy.
|
||||
|
||||
Stale revocation data behavior must distinguish new activation from continuity of an already-valid
|
||||
installed license. Recommended default: block new license activation when revocation policy exceeds
|
||||
its approved maximum age; warn and preserve a currently operating non-revoked license until the
|
||||
approved continuity limit, while retaining backup/export and recovery. Exact ages require approval.
|
||||
|
||||
## Interruption and Recovery
|
||||
|
||||
- Interrupted copy/parse/verification leaves the active license unchanged and staging quarantined.
|
||||
- Interruption after atomic persistence re-evaluates the persisted artifact on reboot.
|
||||
- A rejected replacement never overwrites an existing valid license.
|
||||
- Trust-bundle interruption retains the prior trusted policy.
|
||||
- Clock or binding recovery resumes the same durable activation operation.
|
||||
- If entitlement decreases, stop new gated work first; do not corrupt in-flight work or delete data.
|
||||
- License removal is authorized/audited and moves to explicit staging/restricted state; it never
|
||||
fabricates `basic` entitlement.
|
||||
|
||||
## Evidence Gate
|
||||
|
||||
Test valid Workstation and each Server tier; deliberate staging; missing; malformed; duplicate-key;
|
||||
unsupported schema/algorithm; invalid signature; future-issued/not-before; expiry boundary; clock
|
||||
uncertain; backward clock; machine match/mismatch/unavailable/rehost; category/tier mismatch; feature
|
||||
override; revoked license/key; stale revocation policy; interrupted import/persist/trust update; license
|
||||
replacement; entitlement reduction; reboot persistence; and denied-role access. Verify every surface
|
||||
reports the same state and no raw license/binding secret enters logs or support evidence.
|
||||
|
||||
## Owner Decisions Still Open
|
||||
|
||||
- Staging allowlist, duration and signed evaluation-license process.
|
||||
- Expiry/grace/continuity matrix and emergency security-update rights.
|
||||
- Device identity inputs, hashing/version, rehost authority and cluster binding.
|
||||
- Clock tolerance, trustworthy-first-time procedure and authorized correction role.
|
||||
- License revocation maximum age and stale-policy continuity limit.
|
||||
- License signing-key custody/rotation relationship to the separate artifact-signing trust domain.
|
||||
@@ -0,0 +1,165 @@
|
||||
# Offline Validation Lab and Evidence Ownership
|
||||
|
||||
**Status**: Approval and execution plan; no build or deployment authority.
|
||||
|
||||
## Purpose
|
||||
|
||||
The lab proves that an artifact satisfies its declared connectivity, hardware, trust, interruption,
|
||||
recovery, update/model, entitlement and evidence contracts. A passing container/service check is not
|
||||
an installation proof, and a passing source test is not packaged-artifact evidence.
|
||||
|
||||
## Isolation Topology
|
||||
|
||||
Each offline run uses a dedicated target attached only to an instrumented isolation switch or test
|
||||
host. The isolation environment provides no route to customer, corporate or public networks.
|
||||
|
||||
- Disable/remove Wi-Fi, Bluetooth networking, cellular, secondary Ethernet, IPMI/BMC shared-network
|
||||
routes and hypervisor NAT/bridged adapters before boot.
|
||||
- The target MAY connect to a capture-only Ethernet segment with no DHCP, DNS, gateway, proxy, mirror,
|
||||
registry, NTP or responder. Packet capture records attempted traffic without satisfying it.
|
||||
- Loopback remains available for local services. A local browser may use a directly connected
|
||||
capture-segment address only after the OS is installed; this does not create an external dependency.
|
||||
- For physical-air-gap confirmation, repeat one accepted run with every data network cable physically
|
||||
disconnected and use local console plus post-run local evidence export.
|
||||
- BMC management, power control and serial console MUST use a physically/logically separate lab
|
||||
management plane that is not visible as a target OS interface.
|
||||
|
||||
## Attempted-Network Detection
|
||||
|
||||
Acceptance requires both outside observation and target evidence:
|
||||
|
||||
1. Capture all packets on the isolation segment from pre-boot through final evidence export using
|
||||
synchronized lab timestamps.
|
||||
2. Record link state, interface inventory, routes, resolver configuration, proxy variables, sockets,
|
||||
firewall counters and package/container/model client logs before and after installation.
|
||||
3. Classify every non-loopback packet by source process where locally observable, destination,
|
||||
protocol, stage and whether the attempt was required, optional or unexpected.
|
||||
4. Any attempted dependency fetch—DNS, HTTP(S), Git, APT, pip/Conda, container registry, model registry,
|
||||
license, telemetry or time service—is a failure even when retry/fallback eventually succeeds.
|
||||
5. Essential local IPv6 discovery or link-local traffic is documented separately; it cannot carry a
|
||||
dependency and SHOULD be disabled when not required by the supported product.
|
||||
|
||||
Packet capture with zero successful responses is necessary but insufficient: a client that attempted
|
||||
an external fetch still fails the offline claim.
|
||||
|
||||
## Representative Hardware Matrix
|
||||
|
||||
### Offline Workstation AMD64 — first target
|
||||
|
||||
| Profile | Required representative target | Acceptance focus |
|
||||
|---|---|---|
|
||||
| Core/CPU fallback | AMD64, no supported NVIDIA GPU or sub-8 GB usable VRAM | Core platform readiness; truthful disabled local GPU/vLLM state |
|
||||
| GPU lite | Supported NVIDIA GPU with 8 GB usable VRAM | Small Ollama chat and embedding; vLLM/fine-tuning disabled |
|
||||
| GPU starter | Supported NVIDIA GPU with 24–32 GB usable VRAM | Ollama plus approved vLLM starter inference; RTX 4090/5090-class behavior |
|
||||
| GPU standard | Supported NVIDIA GPU with at least 48 GB usable VRAM | Higher-capacity single-GPU profile and memory checks |
|
||||
|
||||
At least one lower-profile target and one GPU target MUST be physical hardware. VM-only acceptance is
|
||||
insufficient for GPU driver, reboot, firmware, storage and power-loss evidence. AMD GPU/ROCm and ARM64
|
||||
DGX Spark are outside the first release.
|
||||
|
||||
### Server artifacts
|
||||
|
||||
- Online Universal Server: one supported S, M, L and Max selection case across enough hardware to
|
||||
exercise license/hardware allowed and denied boundaries; network failure tests use a controlled
|
||||
routed lab rather than the offline segment.
|
||||
- Offline Server S/M: one representative S and one M physical target.
|
||||
- Offline Server L/Max: one representative L and one Max target unless the approved payload/support
|
||||
distinction defines a smaller justified matrix. Multi-GPU topology must be real where claimed.
|
||||
|
||||
Final machine make/model, firmware, storage controller, disk size, GPU, RAM, NIC, Secure Boot state,
|
||||
OS architecture and evidence owner are approval fields in the release candidate.
|
||||
|
||||
## Clean-Run Matrix
|
||||
|
||||
For each offline artifact/profile combination:
|
||||
|
||||
1. Securely erase/reset the target to the documented clean baseline.
|
||||
2. Verify ISO whole-artifact digest/signature before flashing/attachment.
|
||||
3. Record media identity, target hardware/firmware and isolation proof.
|
||||
4. Boot, install OS, complete first boot, validate embedded payload, configure license/staging and
|
||||
reach truthful ready/degraded state with no undocumented intervention.
|
||||
5. Reboot twice: once normally and once at the declared interruption boundary.
|
||||
6. Validate portal/API/authentication, entitlement/profile, local help, backup/export, services,
|
||||
starter chat and embedding where supported, and vLLM only on approved profiles.
|
||||
7. Export redacted evidence locally and reconcile installed inventory with the signed manifest.
|
||||
|
||||
Minimum release gate is three clean runs per offline ISO, including at least two physical targets and
|
||||
one interruption run. Repeated runs on the same uncleared installation do not count as clean runs.
|
||||
|
||||
## Interruption Injection
|
||||
|
||||
Injection points are mapped to durable operation phases and use controlled power removal, forced
|
||||
reboot, process/service termination, media removal, disk-full/fault simulation, or corrupted test
|
||||
object as appropriate.
|
||||
|
||||
Required boundaries include OS install before/after disk commit, first boot, manifest/object
|
||||
verification, extraction/staging, database checkpoint/migration, application pointer switch, service
|
||||
restart, awaiting reboot, health validation, model import/activation, update activation, automatic
|
||||
rollback and restore-based rollback. Each injection is performed on disposable or recoverable targets
|
||||
with the expected outcome written before execution.
|
||||
|
||||
An interruption passes only when active application inventory, data/schema, selected category/tier or
|
||||
Workstation profile, services and durable evidence converge on the declared state without hidden lab
|
||||
repair.
|
||||
|
||||
## Negative Security and Compatibility Matrix
|
||||
|
||||
Test unsigned/tampered/unknown/revoked/stale-policy artifacts; wrong architecture/category/tier/OS;
|
||||
expired/not-yet-valid/mismatched/binding-unavailable license; clock uncertainty/rollback; insufficient
|
||||
RAM/VRAM/disk; corrupted cache; duplicate/conflicting operation; unsafe archive paths; extra/missing
|
||||
payload objects; rollback below security floor; and unauthorized roles.
|
||||
|
||||
Negative fixtures use test keys and synthetic data. Production private keys and customer content never
|
||||
enter the lab evidence repository.
|
||||
|
||||
## Evidence Package
|
||||
|
||||
Each run produces a signed/hashed evidence index containing:
|
||||
|
||||
- run ID, artifact ID/version/digest/signature, source revision and working-tree state;
|
||||
- target hardware/firmware/architecture, storage, interfaces and Secure Boot state;
|
||||
- isolation setup, capture-interface identity, capture digest and classified packet-attempt report;
|
||||
- exact operator script, timestamps, boot IDs and injected fault;
|
||||
- installed object/application/container/runtime/model/schema/license-policy inventory;
|
||||
- operation/audit correlation IDs and redacted installer/service logs;
|
||||
- readiness, service, portal/API, local inference and reboot results;
|
||||
- disk/media/staging/rollback peak measurements;
|
||||
- expected versus actual recovery state, deviations, severity and disposition;
|
||||
- author, independent witness/reviewer and approval status.
|
||||
|
||||
Raw packet capture, logs and screenshots remain controlled lab attachments. Repository evidence stores
|
||||
non-sensitive summaries, checksums and approved redactions rather than credentials or customer data.
|
||||
|
||||
## Evidence Gates and Owners
|
||||
|
||||
| Gate | Responsible | Independent reviewer/accountable approval |
|
||||
|---|---|---|
|
||||
| Lab isolation and capture readiness | QA/test engineer | Security owner |
|
||||
| Hardware/firmware baseline | Delivery engineer | Delivery/support owner |
|
||||
| Artifact identity and inventory | Platform release engineer | Security + product owners |
|
||||
| Workstation profile/model checks | AI/platform engineer | Product owner |
|
||||
| Server tier and entitlement matrix | Platform/license engineer | Product + delivery owners |
|
||||
| Interruption/update/rollback | Platform + data engineers | Delivery/support owner |
|
||||
| Accessibility/customer journey | QA/product | Product owner |
|
||||
| Final release evidence | Release coordinator | Product and delivery/support joint approval; security joins for trust/security-floor changes |
|
||||
|
||||
The executor cannot be the sole approver of the same evidence. Failed critical safety, integrity,
|
||||
entitlement, recovery or zero-network findings block promotion until corrected and independently rerun.
|
||||
|
||||
## Stop/Retry Rules
|
||||
|
||||
- Preserve failed evidence before resetting a target.
|
||||
- Do not patch the target manually and continue the same acceptance run.
|
||||
- A test-tool or lab-infrastructure failure is `INVALID`, not `PASS` or product `FAIL`; rerun from a
|
||||
clean baseline after documenting the cause.
|
||||
- Three consecutive product failures at the same boundary trigger design review before more retries.
|
||||
- Any external dependency attempt, signature bypass, secret exposure, silent data loss or ambiguous
|
||||
active version is critical.
|
||||
|
||||
## Open Assignments
|
||||
|
||||
- Named people for each responsible/reviewer role and separation-of-duty confirmation.
|
||||
- Physical hardware make/models, lab location, switch/capture/BMC topology and reservation dates.
|
||||
- Approved capture and fault-injection tools, time synchronization method and evidence retention.
|
||||
- Test data/model prompts, expected outputs/tolerances and accessibility participants.
|
||||
- Severity/SLA policy, controlled-pilot targets and final evidence repository/access controls.
|
||||
@@ -0,0 +1,110 @@
|
||||
# Online Universal Server Acquisition Contract
|
||||
|
||||
**Status**: Approval draft; no implementation authority.
|
||||
|
||||
## Purpose and Boundary
|
||||
|
||||
The Online Universal Server ISO boots and installs the supported Ubuntu base, performs local hardware
|
||||
and license preflight, permits Server S/M/L/Max selection, then acquires the exact signed platform
|
||||
payload for the approved release. Network access is required, but network availability never replaces
|
||||
artifact authenticity, compatibility, or rollback checks.
|
||||
|
||||
The current implementation clones the default branch from
|
||||
`https://cgit.cezentech.com/jinojose/aipackage.git` during Ubuntu late commands and subsequently allows
|
||||
APT, Python, container, runtime, and model tooling to fetch mutable dependencies. This is observed
|
||||
legacy behavior, not the accepted release contract.
|
||||
|
||||
## Approved Endpoint Classes
|
||||
|
||||
Every release candidate MUST provide an explicit allowlist containing scheme, hostname, port,
|
||||
certificate policy, purpose, authentication method, and whether access occurs before or after target
|
||||
disk mutation. No wildcard hostname is allowed.
|
||||
|
||||
| Endpoint class | Required purpose | Contract |
|
||||
|---|---|---|
|
||||
| Release index | Discover one approved release manifest by channel/version | HTTPS; small signed index; no executable content |
|
||||
| Content store | Download content-addressed payload objects | HTTPS; object path bound to SHA-256; range/resume supported |
|
||||
| Ubuntu/package sources | Acquire pinned OS/package objects not embedded in media | Approved mirrors only; repository metadata and package signatures verified |
|
||||
| Container registry | Acquire pinned images | Digest references only; registry authentication scoped read-only |
|
||||
| License service | Optional online license acquisition/refresh where policy permits | Separate authenticated endpoint; signed license remains independently verifiable |
|
||||
| Time source | Optional clock confidence | Never establishes artifact authenticity; absence has declared license/policy behavior |
|
||||
|
||||
Git default branches, container tags, `latest` runtime URLs, unauthenticated scripts piped to shells,
|
||||
and model names without immutable revision/digest MUST NOT be release inputs.
|
||||
|
||||
## Acquisition Sequence
|
||||
|
||||
1. Verify local boot-media identity and embedded trust roots.
|
||||
2. Establish network and record interface, DNS, route, proxy, and local clock confidence without
|
||||
recording credentials.
|
||||
3. Fetch the signed release index; verify trust policy, digest, signature, channel, expiry policy, and
|
||||
rollback/security floor before selecting a release.
|
||||
4. Select Server tier only after license and hardware preflight. Tier selection does not change trust.
|
||||
5. Resolve one immutable artifact manifest and evaluate architecture/category/tier/OS/capacity
|
||||
compatibility locally.
|
||||
6. Download objects into a staging area by digest with bounded retries, timeouts, rate limits, and
|
||||
resumable range requests. Partial objects use a non-final name and are never executable.
|
||||
7. Verify every completed object size/digest, then verify the complete signed manifest again.
|
||||
8. Create and verify the declared pre-change checkpoint before platform mutation.
|
||||
9. Activate through the shared durable operation/rollback contract.
|
||||
10. Record release ID, manifest/signature identity, object inventory, endpoint classes used, retry
|
||||
counts, and final state without tokens, passwords, customer content, or full signed licenses.
|
||||
|
||||
## Authentication and TLS
|
||||
|
||||
- TLS certificate and hostname validation is mandatory; insecure/skip-verify modes are prohibited.
|
||||
- The embedded OS CA set is the minimum web PKI trust. A Cezen release-signing signature remains
|
||||
mandatory even when TLS succeeds.
|
||||
- Private content credentials MUST be short-lived, least-privilege, read-only, redacted from command
|
||||
lines/logs, and stored only for the operation lifetime unless an approved refresh policy requires
|
||||
otherwise.
|
||||
- Proxy support MUST preserve TLS validation and provide a customer-visible explanation when TLS
|
||||
interception uses a customer-approved CA. Silent trust-root installation is prohibited.
|
||||
- Redirects across hostnames are rejected unless the destination is independently allowlisted.
|
||||
|
||||
## Retry, Resume, Cache, and Idempotency
|
||||
|
||||
- DNS, connect, TLS, first-byte, idle, and total-operation timeouts are explicit release-policy values.
|
||||
- Retries are bounded exponential backoff with jitter and honor server retry guidance within limits.
|
||||
- A resumed object is retained only when its expected digest and length still match the signed
|
||||
manifest. ETag alone is insufficient identity.
|
||||
- Verified content-addressed objects MAY be reused across attempts and tiers; unverified or partial
|
||||
content is quarantined or deleted.
|
||||
- Re-running acquisition for the same operation ID resumes the same staging inventory. A different
|
||||
manifest creates a new operation and cannot silently replace active staging.
|
||||
|
||||
## Failure and Recovery Contract
|
||||
|
||||
| Failure point | Required outcome |
|
||||
|---|---|
|
||||
| No DHCP/static route/DNS | Target remains at local setup; show network evidence and safe retry |
|
||||
| TLS/certificate/hostname failure | Stop before payload trust; never offer insecure bypass |
|
||||
| Index/manifest unsigned, revoked, stale, or below security floor | Stop before payload download/mutation; preserve redacted evidence |
|
||||
| Authentication denied/expired | Stop or renew through approved flow; do not log credential |
|
||||
| Interrupted object download | Retain only bounded partial staging; safely resume by digest |
|
||||
| Digest/size mismatch | Quarantine/delete object, invalidate cache entry, bounded retry from approved endpoint |
|
||||
| Insufficient disk discovered | Stop before activation; report staging and rollback space separately |
|
||||
| Network loss after full verification, before activation | Activation MAY continue only when every required object is locally verified |
|
||||
| Network loss during activation | Activation outcome depends only on local staged objects; shared rollback contract applies |
|
||||
| Reboot interruption | Resume the same durable operation and never reacquire already verified objects unnecessarily |
|
||||
|
||||
## Evidence Gates
|
||||
|
||||
Before implementation-ready status:
|
||||
|
||||
1. Platform/security owners approve the exact endpoint allowlist and ownership.
|
||||
2. Release-index schema and test vectors extend the shared manifest/signature fixtures.
|
||||
3. Credential source, lifetime, rotation, revocation, proxy, and customer-CA policies are approved.
|
||||
4. Timeout/retry/cache quotas and staging retention are measurable and approved.
|
||||
5. Tests cover DNS, TLS, redirect, proxy, auth, partial content, resume, corrupted cache, manifest
|
||||
replacement, insufficient disk, network loss before/after verification, activation, and reboot.
|
||||
6. A clean install proves the deployed source revision and every acquired object match the accepted
|
||||
manifest; cloning a mutable default branch is a release blocker.
|
||||
|
||||
## Decisions Still Requiring Owners
|
||||
|
||||
- Production release-index and content-store hostnames and responsible operator.
|
||||
- Public versus authenticated payload access and credential issuer.
|
||||
- Approved Ubuntu/package mirrors and any customer-hosted mirror mode.
|
||||
- Proxy/customer CA enrollment workflow.
|
||||
- Supported release channels, index expiry, cache quota/retention, retry/timeouts, and support SLA.
|
||||
@@ -0,0 +1,134 @@
|
||||
# Release Payload Inventory, Deduplication, and Media Sizing
|
||||
|
||||
**Status**: Repository-derived planning baseline; no build authority.
|
||||
**Observed source revision**: `bea082a2014a3edc31cb006108b952c8adbbc8bc` plus the uncommitted
|
||||
specification changes in this task.
|
||||
**Observed artifact fact**: `autoinstall/cezen-ai-ubuntu2204.iso` is 0 bytes and is not usable as a
|
||||
release or sizing baseline.
|
||||
|
||||
## Inventory Rules
|
||||
|
||||
Every payload object has one canonical inventory row containing object ID, class, immutable upstream
|
||||
identity, license, architecture, media type, compressed/download bytes, unpacked bytes, on-target
|
||||
bytes, digest, source URL/repository, included artifacts, activation profiles, dedup group, and evidence
|
||||
status. No bytes are counted from model names, tags, estimates, sparse files, or expected upstream size.
|
||||
|
||||
The release manifest is generated from the finalized inventory. The inventory is not reconstructed
|
||||
from an ISO after publication except as independent verification.
|
||||
|
||||
## Four-Artifact Boundary
|
||||
|
||||
| Artifact | Embedded boundary | Explicit exclusions | Current sizing state |
|
||||
|---|---|---|---|
|
||||
| Online Universal Server | Ubuntu boot/install base, network/preflight/acquisition client, trust roots, signed-index support, local recovery/help | Platform payload, optional/large models and mutable default-branch source | Current checked-in ISO is 0 bytes; no valid measured size |
|
||||
| Offline Workstation AMD64 | Ubuntu base, universal NVIDIA/CPU-adaptive platform superset, required packages/runtimes/images, local help/recovery, approved small starter models | AMD GPU/ROCm, ARM64 DGX Spark, large optional models, customer license/data | Candidate lists exist; no complete built payload or measured ISO |
|
||||
| Offline Server S/M AMD64 | Ubuntu base plus superset required for both S and M; selection restricted to `starter/basic`; small approved starter models only | Server L/Max selection and large models | No complete inventory/build/size evidence |
|
||||
| Offline Server L/Max AMD64 | Ubuntu base plus enterprise platform superset for L and Max; selection restricted to `pro/max`; only approved bootstrap/small validation models | Large L/Max models, which are separate signed packs | No complete inventory/build/size evidence; current roles do not yet prove a distinct payload |
|
||||
|
||||
Architecture is part of artifact identity. Any later Workstation ARM64 media has its own inventory and
|
||||
measurements while remaining the same commercial product category.
|
||||
|
||||
## Repository-Derived Candidate Inventory
|
||||
|
||||
### Common source and trust
|
||||
|
||||
- Exact platform source revision excluding `.git`, ISOs, offline output, user collateral and secrets.
|
||||
- Boot/autoinstall data, first-boot/browser setup, install orchestration and Ansible roles/playbooks.
|
||||
- Portal, backend, local documentation, recovery and diagnostic tooling.
|
||||
- License public key, artifact trust roots, manifest schemas, signature/revocation policy and SBOM.
|
||||
- Ubuntu installer/base identity and boot metadata.
|
||||
|
||||
### Current Workstation offline lists
|
||||
|
||||
- 26 non-comment APT package names.
|
||||
- 15 non-comment additional Python package requirements plus backend requirements and pinned
|
||||
`chromadb==0.5.23`.
|
||||
- Six container image names: Open WebUI, vLLM, DCGM exporter, Prometheus, node exporter and Grafana.
|
||||
- Miniconda, Ollama runtime, K3s, MinIO and `mc` binaries described by the current offline material.
|
||||
- Ollama `phi3:mini` and `nomic-embed-text` candidate pins plus the Hugging Face Phi-3 snapshot.
|
||||
|
||||
These are candidate inputs, not complete objects: several versions/tags, licenses, transitive packages,
|
||||
architectures and actual byte/digest inventories remain unresolved.
|
||||
|
||||
### Role matrix
|
||||
|
||||
| Role | Workstation adaptive | Server S | Server M | Server L | Server Max |
|
||||
|---|---|---|---|---|---|
|
||||
| Base, Docker, Ollama, vLLM, ChromaDB, monitoring, backend, ttyd, Nginx | Profile-dependent | Yes | Yes | Yes | Yes |
|
||||
| JupyterLab | Optional/profile | Optional | Yes | Yes | Yes |
|
||||
| K3s, MLflow, MinIO | Not enabled on low profiles; payload decision pending | No | Yes | Yes | Yes |
|
||||
| NVIDIA driver/runtime | Only on supported NVIDIA profile | Hardware-dependent | Hardware-dependent | Required profile decision | Required profile decision |
|
||||
| Large default model | Separate pack | Separate/not required | Separate pack | Separate pack | Separate pack |
|
||||
|
||||
The existing `entry`, `pro`, and `max` playbooks contain the same role set. Pro/Max differ primarily in
|
||||
model choice, tensor parallelism, quantization and hardware expectations. Because large models are now
|
||||
separate packs, current repository evidence does not yet prove that Offline Server L/Max needs a
|
||||
materially different boot payload from the Server M superset. The agreed separate L/Max artifact may
|
||||
still be justified by support boundary, validation, driver/runtime, capacity or enterprise policy,
|
||||
but that distinction must be explicit before implementation.
|
||||
|
||||
## Deduplication Policy
|
||||
|
||||
1. Every object is identified by SHA-256 of exact bytes. Identical digests share one dedup group.
|
||||
2. Within one artifact, store identical package/wheel/image/model/runtime objects once; manifests may
|
||||
reference the same object from multiple profiles/tiers.
|
||||
3. Container layers are deduplicated by compressed layer digest, not image tag.
|
||||
4. Python wheels and APT packages are deduplicated by exact file digest and architecture; different
|
||||
builds/architectures are distinct even when package/version text matches.
|
||||
5. Model weights are deduplicated only when exact object digests match. Similar model names or
|
||||
quantizations are distinct.
|
||||
6. Shared source, local help and portal/backend copies use one canonical payload object and explicit
|
||||
install destinations rather than duplicated archives.
|
||||
7. Deduplication across separately distributed ISOs does not reduce each customer's media size and is
|
||||
reported only as build-store efficiency, never as ISO byte reduction.
|
||||
8. Compression savings and filesystem sparse allocation are recorded separately from logical bytes.
|
||||
|
||||
## Measurement Worksheet
|
||||
|
||||
For each build candidate record exact bytes:
|
||||
|
||||
| Component class | Unique compressed bytes | ISO/on-media bytes | Unpacked target bytes | Staging bytes | Rollback bytes | Evidence |
|
||||
|---|---:|---:|---:|---:|---:|---|
|
||||
| Ubuntu boot/install base | TBD | TBD | TBD | TBD | N/A | Base ISO digest/signature required |
|
||||
| Platform source/config/help | TBD | TBD | TBD | TBD | TBD | Exact revision/archive digest |
|
||||
| APT packages/repository metadata | TBD | TBD | TBD | TBD | TBD | Resolved package manifest |
|
||||
| Python/Conda environments | TBD | TBD | TBD | TBD | TBD | Wheel/conda explicit lock |
|
||||
| Runtime binaries | TBD | TBD | TBD | TBD | TBD | Immutable URLs/digests/licenses |
|
||||
| Container layers | TBD | TBD | TBD | TBD | TBD | Digest/layer inventory |
|
||||
| Starter model objects | TBD | TBD | TBD | TBD | TBD | Exact model/layer inventory |
|
||||
| Trust/SBOM/provenance/manifests | TBD | TBD | TBD | TBD | TBD | Signed build output |
|
||||
| ISO filesystem/boot overhead | N/A | TBD | N/A | N/A | N/A | Final image measurement |
|
||||
|
||||
Totals MUST distinguish download/media bytes, target bytes, temporary staging, last-known-good
|
||||
rollback and operational free space. Target disk minimum is not the same as USB capacity.
|
||||
|
||||
## Media Capacity Rule
|
||||
|
||||
After final ISO bytes are measured, compute `required_flash_bytes = final_iso_bytes + tool/filesystem
|
||||
overhead`, then add at least 20% headroom. Publish the smallest commonly available USB capacity above
|
||||
that result. Recommend the next larger capacity when field reliability or signed forecast growth
|
||||
requires it. Record exact arithmetic and artifact digest.
|
||||
|
||||
Current 2–4 GB Online and 35–50 GB Workstation numbers remain labelled estimates only. Offline Server
|
||||
S/M and L/Max sizes remain unpublished until their resolved inventories are built and deduplicated.
|
||||
Large-model-pack media is sized independently from boot media.
|
||||
|
||||
## Evidence Gate
|
||||
|
||||
1. Resolve every input to immutable version/revision/digest, architecture and redistribution license.
|
||||
2. Produce SBOM and object inventory before assembly; verify every fetched byte.
|
||||
3. Fail the build for missing, extra, duplicate-path/different-digest or mutable-tag objects.
|
||||
4. Build from a clean staging host, record logical and physical bytes, and verify manifest totals.
|
||||
5. Extract the ISO independently and reconcile every embedded object to the signed inventory.
|
||||
6. Complete zero-network install and record actual peak target/staging/rollback disk usage.
|
||||
7. Repeat the build to assess reproducibility; unexplained digest differences block release.
|
||||
8. Product/delivery approve the L/Max split justification after comparing its resolved payload to M.
|
||||
|
||||
## Open Decisions
|
||||
|
||||
- Exact immutable Ubuntu, APT, Python/Conda, runtime, image and binary inputs/licenses.
|
||||
- Whether K3s/MinIO tooling belongs in Workstation media when disabled for lower profiles.
|
||||
- Small bootstrap-model boundary for Server S/M and L/Max.
|
||||
- Concrete platform difference justifying separate Offline Server L/Max media after large models are removed.
|
||||
- Compression format/level, reproducible timestamps/ordering, SBOM/provenance formats and build host.
|
||||
- Published USB capacities only after real artifact and flashing measurements.
|
||||
@@ -0,0 +1,172 @@
|
||||
# Python Runtime Profile Selection Contract
|
||||
|
||||
The Offline Workstation AMD64 medium MAY carry both CPU-only and NVIDIA CUDA 12.8 wheel objects, but
|
||||
installation MUST select exactly one platform runtime profile. Media universality does not authorize
|
||||
installing both profiles.
|
||||
|
||||
## Selection
|
||||
|
||||
- `cpu-only`: selected when no supported NVIDIA GPU is accepted or when the operator explicitly
|
||||
chooses CPU mode. It MUST use the PyTorch 2.8.0 CPU trio and MUST NOT install NVIDIA, CUDA, Triton or
|
||||
bitsandbytes wheels.
|
||||
- `nvidia-cu128`: selected only after supported NVIDIA hardware and driver readiness pass. It MUST use
|
||||
the vLLM-0.10.2-aligned Torch 2.8.0/Torchaudio 2.8.0/Torchvision 0.23.0 CUDA 12.8 trio and MUST NOT
|
||||
contain CUDA 13 objects.
|
||||
- Selection is recorded in the installation journal before package mutation. Resume MUST reuse the
|
||||
recorded profile; changing profile requires rollback to the pre-Python checkpoint and a new operation.
|
||||
- Every selected wheel MUST exist in the reviewed payload lock and pass its SHA-256 check before it is
|
||||
exposed to `pip`. Installation MUST use `--no-index` against a profile-specific wheel directory.
|
||||
- Hardware detection failure defaults to `cpu-only`; it MUST NOT silently select NVIDIA.
|
||||
|
||||
The machine-readable candidate is `autoinstall/offline/python-runtime-profiles.json`; its current
|
||||
digests are evidence inputs, not a production signature. `validate-python-runtime-profile.py` is the
|
||||
fail-closed structural/digest guard. Release acceptance additionally requires signed profile membership,
|
||||
license/notice approval and clean bare-metal interruption/resume tests.
|
||||
|
||||
## Selection Planner Boundary
|
||||
|
||||
`plan-python-runtime-profile.py` is a non-mutating planner. It requires an AMD64 hardware probe, an
|
||||
operation ID, optional prior journal state and a membership-verification receipt. The receipt is trusted
|
||||
only as the output of the future production signature verifier; the planner does not perform
|
||||
cryptographic verification and a caller-supplied `signature_verified` boolean is not production proof.
|
||||
|
||||
Stable failures include `ARCHITECTURE_UNSUPPORTED`, `NVIDIA_PROFILE_NOT_READY`,
|
||||
`MEMBERSHIP_RECEIPT_INVALID`, `MEMBERSHIP_UNVERIFIED`, `TEST_RECEIPT_FORBIDDEN`,
|
||||
`PROFILE_NOT_IN_SIGNED_MEMBERSHIP`, `ACTIVE_OPERATION_EXISTS`,
|
||||
`PROFILE_CHANGE_REQUIRES_ROLLBACK` and `NEW_OPERATION_REQUIRED`. Auto-selection chooses NVIDIA only
|
||||
when presence, support and driver readiness are all explicitly true; missing or failed facts select
|
||||
CPU. An existing non-rolled-back journal can only resume the same operation and profile. A rolled-back
|
||||
operation requires a new operation ID.
|
||||
|
||||
The production verifier receipt MUST validate against
|
||||
`schemas/profile-membership-verification-receipt.schema.json`. It binds the exact manifest and
|
||||
signature-envelope digests, key identity/fingerprint, trust snapshot, policy, artifact namespace,
|
||||
authorized profiles, verification time and verifier build. A test-environment receipt is rejected by
|
||||
default and is accepted only through the planner's explicit structural-test switch.
|
||||
|
||||
## Atomic Journal Boundary
|
||||
|
||||
`atomic-profile-journal.py` persists the structural profile-operation journal under an exclusive lock.
|
||||
Every update uses an expected generation, preserves operation/profile/manifest identity, links the prior
|
||||
record digest, writes canonical JSON to a mode-`0600` temporary file, fsyncs it, atomically renames it,
|
||||
then fsyncs the containing directory. Stale generations, altered records, identity changes and invalid
|
||||
transitions fail closed.
|
||||
|
||||
The allowed path is `profile_selected -> checkpoint_ready -> installing -> installed`, with
|
||||
`installing -> rollback_required -> rolled_back`; selection/checkpoint stages may also roll back.
|
||||
`checkpoint_ready` and every mutating/later state require a durable checkpoint identity. Terminal
|
||||
records cannot be reused. The writer records checkpoint identity but does not create or validate the
|
||||
checkpoint itself.
|
||||
|
||||
## Profile Membership Verifier
|
||||
|
||||
`verify-python-profile-membership.py` canonicalizes the profile manifest, verifies its SHA-256 against
|
||||
the detached Ed25519 envelope, enforces policy-version equality, resolves exactly one active trust key,
|
||||
checks algorithm/purpose/environment, verifies the public-key DER fingerprint, and performs Ed25519
|
||||
verification through OpenSSL. Only then does it emit the closed receipt consumed by the planner.
|
||||
|
||||
The profile manifest namespace is fixed as `offline-workstation/python-runtime-profiles`. Unknown or
|
||||
ambiguous keys, wrong purpose/environment/status, fingerprint mismatch, policy mismatch, digest
|
||||
mismatch, malformed signature and invalid signature fail closed. OpenSSL and the verifier executable
|
||||
are themselves release inputs and MUST be locked/measured in the final payload.
|
||||
|
||||
## Python Environment Checkpoint
|
||||
|
||||
`python-environment-checkpoint.py` snapshots an existing environment directory, or records that the
|
||||
target was absent, before mutation. Its manifest binds operation ID, exact target path, original
|
||||
existence and a sorted inventory of directories, files (mode/bytes/SHA-256) and symlinks (mode/target).
|
||||
Creation copies into a same-parent temporary directory, fsyncs files/directories, then atomically
|
||||
renames and fsyncs the parent. Verification recomputes the complete inventory before restore.
|
||||
|
||||
Restore verifies the checkpoint first, quarantines the failed/new target rather than deleting it,
|
||||
copies the verified payload to a same-filesystem temporary directory, fsyncs it and atomically replaces
|
||||
the target. Unsupported filesystem entries, target mismatch, manifest/payload tamper, pre-existing
|
||||
checkpoint/quarantine and restore ambiguity fail closed.
|
||||
|
||||
Test-only fault injection is disabled unless both `NEXUS_ALLOW_TEST_FAULTS=1` and an explicit crash
|
||||
point are set. Boundaries exist before/after checkpoint publication and after failed-target quarantine
|
||||
or restored-target activation. `recover-restore` completes only from preserved quarantine or accepts an
|
||||
already restored target whose complete inventory matches the checkpoint.
|
||||
|
||||
## Pre-Mutation Orchestration
|
||||
|
||||
`prepare-python-profile-operation.py` composes the receipt boundary, selection planner, exact profile
|
||||
payload validator, atomic journal and environment checkpoint. It validates membership and wheel bytes
|
||||
before creating a journal, records `profile_selected`, creates or verifies the checkpoint, then records
|
||||
`checkpoint_ready`. It deliberately has no package-install action and reports
|
||||
`mutation_performed: false`. Re-entry at `checkpoint_ready` is idempotent.
|
||||
|
||||
## Disposable Offline Installation Executor
|
||||
|
||||
`install-python-profile.py` requires a verified `checkpoint_ready` journal and matching checkpoint,
|
||||
records `installing`, creates a new environment beside the target, installs only with `--no-index` and
|
||||
the selected wheel directory, runs profile-specific health checks, fsyncs the complete new tree,
|
||||
atomically activates it, fsyncs the parent, repeats health validation and records `installed`.
|
||||
|
||||
An optional service-health probe runs after built-in post-activation runtime health and before the
|
||||
`installed` journal transition. The probe path MUST be absolute, a non-symlink regular executable and
|
||||
a locked/signed release input; it is invoked directly without a shell as `probe target profile` under
|
||||
a bounded 1–3600 second timeout. Non-zero exit, timeout or execution failure triggers the same verified
|
||||
rollback path as any other post-activation failure. Production integration must define probe identity,
|
||||
least privilege, environment, output capture, service dependencies and the accepted consecutive-health
|
||||
window; an arbitrary operator-supplied executable is not release evidence.
|
||||
|
||||
### Service dependency and health-window contract
|
||||
|
||||
The production activation graph MUST explicitly declare the selected model runtime and vector store
|
||||
as API dependencies, and the portal/reverse proxy as an API dependent. Ordering alone is insufficient:
|
||||
required components use both failure propagation and ordering semantics (`Requires` plus `After`, or
|
||||
an approved equivalent). Optional/category-disabled components MUST be omitted by the resolved profile
|
||||
rather than represented as permanently failing required units.
|
||||
|
||||
Activation acceptance requires at least three consecutive complete graph samples across model runtime,
|
||||
vector store, API and portal/proxy, with the release-approved interval and total timeout. Every sample
|
||||
must validate the component-specific semantic response, not merely an open TCP port. Any failed sample
|
||||
before commit fails the window and triggers rollback from the last verified journal/checkpoint. Probe
|
||||
logs bind the service identities, dependency graph, sample number, response outcome and rollback result.
|
||||
|
||||
The current checked-in `cezen-api.service` is not compliant evidence: it has `After=... ollama.service`
|
||||
but no `Requires=ollama.service`, does not declare ChromaDB ordering/dependency and does not establish
|
||||
the portal/proxy dependency or consecutive semantic-health window. Production units must be remediated
|
||||
and tested separately; isolated mock-unit evidence cannot approve the real graph.
|
||||
|
||||
CPU mode removes ChromaDB (separate environment) and bitsandbytes (GPU-only) from the platform input.
|
||||
On failure it records `rollback_required`, verifies/restores the checkpoint as applicable, then records
|
||||
`rolled_back`. The prior environment and failed activated environment are quarantined, not deleted.
|
||||
|
||||
Test-only executor fault injection can terminate immediately after activation and before post-health or
|
||||
the `installed` journal write. `--recover-only` accepts only `installing` or `rollback_required`, moves
|
||||
to `rollback_required` when necessary, restores or recognizes the verified checkpoint state, preserves
|
||||
the failed activated environment, then records terminal `rolled_back`.
|
||||
|
||||
NVIDIA health requires Torch 2.8.0 with compiled CUDA 12.8, `torch.cuda.is_available()`, successful
|
||||
device tensor execution and synchronization, plus imports for the shared ML stack and bitsandbytes.
|
||||
Merely importing CUDA-bearing wheels does not satisfy NVIDIA readiness.
|
||||
|
||||
## Boot Recovery Dispatcher
|
||||
|
||||
`recover-python-profile-on-boot.py` is the boot-service-safe dispatcher for an existing profile
|
||||
operation. It performs rollback recovery only when the verified journal is in a mutating interrupted
|
||||
state: `installing` or `rollback_required`. An absent journal, terminal `installed`/`rolled_back`
|
||||
journal, or non-mutating `profile_selected`/`checkpoint_ready` journal is an explicit no-op. Unknown,
|
||||
invalid or tampered journal state fails closed.
|
||||
|
||||
The dispatcher does not select a profile, create a checkpoint, install packages or infer success. It
|
||||
must run with access to the exact journal, checkpoint and target paths recorded for the operation.
|
||||
Production boot integration must order it before consumers of the target environment and must retain
|
||||
its output in the installation evidence journal. Process/container restart evidence does not satisfy
|
||||
the separate physical reboot or sudden-power-loss acceptance gates.
|
||||
|
||||
## Capacity-Exhaustion Boundary
|
||||
|
||||
The operation journal, its lock, checkpoint metadata/payload and recovery evidence MUST have reserved
|
||||
capacity independent of the mutable target environment. Target byte or inode exhaustion must not
|
||||
prevent the executor from recording `rollback_required` and terminal `rolled_back`. A release must
|
||||
preflight both free bytes and free inodes for the selected profile, staging tree, activated target,
|
||||
checkpoint, quarantine and journal reserve; byte-only checks are insufficient.
|
||||
|
||||
`ENOSPC` before activation MUST leave the original target unchanged, remove incomplete temporary
|
||||
installation state when possible and record terminal rollback. If reserved journal/checkpoint capacity
|
||||
is itself exhausted, the operation MUST stop fail-closed and recovery must restore that reserve before
|
||||
any retry; it MUST NOT infer success or discard the last verified journal/checkpoint. Disposable tmpfs
|
||||
evidence does not establish production filesystem quotas, live-path metadata or service recovery.
|
||||
@@ -0,0 +1,167 @@
|
||||
# Release Naming, Provenance, Retention, and Support Lifecycle
|
||||
|
||||
**Status**: Approval draft; no release authority.
|
||||
|
||||
## Artifact Identity
|
||||
|
||||
Artifact identity is independent of filename. The canonical identity tuple is artifact type, product,
|
||||
CPU architecture, release version, source revision, manifest digest, signing-key ID and whole-artifact
|
||||
digest. Two byte-different artifacts never share the same complete identity, even if filenames match.
|
||||
|
||||
## Versioning
|
||||
|
||||
Nexus One AI platform releases use Semantic Versioning `MAJOR.MINOR.PATCH`:
|
||||
|
||||
- `MAJOR`: customer-impacting compatibility or migration boundary requiring explicit upgrade policy.
|
||||
- `MINOR`: backward-compatible capability, supported hardware/profile or operational expansion.
|
||||
- `PATCH`: backward-compatible defect/security fix without entitlement expansion.
|
||||
|
||||
Prerelease identifiers are `dev.N`, `alpha.N`, `beta.N`, `rc.N` and are never generally releasable.
|
||||
Build metadata MAY identify a reproducibility rerun but cannot distinguish customer-visible content;
|
||||
any payload change increments the release/prerelease version. Security floor and supported upgrade
|
||||
range use parsed semantic versions, never lexical comparison.
|
||||
|
||||
Models have their upstream immutable revision plus a Cezen pack revision, for example pack
|
||||
`1.0.0` containing a named upstream commit/manifest digest. Trust bundles have monotonically increasing
|
||||
policy versions and cannot be rolled back below the active signed floor.
|
||||
|
||||
## Canonical Product and Filename Slugs
|
||||
|
||||
| Artifact | Canonical artifact type/product slug | Filename pattern |
|
||||
|---|---|---|
|
||||
| Online Universal Server ISO | `iso-online-server-universal` | `nexus-one-ai-online-server-universal_<version>_<arch>.iso` |
|
||||
| Offline Workstation ISO | `iso-offline-workstation` | `nexus-one-ai-offline-workstation_<version>_<arch>.iso` |
|
||||
| Offline Server S/M ISO | `iso-offline-server-sm` | `nexus-one-ai-offline-server-sm_<version>_<arch>.iso` |
|
||||
| Offline Server L/Max ISO | `iso-offline-server-lmax` | `nexus-one-ai-offline-server-lmax_<version>_<arch>.iso` |
|
||||
| Model pack | `model-pack-<model-slug>` | `nexus-one-ai-model-pack_<model-slug>_<upstream-revision>_<pack-version>_<arch>.tar.zst` |
|
||||
| Offline update | `update-bundle` | `nexus-one-ai-update_<from-range>_to_<version>_<arch>.tar.zst` |
|
||||
| Trust bundle | `trust-bundle` | `nexus-one-ai-trust_<policy-version>.json` |
|
||||
|
||||
Filenames use lowercase ASCII slugs, semantic versions, explicit architecture and no spaces. Filename
|
||||
is display/convenience metadata and is never trusted without signed-manifest verification.
|
||||
|
||||
## Release Channels
|
||||
|
||||
| Channel | Permitted artifacts | Promotion rule |
|
||||
|---|---|---|
|
||||
| `development` | Internal unsigned build outputs allowed only in isolated build/test systems | Never delivered to customers |
|
||||
| `internal` | Signed prerelease | Static/schema/security tests and reproducible identity pass |
|
||||
| `pilot` | Signed RC | Required physical/offline/update/recovery evidence plus pilot authorization |
|
||||
| `stable` | Signed final | All gates, independent review and joint product/delivery approval pass |
|
||||
| `security` | Signed targeted update/trust bundle | Security-owner scope plus product/delivery recovery approval |
|
||||
|
||||
Promotion does not rename or mutate bytes. A promoted release is rebuilt under a new final version or
|
||||
the exact already-signed artifact is referenced by a new signed channel index according to approved
|
||||
policy; silent replacement is prohibited.
|
||||
|
||||
## SBOM
|
||||
|
||||
Every ISO payload, model pack and update bundle includes:
|
||||
|
||||
- SPDX 3.0.1 JSON as the canonical release SBOM;
|
||||
- package/file/component identities, versions, suppliers, licenses, checksums and relationships;
|
||||
- OS packages, Python/Conda packages, container images/layers, binaries, source package, JavaScript
|
||||
assets, models/runtime objects and embedded build/install tools;
|
||||
- generated timestamp and tool identity separated from reproducible component content;
|
||||
- declared unknown/incomplete license fields as release blockers, not guessed values.
|
||||
|
||||
CycloneDX MAY be generated as an additional customer/tooling view but cannot replace canonical SPDX.
|
||||
Model SBOM entries include provider, model/revision, weight/config/tokenizer/template/license object
|
||||
digests and declared runtime relationship.
|
||||
|
||||
## Provenance
|
||||
|
||||
Every built artifact carries an in-toto Attestation Framework v1.2 Statement v1 using the
|
||||
SLSA Provenance v1 predicate (aligned to the SLSA specification v1.2), encoded as
|
||||
canonical JSON and referenced by digest from the artifact manifest. It identifies:
|
||||
|
||||
- source repository and exact revision plus clean/dirty state;
|
||||
- build recipe/revision, resolved immutable inputs and dependency/object digests;
|
||||
- builder identity, isolated environment image/OS/tool versions and architecture;
|
||||
- build start/end, invocation parameters excluding secrets, network policy and reproducibility status;
|
||||
- output artifact/manifest/SBOM digests and signing handoff identity.
|
||||
|
||||
The signing event is a separate attestation linking verified build output to release key/policy,
|
||||
reviewer and channel. Private-key location, credential values and sensitive host details are excluded.
|
||||
|
||||
## Reproducibility Classification
|
||||
|
||||
- `reproducible`: independent authorized rebuilds produce identical whole-artifact bytes/digest.
|
||||
- `content-reproducible`: all signed payload objects/manifests match but ISO container bytes differ only
|
||||
in documented non-semantic metadata that is excluded from trusted content identity.
|
||||
- `non-reproducible`: unexplained content or container differences; cannot enter stable channel.
|
||||
|
||||
Timestamps, file ordering, ownership/mode, locale, compression, ISO volume metadata and generated IDs
|
||||
must be normalized where tooling permits. Differences are stored and reviewed, not waived silently.
|
||||
|
||||
## Release Record and Publication
|
||||
|
||||
The release record contains version/channel/status, every artifact identity, source/build provenance,
|
||||
SBOM, license review, security findings, supported category/tier/architecture/hardware/OS matrix,
|
||||
upgrade/from-version and rollback class, known issues, evidence links/checksums, release notes, support
|
||||
window and named approvals. Publication includes manifest/signature/digest and verification guidance.
|
||||
|
||||
An artifact is never “latest” solely because a filename or repository branch is newer. Signed channel
|
||||
indexes map `stable`/`pilot` to immutable artifact identity and retain history.
|
||||
|
||||
## Retention
|
||||
|
||||
Recommended minimums pending owner approval:
|
||||
|
||||
- Stable release records, manifests, signatures, SBOMs, provenance, approvals and checksums: product
|
||||
lifetime plus seven years.
|
||||
- Stable ISO/update/model/trust bytes: while supported plus two years, subject to redistribution rights.
|
||||
- Pilot/RC evidence and failed critical release candidates: seven years.
|
||||
- Internal/development artifact bytes: 90 days unless referenced by an investigation; metadata one year.
|
||||
- Revoked/withdrawn artifacts: retain controlled bytes and permanent public/internal tombstone identity;
|
||||
never delete the fact that the artifact existed.
|
||||
- Raw lab captures/logs: approved evidence retention, access and privacy schedule; summary/checksums
|
||||
follow the release record.
|
||||
|
||||
Retention expiration requires recorded disposition; signed metadata, security/revocation history and
|
||||
customer restore dependencies cannot be deleted merely to save storage.
|
||||
|
||||
## Support Window and Cadence
|
||||
|
||||
Proposed policy for approval:
|
||||
|
||||
- One current stable `MAJOR.MINOR` line plus the immediately previous minor receives standard fixes.
|
||||
- Critical security updates may target older supported appliances when upgrade is unsafe; unsupported
|
||||
lines receive a signed upgrade/recovery recommendation, not an untested patch.
|
||||
- Patch/update bundles are issued as required after gates; there is no forced monthly payload churn.
|
||||
- Quarterly dependency/model/runtime review determines whether a maintenance release is needed.
|
||||
- ISO refresh occurs after accepted updates materially affect clean installation, security, hardware
|
||||
enablement or field time; installed systems use update bundles rather than OS reinstall.
|
||||
- Model packs have independent revisions/support notices and do not force platform release unless
|
||||
runtime compatibility changes.
|
||||
- Trust/revocation bundles publish immediately for approved emergency changes and on the regular
|
||||
maximum-age cadence required by policy.
|
||||
|
||||
Every release states end-of-support date or governing policy, minimum supported update source,
|
||||
successor release and recovery/upgrade path. No auto-update occurs without the appliance update policy.
|
||||
|
||||
## Withdrawal and Revocation
|
||||
|
||||
A withdrawn artifact remains identifiable by digest and status. Signed channel indexes stop selecting
|
||||
it; trust/revocation policy may block new installation/import while preserving recovery-safe behavior
|
||||
for already-running appliances. The notice records reason/severity, affected identities, customer
|
||||
impact, replacement, backup/rollback advice and support contact without exposing exploit details
|
||||
beyond approved disclosure policy.
|
||||
|
||||
## Evidence Gate
|
||||
|
||||
1. Validate filenames and manifest identity for every artifact type and architecture.
|
||||
2. Generate/validate SPDX and provenance schemas; reconcile all inventory objects.
|
||||
3. Rebuild independently and classify reproducibility with documented diff.
|
||||
4. Verify signed channel index promotion never mutates referenced bytes.
|
||||
5. Exercise withdrawal/revocation and older-version upgrade/restore discovery.
|
||||
6. Confirm retention and publication locations are access-controlled, backed up and restorable.
|
||||
7. Product, security, legal and delivery/support approve support/retention/cadence values.
|
||||
|
||||
## Owner Decisions Still Open
|
||||
|
||||
- Approve SPDX 3.0.1 and in-toto v1.2/SLSA v1.2 formats/toolchain and reproducibility classification.
|
||||
- Approve filename/version/channel rules and production publication locations.
|
||||
- Approve retention periods, raw-evidence privacy schedule and legal hold.
|
||||
- Approve supported-version window, security backport policy, review/ISO refresh cadence and EOL notice.
|
||||
- Name release coordinator, SBOM/license owner, provenance reviewer and archive owner.
|
||||
@@ -0,0 +1,144 @@
|
||||
# Release Signing and Offline Trust Contract
|
||||
|
||||
## Trust Domains
|
||||
|
||||
Release-artifact signing and customer-license signing are separate trust domains. A release key MUST
|
||||
NOT sign licenses, and a license key MUST NOT sign ISOs, model packs, update bundles, channel indexes,
|
||||
trust bundles or revocation lists. Test keys are conspicuously identified and MUST NOT be trusted by a
|
||||
production verifier.
|
||||
|
||||
The release hierarchy has these roles:
|
||||
|
||||
| Role | Permitted signatures | Required custody |
|
||||
|---|---|---|
|
||||
| Offline release root | Subordinate-key authorization, root rotation and emergency trust recovery | Offline, encrypted hardware/removable custody; dual control; never connected to build or distribution systems |
|
||||
| Artifact-signing subordinate | Approved ISO, model-pack and update manifests plus release provenance handoff | Dedicated signing device/service isolated from builders; short-lived operator authorization; no exportable plaintext key |
|
||||
| Metadata-signing subordinate | Channel indexes and withdrawal notices | Separate from artifact builder and distribution publisher; constrained namespace/purpose |
|
||||
| Revocation/trust subordinate | Versioned revocation lists and routine trust bundles | Offline-capable controlled signer; cannot sign artifacts |
|
||||
|
||||
Each key record declares key ID/fingerprint, algorithm, purpose, environment, activation/expiry,
|
||||
issuer, status, permitted artifact namespaces/channels and ceremony evidence ID. Verifiers reject a
|
||||
valid cryptographic signature when the key purpose, namespace, channel, time policy or trust path is
|
||||
wrong.
|
||||
|
||||
## Ownership and Separation of Duties
|
||||
|
||||
The repository MAY display **Cezen Technologies** as the accountable organization rather than personal
|
||||
names, but every release MUST link an access-controlled approval record that attributes authorized
|
||||
people to these roles:
|
||||
|
||||
- **Security owner** approves trust policy, ceremonies, key status and emergency revocation.
|
||||
- **Release owner** requests signing only after build/evidence gates pass.
|
||||
- **Signing operators** execute dual-controlled signing and cannot be the sole build executor.
|
||||
- **Independent release reviewer** verifies manifest, provenance, evidence and requested channel.
|
||||
- **Distribution publisher** publishes immutable bytes and metadata but has no signing key.
|
||||
- **Support/recovery owner** receives withdrawal/recovery instructions and verifies field media.
|
||||
|
||||
No person can alone build, approve, sign and publish a stable release. Public use of the company name
|
||||
does not satisfy this control without the restricted role-attribution record. Stable signing requires a
|
||||
release request plus independent approval bound to exact manifest, artifact, SBOM and provenance
|
||||
digests. Emergency action may shorten timing but not remove dual control or evidence.
|
||||
|
||||
## Key Generation, Backup and Custody
|
||||
|
||||
Production keys are generated inside the approved signing boundary from an approved entropy source.
|
||||
Private key material is non-exportable where supported. Any permitted backup is encrypted to two or
|
||||
more custodians or protected by an approved threshold mechanism so one custodian cannot recover it.
|
||||
Custody inventory records tamper seals/device serials, storage locations, access events and quarterly
|
||||
presence checks without exposing secrets.
|
||||
|
||||
Root use requires an offline ceremony on a clean controlled workstation, two authorized custodians,
|
||||
an independent witness, time-bounded change request, verified ceremony tooling and recorded public
|
||||
outputs. The ceremony evidence includes inputs/outputs by digest, participants by role, device and
|
||||
tool versions, photographs or equivalent custody evidence where policy permits, and destruction or
|
||||
resealing confirmation. Secret key bytes, PINs and recovery shares never enter logs or release
|
||||
evidence.
|
||||
|
||||
Loss, suspected access, custody discrepancy, failed integrity check or unexplained signature triggers
|
||||
incident handling and suspension of the affected key before further signing.
|
||||
|
||||
## Signing Handoff and Publication
|
||||
|
||||
1. The reproducible builder emits immutable unsigned artifact, canonical manifest, SBOM and provenance
|
||||
digests into a read-only handoff.
|
||||
2. The independent reviewer reconciles source revision, inventory, test evidence and target channel.
|
||||
3. The release owner submits an immutable signing request containing all digests, policy version,
|
||||
artifact namespace/version and approval IDs.
|
||||
4. Signing operators re-hash every input inside the signing boundary, verify approvals/policy and sign
|
||||
only the canonical manifest/attestation objects specified by the contract.
|
||||
5. A signing receipt binds request, signer key ID, input/output digests, time source/confidence,
|
||||
operators by role and ceremony/session ID.
|
||||
6. The publisher verifies signatures and receipts, publishes immutable bytes, then publishes the
|
||||
signed channel mapping. Post-publication retrieval must reproduce every published digest.
|
||||
|
||||
Any digest or approval mismatch aborts the session. Retrying creates a new signing receipt; an output
|
||||
from an aborted or unapproved session cannot be promoted.
|
||||
|
||||
## Rotation, Expiry and Trust Distribution
|
||||
|
||||
Subordinate keys have explicit activation/expiry and SHOULD rotate at least annually or sooner after
|
||||
policy/technology change. The offline root rotates only through a root ceremony. Rotation uses an
|
||||
overlap window: existing trusted authority signs the successor trust record, new media embeds both
|
||||
currently required public keys, and verification evidence proves old-supported, overlap and new-only
|
||||
paths. Expired keys cannot sign new releases; previously signed supported artifacts remain acceptable
|
||||
only under the approved historical-signature/time policy and non-revoked status.
|
||||
|
||||
Every bootable artifact embeds a versioned trust snapshot sufficient to verify its own payload.
|
||||
Installed appliances accept newer signed trust bundles through the same offline fail-closed import
|
||||
flow. Trust state is monotonic by sequence number/security floor; rollback requires separately
|
||||
authorized break-glass recovery and cannot be hidden as a normal import.
|
||||
|
||||
Public trust material, fingerprints and signed metadata may be distributed broadly. Distribution
|
||||
systems are untrusted for integrity: appliances rely on the embedded root and signed sequence, not the
|
||||
download location or removable-media label.
|
||||
|
||||
## Revocation and Emergency Recovery
|
||||
|
||||
A root- or authorized revocation-signer-signed list identifies key ID, status, effective time,
|
||||
reason class, minimum trust sequence and required operator behavior. Revocation lists are versioned,
|
||||
monotonic and importable without network access. Policy sets a maximum acceptable age for new imports;
|
||||
stale policy blocks artifact activation according to the declared fail-closed rule while preserving
|
||||
local recovery, diagnostics, export and an already healthy installation unless a signed emergency
|
||||
directive explicitly requires deactivation.
|
||||
|
||||
Emergency procedure:
|
||||
|
||||
1. Suspend signing/publishing and preserve suspected artifacts, logs and custody evidence.
|
||||
2. Security owner plus second authorized approver classify scope: subordinate, metadata, revocation
|
||||
signer or root compromise.
|
||||
3. Use an unaffected authority to issue a higher-sequence revocation/trust bundle and signed customer
|
||||
advisory. If the root is affected, invoke the separately stored recovery-root/field-recovery plan;
|
||||
ordinary compromised-root signatures cannot restore trust.
|
||||
4. Publish verified recovery media through at least two controlled channels and provide offline
|
||||
fingerprint verification to support.
|
||||
5. Test clean, stale-policy, revoked-key, rollback-attempt, interrupted-import and already-installed
|
||||
behavior before release; record affected artifact IDs and successor paths.
|
||||
6. Close only after inventory reconciliation, key replacement, customer/support communication and
|
||||
independent incident review.
|
||||
|
||||
Revocation MUST block new use of affected signatures. It MUST NOT silently erase customer data or
|
||||
brick recovery access. Mandatory shutdown/removal requires an explicit signed emergency policy and
|
||||
product/security approval with a documented recovery path.
|
||||
|
||||
## Acceptance Evidence
|
||||
|
||||
Gate 1 requires approved role assignments, hierarchy/purpose constraints, custody design, rotation and
|
||||
revocation policy, maximum revocation age, emergency recovery path and test inventory. Gate 3 adds
|
||||
ceremony/signing receipts, public-key fingerprints, signature verification, purpose/namespace/time
|
||||
negatives and post-publication retrieval. Gate 5/6 adds offline trust import, stale/revoked/rollback,
|
||||
rotation overlap, interruption and emergency tabletop evidence with independent review.
|
||||
|
||||
Required negative vectors include wrong trust domain, wrong key purpose, unknown/revoked/expired/not-
|
||||
yet-valid key, wrong artifact namespace/channel, stale/lower-sequence trust state, tampered manifest,
|
||||
approval digest mismatch and test-key use in production policy.
|
||||
|
||||
## Decisions Requiring Named Approval
|
||||
|
||||
- Cezen Technologies ownership plus restricted attribution of authorized Security, Release,
|
||||
signing-operator, reviewer, publisher and Support people and alternates.
|
||||
- Approved signing hardware/service, threshold/backup method, custody locations and ceremony tooling.
|
||||
- Key lifetimes, rotation/overlap duration, historical-signature rule and maximum revocation-list age.
|
||||
- Time source/confidence policy for disconnected signing and verification.
|
||||
- Recovery-root or equivalent compromised-root field recovery design and storage.
|
||||
- Emergency severity matrix, response/communication targets and mandatory-deactivation authority.
|
||||
- Evidence storage, access, retention and privacy policy for ceremonies and incidents.
|
||||
@@ -0,0 +1,180 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://cezentech.com/schemas/nexus-one/artifact-manifest-v1.json",
|
||||
"title": "Nexus One AI Signed Artifact Manifest",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema", "artifact", "source", "targets", "payload", "requirements",
|
||||
"lifecycle", "integrity"
|
||||
],
|
||||
"properties": {
|
||||
"schema": { "const": "com.cezen.nexus-one.artifact-manifest.v1" },
|
||||
"artifact": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "type", "version", "created_at", "architecture"],
|
||||
"properties": {
|
||||
"id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{2,127}$" },
|
||||
"type": { "enum": ["iso-payload", "model-pack", "update-bundle", "trust-bundle"] },
|
||||
"version": { "type": "string", "minLength": 1 },
|
||||
"created_at": { "type": "string", "format": "date-time" },
|
||||
"architecture": { "enum": ["amd64", "arm64", "multi"] },
|
||||
"description": { "type": "string", "maxLength": 512 }
|
||||
}
|
||||
},
|
||||
"source": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["repository", "revision", "builder", "build_recipe_digest"],
|
||||
"properties": {
|
||||
"repository": { "type": "string", "minLength": 1 },
|
||||
"revision": { "type": "string", "pattern": "^[0-9a-f]{40,64}$" },
|
||||
"builder": { "type": "string", "minLength": 1 },
|
||||
"build_recipe_digest": { "$ref": "#/$defs/digest" },
|
||||
"sbom": { "$ref": "#/$defs/objectRef" },
|
||||
"provenance": { "$ref": "#/$defs/objectRef" }
|
||||
}
|
||||
},
|
||||
"targets": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["categories", "tiers", "platform_versions", "ubuntu_release"],
|
||||
"properties": {
|
||||
"categories": {
|
||||
"type": "array", "minItems": 1, "uniqueItems": true,
|
||||
"items": { "enum": ["workstation", "server"] }
|
||||
},
|
||||
"tiers": {
|
||||
"type": "array", "minItems": 1, "uniqueItems": true,
|
||||
"items": { "enum": ["workstation", "starter", "basic", "pro", "max"] }
|
||||
},
|
||||
"platform_versions": { "type": "string", "minLength": 1 },
|
||||
"ubuntu_release": { "type": "string", "minLength": 1 },
|
||||
"hardware_profiles": {
|
||||
"type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"payload": {
|
||||
"type": "array", "minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "bytes", "digest", "media_type", "install_scope"],
|
||||
"properties": {
|
||||
"path": { "type": "string", "pattern": "^[^/].*$" },
|
||||
"bytes": { "type": "integer", "minimum": 0 },
|
||||
"digest": { "$ref": "#/$defs/digest" },
|
||||
"media_type": { "type": "string", "minLength": 1 },
|
||||
"install_scope": { "enum": ["base", "category", "tier", "optional"] },
|
||||
"immutable_source": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["download_bytes", "unpacked_bytes", "required_free_bytes"],
|
||||
"properties": {
|
||||
"download_bytes": { "type": "integer", "minimum": 0 },
|
||||
"unpacked_bytes": { "type": "integer", "minimum": 0 },
|
||||
"required_free_bytes": { "type": "integer", "minimum": 0 },
|
||||
"minimum_ram_bytes": { "type": "integer", "minimum": 0 },
|
||||
"minimum_vram_bytes": { "type": "integer", "minimum": 0 },
|
||||
"required_capabilities": {
|
||||
"type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"lifecycle": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["activation", "reboot", "rollback_class"],
|
||||
"properties": {
|
||||
"from_versions": { "type": "string" },
|
||||
"to_version": { "type": "string" },
|
||||
"activation": { "enum": ["install", "import", "staged-switch", "trust-update"] },
|
||||
"reboot": { "enum": ["none", "may-require", "required"] },
|
||||
"rollback_class": { "enum": ["automatic", "operator", "restore", "none"] },
|
||||
"security_floor": { "type": "string" },
|
||||
"health_validation_seconds": { "type": "integer", "minimum": 1 }
|
||||
}
|
||||
},
|
||||
"integrity": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["signature_algorithm", "signing_key_id", "policy_version"],
|
||||
"properties": {
|
||||
"signature_algorithm": { "const": "ed25519" },
|
||||
"signing_key_id": { "type": "string", "minLength": 8 },
|
||||
"policy_version": { "type": "string", "minLength": 1 },
|
||||
"revocation_list_version": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"model": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["provider", "model_id", "revision", "runtime", "activation_name"],
|
||||
"properties": {
|
||||
"provider": { "type": "string", "minLength": 1 },
|
||||
"model_id": { "type": "string", "minLength": 1 },
|
||||
"revision": { "type": "string", "minLength": 1 },
|
||||
"runtime": { "type": "string", "minLength": 1 },
|
||||
"activation_name": { "type": "string", "minLength": 1 }
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["order", "kind", "object", "failure_action"],
|
||||
"properties": {
|
||||
"order": { "type": "integer", "minimum": 1 },
|
||||
"kind": { "enum": ["install", "replace", "remove", "migrate", "activate", "validate"] },
|
||||
"object": { "type": "string", "minLength": 1 },
|
||||
"failure_action": { "enum": ["stop-safe", "rollback", "restore", "operator-recovery"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
|
||||
"objectRef": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "bytes", "digest"],
|
||||
"properties": {
|
||||
"path": { "type": "string", "pattern": "^[^/].*$" },
|
||||
"bytes": { "type": "integer", "minimum": 0 },
|
||||
"digest": { "$ref": "#/$defs/digest" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"artifact": {
|
||||
"properties": {
|
||||
"type": { "const": "model-pack" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": { "required": ["model"] }
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"properties": {
|
||||
"artifact": {
|
||||
"properties": {
|
||||
"type": { "const": "update-bundle" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"then": { "required": ["actions"] }
|
||||
}
|
||||
]
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://cezentech.com/schemas/nexus-one/profile-membership-verification-receipt-v1.json",
|
||||
"title": "Nexus One AI Profile Membership Verification Receipt",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema", "environment", "result", "manifest_sha256", "envelope_sha256", "key_id",
|
||||
"key_fingerprint_sha256", "trust_snapshot_sha256", "policy_version", "namespace", "profiles",
|
||||
"verified_at", "verifier_build_sha256"
|
||||
],
|
||||
"properties": {
|
||||
"schema": { "const": "com.cezen.nexus-one.profile-membership-verification-receipt.v1" },
|
||||
"environment": { "enum": ["production", "test"] },
|
||||
"result": { "const": "verified" },
|
||||
"manifest_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"envelope_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"key_id": { "type": "string", "minLength": 8 },
|
||||
"key_fingerprint_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"trust_snapshot_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"policy_version": { "type": "string", "minLength": 1 },
|
||||
"namespace": { "const": "offline-workstation/python-runtime-profiles" },
|
||||
"profiles": {
|
||||
"type": "array", "minItems": 1, "uniqueItems": true,
|
||||
"items": { "enum": ["cpu-only", "nvidia-cu128"] }
|
||||
},
|
||||
"verified_at": { "type": "string", "format": "date-time" },
|
||||
"verifier_build_sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://cezentech.com/schemas/nexus-one/signature-envelope-v1.json",
|
||||
"title": "Nexus One AI Detached Signature Envelope",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["schema", "manifest_digest", "algorithm", "key_id", "signed_at", "signature"],
|
||||
"properties": {
|
||||
"schema": { "const": "com.cezen.nexus-one.signature-envelope.v1" },
|
||||
"manifest_digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
|
||||
"algorithm": { "const": "ed25519" },
|
||||
"key_id": { "type": "string", "minLength": 8 },
|
||||
"signed_at": { "type": "string", "format": "date-time" },
|
||||
"policy_version": { "type": "string", "minLength": 1 },
|
||||
"signature": { "type": "string", "contentEncoding": "base64" },
|
||||
"certificate_chain": {
|
||||
"type": "array", "items": { "type": "string", "contentEncoding": "base64" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
# Candidate Production Service Graph
|
||||
|
||||
These files are a design/validation candidate, not installed runtime units. Promotion requires the
|
||||
Gate 2 evidence below and explicit implementation authorization.
|
||||
|
||||
## Dependency graph
|
||||
|
||||
`ollama.service` and `chromadb.service` are required upstream components for the current Workstation
|
||||
profile. `cezen-api.service` requires and orders after both. The nginx drop-in only *wants* and orders
|
||||
after the API so static local recovery/help remains reachable during API failure. The transactional
|
||||
`nexus-one-activation-health.service` requires the complete model/vector/API/nginx graph; any failed
|
||||
window triggers `nexus-one-activation-rollback.service`.
|
||||
|
||||
`activation-health-window.py` accepts only literal loopback HTTP URLs and exact semantic JSON responses
|
||||
containing `service` and `status`. It does not resolve hostnames or contact LAN/Internet addresses.
|
||||
Required components must report `ready`. An optional component may report `degraded` only when both the
|
||||
signed profile marks it optional and the activation invocation explicitly enables degraded acceptance;
|
||||
the default rejects degradation. Timeout, non-200 response, wrong content type/shape/identity/status,
|
||||
oversized response, malformed JSON and unreachable endpoint reject immediately.
|
||||
|
||||
Exit `0` means the requested consecutive window completed as `ready`, or explicitly policy-accepted
|
||||
`degraded`. Exit `23` means a semantic health rejection and is the contract used by systemd
|
||||
`OnFailure`. Exit `2` means invalid configuration/evidence I/O and also fails the unit. Evidence is
|
||||
canonical JSON, mode `0600`, fsynced and atomically published without wall-clock-dependent fields.
|
||||
|
||||
The per-request timeout is capped by the remaining monotonic total-window deadline. The validator
|
||||
rejects with `WINDOW_TIMEOUT` when the deadline has expired or when the configured interval makes the
|
||||
next required sample impossible. It never extends the deadline because a component responds slowly.
|
||||
|
||||
Each health-profile component also declares `systemd_unit` (a literal `.service` name or `null`) and
|
||||
`max_restarts`. Before HTTP evaluation, the validator reads `NRestarts`, `ActiveState` and `SubState`
|
||||
using a fixed `systemctl show` argv. A count above the signed profile limit rejects as `RESTART_STORM`;
|
||||
an unavailable/malformed unit state or a non-active unit also rejects. `null` is permitted only for a
|
||||
profile component whose lifecycle is demonstrably outside systemd. Restart checks occur before HTTP so
|
||||
a stale or separately served healthy endpoint cannot conceal an unstable unit.
|
||||
|
||||
Category/profile resolution may replace Ollama with another signed model-runtime unit or omit an
|
||||
unsupported optional component, but it must generate a closed graph before activation. A missing
|
||||
required unit fails the transaction; it is not silently downgraded.
|
||||
|
||||
## Active-operation environment contract
|
||||
|
||||
`/var/lib/nexus-one/installer/active-operation.env` is root-owned mode `0600`, atomically published and
|
||||
contains only these validated, systemd-safe assignments:
|
||||
|
||||
```text
|
||||
OPERATION_ID=<restricted identifier>
|
||||
HEALTH_PROFILE_CONFIG=/usr/share/nexus-one/health-profiles/<signed profile>.json
|
||||
HEALTH_SAMPLES=3
|
||||
HEALTH_INTERVAL_SECONDS=<approved integer>
|
||||
HEALTH_TIMEOUT_SECONDS=<approved integer>
|
||||
HEALTH_WINDOW_TIMEOUT_SECONDS=<approved integer>
|
||||
HEALTH_EVIDENCE_PATH=/var/lib/nexus-one/installer/evidence/<operation>.json
|
||||
JOURNAL_PATH=/var/lib/nexus-one/installer/operations/<operation>/journal.json
|
||||
CHECKPOINT_PATH=/var/lib/nexus-one/installer/operations/<operation>/checkpoint
|
||||
TARGET_PATH=/opt/cezen/<selected target>
|
||||
```
|
||||
|
||||
Values must not contain whitespace, quotes, `%`, `$`, shell syntax or path traversal. All paths are
|
||||
canonicalized and checked against their allowed roots before publication. The file contains no secret.
|
||||
It remains until the health unit commits success or rollback reaches terminal state, then is archived
|
||||
with the evidence record and removed atomically.
|
||||
|
||||
## Promotion gates
|
||||
|
||||
- Lock and sign the health profile, health-window/recovery executables and unit/drop-in bytes.
|
||||
- Define semantic probes for Ollama/model availability, Chroma heartbeat, API `/api/health`, and nginx
|
||||
portal/API proxy behavior, including category-aware degraded states.
|
||||
- Approve sample interval, total timeout, restart policy and consecutive-success count.
|
||||
- Prove clean boot, activation, dependency failure, restart storm, timeout, rollback and recovery-portal
|
||||
access on the real services with zero network access.
|
||||
- Verify ownership, modes, ACLs, xattrs, SELinux/AppArmor implications and least-privilege write paths.
|
||||
- Resolve whether CPU-only installations still require Ollama; generate a different graph if not.
|
||||
- Replace the current Ansible-created unit content only after the candidate passes these gates.
|
||||
@@ -0,0 +1,33 @@
|
||||
[Unit]
|
||||
Description=Nexus One AI Management API
|
||||
Wants=network-online.target
|
||||
Requires=ollama.service chromadb.service
|
||||
After=network-online.target ollama.service chromadb.service
|
||||
StartLimitIntervalSec=120
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=cezen
|
||||
Group=cezen
|
||||
WorkingDirectory=/opt/cezen/backend
|
||||
Environment=CEZEN_DATA=/opt/cezen/data
|
||||
Environment=OLLAMA_URL=http://127.0.0.1:11434
|
||||
Environment=CHROMA_URL=http://127.0.0.1:8100
|
||||
Environment=PATH=/opt/cezen/backend/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
|
||||
ExecStart=/opt/cezen/backend/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8080 --workers 2
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
TimeoutStartSec=120
|
||||
TimeoutStopSec=30
|
||||
KillSignal=SIGTERM
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/opt/cezen/data
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,27 @@
|
||||
[Unit]
|
||||
Description=Nexus One AI ChromaDB Vector Store
|
||||
After=local-fs.target
|
||||
StartLimitIntervalSec=120
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=cezen
|
||||
Group=cezen
|
||||
WorkingDirectory=/opt/cezen/data/chromadb
|
||||
Environment=PATH=/opt/cezen/chromadb-venv/bin:/usr/local/bin:/usr/bin:/bin
|
||||
ExecStart=/opt/cezen/chromadb-venv/bin/chroma run --host 127.0.0.1 --port 8100 --path /opt/cezen/data/chromadb
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
TimeoutStartSec=120
|
||||
TimeoutStopSec=30
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/opt/cezen/data/chromadb
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Nexus One AI post-activation health window
|
||||
Requires=ollama.service chromadb.service cezen-api.service nginx.service
|
||||
After=ollama.service chromadb.service cezen-api.service nginx.service
|
||||
OnFailure=nexus-one-activation-rollback.service
|
||||
ConditionPathExists=/var/lib/nexus-one/installer/active-operation.env
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
EnvironmentFile=/var/lib/nexus-one/installer/active-operation.env
|
||||
ExecStart=/usr/bin/python3 /usr/lib/nexus-one/activation-health-window.py --operation-id ${OPERATION_ID} --profile-config ${HEALTH_PROFILE_CONFIG} --samples ${HEALTH_SAMPLES} --interval-seconds ${HEALTH_INTERVAL_SECONDS} --timeout-seconds ${HEALTH_TIMEOUT_SECONDS} --window-timeout-seconds ${HEALTH_WINDOW_TIMEOUT_SECONDS} --evidence ${HEALTH_EVIDENCE_PATH}
|
||||
TimeoutStartSec=600
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/nexus-one/installer
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Nexus One AI failed-activation rollback
|
||||
ConditionPathExists=/var/lib/nexus-one/installer/active-operation.env
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
EnvironmentFile=/var/lib/nexus-one/installer/active-operation.env
|
||||
ExecStart=/usr/bin/python3 /usr/lib/nexus-one/recover-python-profile-on-boot.py --journal ${JOURNAL_PATH} --checkpoint ${CHECKPOINT_PATH} --target ${TARGET_PATH}
|
||||
TimeoutStartSec=600
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/opt/cezen /var/lib/nexus-one/installer
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
# Keep nginx available for local recovery/help even when the API fails. The activation health gate,
|
||||
# rather than nginx itself, requires the complete graph.
|
||||
Wants=cezen-api.service
|
||||
After=cezen-api.service
|
||||
@@ -0,0 +1,26 @@
|
||||
# Artifact Contract Test Vectors
|
||||
|
||||
These files are specification fixtures only. They contain conspicuous non-production identifiers and
|
||||
digests. They MUST NOT be copied into an installer or accepted by a release verifier.
|
||||
|
||||
- `workstation-iso-manifest.valid.json`: structurally valid Workstation ISO payload example.
|
||||
- `compatibility-cases.json`: deterministic compatibility outcomes and primary reason codes.
|
||||
- `ed25519-test-public.pem`, the four `*-signature.valid.json` envelopes, and
|
||||
`signature-cases.json`: real test-only Ed25519 positive vectors plus tamper and unknown-key
|
||||
negatives. The private key was transient and is intentionally absent.
|
||||
- `model-pack-manifest.valid.json`, `update-bundle-manifest.valid.json`, and
|
||||
`trust-bundle-manifest.valid.json`: structural examples for the remaining artifact types.
|
||||
- `verification-evidence.md`: current parsing, digest, signature, and scope-limited verification result.
|
||||
|
||||
Before Gate 1 approval, add:
|
||||
|
||||
1. independent security/platform review of the test-vector procedure;
|
||||
2. owner approval of the schemas, compatibility contract, and signing policy.
|
||||
|
||||
No production key or customer license may appear in this directory.
|
||||
|
||||
Run the complete automated fixture suite with Python packages `jsonschema` and `cryptography`:
|
||||
|
||||
```bash
|
||||
python3 validate_vectors.py
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.compatibility-cases.v1",
|
||||
"notice": "TEST ONLY - trust and digest checks are assumed successful unless the case names them",
|
||||
"base_context": {
|
||||
"category": "workstation",
|
||||
"tier": "workstation",
|
||||
"platform_version": "0.0.0-test.1",
|
||||
"ubuntu_release": "22.04.5",
|
||||
"architecture": "amd64",
|
||||
"hardware_profile": "test-workstation-amd64",
|
||||
"capabilities": [],
|
||||
"available_bytes": 2,
|
||||
"security_floor": "0.0.0-test.1",
|
||||
"rollback_prerequisite_verified": true
|
||||
},
|
||||
"cases": [
|
||||
{ "id": "valid-workstation", "mutation": {}, "expected": "COMPATIBLE" },
|
||||
{ "id": "server-category", "mutation": { "targets.categories": ["server"] }, "expected": "CATEGORY_INCOMPATIBLE" },
|
||||
{ "id": "server-tier", "mutation": { "targets.tiers": ["starter"] }, "expected": "TIER_INCOMPATIBLE" },
|
||||
{ "id": "arm-only", "mutation": { "artifact.architecture": "arm64" }, "expected": "ARCHITECTURE_INCOMPATIBLE" },
|
||||
{ "id": "wrong-ubuntu", "mutation": { "targets.ubuntu_release": "24.04" }, "expected": "UBUNTU_RELEASE_INCOMPATIBLE" },
|
||||
{ "id": "insufficient-space", "mutation": { "requirements.required_free_bytes": 3 }, "expected": "SPACE_INSUFFICIENT" },
|
||||
{ "id": "missing-capability", "mutation": { "requirements.required_capabilities": ["test-gpu"] }, "expected": "CAPABILITY_MISSING" },
|
||||
{ "id": "security-downgrade", "mutation": { "lifecycle.to_version": "0.0.0-test.0" }, "expected": "SECURITY_FLOOR_VIOLATION" },
|
||||
{ "id": "rollback-missing", "context_mutation": { "rollback_prerequisite_verified": false }, "expected": "ROLLBACK_PREREQUISITE_MISSING" },
|
||||
{ "id": "revoked-key", "trust_mutation": { "key_status": "revoked" }, "expected": "KEY_REVOKED" },
|
||||
{ "id": "bad-signature", "trust_mutation": { "signature_valid": false }, "expected": "SIGNATURE_INVALID" },
|
||||
{ "id": "bad-object", "trust_mutation": { "object_digests_valid": false }, "expected": "OBJECT_DIGEST_MISMATCH" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MCowBQYDK2VwAyEAHExdkCzCGqKqpxeVgRTKNXW+qcemVLaDI3UsFOq5DFA=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.artifact-manifest.v1",
|
||||
"artifact": { "id": "test-only.model-pack", "type": "model-pack", "version": "0.0.0-test.1", "created_at": "2000-01-01T00:00:00Z", "architecture": "amd64", "description": "TEST ONLY" },
|
||||
"source": { "repository": "https://example.invalid/test-only.git", "revision": "0000000000000000000000000000000000000000", "builder": "test-only", "build_recipe_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000" },
|
||||
"targets": { "categories": ["workstation"], "tiers": ["workstation"], "platform_versions": ">=0.0.0-test.1 <0.0.0-test.2", "ubuntu_release": "22.04.5", "hardware_profiles": ["test-workstation-amd64"] },
|
||||
"payload": [{ "path": "models/test-only.bin", "bytes": 1, "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "media_type": "application/octet-stream", "install_scope": "optional", "immutable_source": "test-only@0000000" }],
|
||||
"requirements": { "download_bytes": 1, "unpacked_bytes": 1, "required_free_bytes": 2, "minimum_ram_bytes": 1, "minimum_vram_bytes": 0, "required_capabilities": [] },
|
||||
"lifecycle": { "activation": "import", "reboot": "none", "rollback_class": "operator", "security_floor": "0.0.0-test.1", "health_validation_seconds": 60 },
|
||||
"integrity": { "signature_algorithm": "ed25519", "signing_key_id": "TEST-KEY-DO-NOT-TRUST", "policy_version": "test-only-v1", "revocation_list_version": "test-only-1" },
|
||||
"model": { "provider": "test-only", "model_id": "test/model", "revision": "0000000000000000000000000000000000000000", "runtime": "test-runtime", "activation_name": "test-model" }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.signature-envelope.v1",
|
||||
"manifest_digest": "sha256:938c330b94d20e712e57595a7c284e1abd2b296cdf62c92fe75cdeaa4c44f2da",
|
||||
"algorithm": "ed25519",
|
||||
"key_id": "TEST-KEY-DO-NOT-TRUST",
|
||||
"signed_at": "2000-01-01T00:00:00Z",
|
||||
"policy_version": "test-only-v1",
|
||||
"signature": "dF1yeH7/yuthI34iayBi5RWZUuOHWQxoYYKBkO2e5/Yi5uHQlOkMUS5+9nlujjpRg706TLVqJl1Xc7Mg2n5zCg=="
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"operation_id": "gate2-profile-test-001",
|
||||
"selected_profile": "nvidia-cu128",
|
||||
"state": "installing"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.profile-membership-verification-receipt.v1",
|
||||
"environment": "test",
|
||||
"result": "verified",
|
||||
"manifest_sha256": "3b1fef9705e8049b28d283383f16fa7fd66e7fc00434315b2cc86163ba8e93ac",
|
||||
"envelope_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"key_id": "TEST-ONLY-ED25519",
|
||||
"key_fingerprint_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"trust_snapshot_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
|
||||
"policy_version": "structural-test-v1",
|
||||
"namespace": "offline-workstation/python-runtime-profiles",
|
||||
"profiles": ["cpu-only", "nvidia-cu128"],
|
||||
"verified_at": "2026-07-14T00:00:00Z",
|
||||
"verifier_build_sha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"architecture": "amd64",
|
||||
"nvidia": {
|
||||
"present": true,
|
||||
"supported": true,
|
||||
"driver_ready": true,
|
||||
"device": "NVIDIA GeForce RTX 3050 OEM",
|
||||
"driver": "595.58.03",
|
||||
"memory_bytes": 8222670848
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.signature-cases.v1",
|
||||
"canonicalization": "jq -cS with one trailing newline",
|
||||
"public_key": "ed25519-test-public.pem",
|
||||
"manifest": "workstation-iso-manifest.valid.json",
|
||||
"cases": [
|
||||
{
|
||||
"id": "valid-signature",
|
||||
"manifest_digest": "sha256:e3c8a7f5ac9c0ad1ebc29c739f32dbd3c533d8ac7378b76cca12f30a5ebd5e10",
|
||||
"signature": "G7o7ANH37c6C7eFdavb5Rviyo0p07DZLU0ISBXvBPLNgauJxNc1EqrEKLTUdhlthOrPMfI9vS/zeZH8lgi3UBg==",
|
||||
"expected": "VALID"
|
||||
},
|
||||
{
|
||||
"id": "tampered-manifest",
|
||||
"mutation": { "artifact.description": "TEST ONLY - tampered" },
|
||||
"expected": "MANIFEST_DIGEST_MISMATCH"
|
||||
},
|
||||
{
|
||||
"id": "tampered-signature",
|
||||
"signature": "A7o7ANH37c6C7eFdavb5Rviyo0p07DZLU0ISBXvBPLNgauJxNc1EqrEKLTUdhlthOrPMfI9vS/zeZH8lgi3UBg==",
|
||||
"expected": "SIGNATURE_INVALID"
|
||||
},
|
||||
{
|
||||
"id": "unknown-key",
|
||||
"key_id": "TEST-UNKNOWN-KEY",
|
||||
"expected": "KEY_UNKNOWN"
|
||||
}
|
||||
]
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.artifact-manifest.v1",
|
||||
"artifact": { "id": "test-only.trust-bundle", "type": "trust-bundle", "version": "0.0.0-test.2", "created_at": "2000-01-01T00:00:00Z", "architecture": "multi", "description": "TEST ONLY" },
|
||||
"source": { "repository": "https://example.invalid/test-only.git", "revision": "0000000000000000000000000000000000000000", "builder": "test-only", "build_recipe_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000" },
|
||||
"targets": { "categories": ["workstation", "server"], "tiers": ["workstation", "starter", "basic", "pro", "max"], "platform_versions": ">=0.0.0-test.1 <0.0.0-test.3", "ubuntu_release": "22.04.5", "hardware_profiles": [] },
|
||||
"payload": [{ "path": "trust/test-revocations.json", "bytes": 1, "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "media_type": "application/json", "install_scope": "base", "immutable_source": "test-only" }],
|
||||
"requirements": { "download_bytes": 1, "unpacked_bytes": 1, "required_free_bytes": 2, "minimum_ram_bytes": 0, "minimum_vram_bytes": 0, "required_capabilities": [] },
|
||||
"lifecycle": { "activation": "trust-update", "reboot": "none", "rollback_class": "operator", "security_floor": "0.0.0-test.1", "health_validation_seconds": 60 },
|
||||
"integrity": { "signature_algorithm": "ed25519", "signing_key_id": "TEST-KEY-DO-NOT-TRUST", "policy_version": "test-only-v1", "revocation_list_version": "test-only-2" }
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.signature-envelope.v1",
|
||||
"manifest_digest": "sha256:ebb4f214ba2367ed7d4d8099b9e4892378d068c3dd2699aa2ebd5521a4c4febf",
|
||||
"algorithm": "ed25519",
|
||||
"key_id": "TEST-KEY-DO-NOT-TRUST",
|
||||
"signed_at": "2000-01-01T00:00:00Z",
|
||||
"policy_version": "test-only-v1",
|
||||
"signature": "Cuyu5QvYmzeHMUeoJl6mksPEYpwb0J//QO1hGrUsnT+uz5WAce5O+yoS2TrJDQLi0Ml7wjXw5i/FU3zaxzJcDQ=="
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.artifact-manifest.v1",
|
||||
"artifact": { "id": "test-only.update-bundle", "type": "update-bundle", "version": "0.0.0-test.2", "created_at": "2000-01-01T00:00:00Z", "architecture": "multi", "description": "TEST ONLY" },
|
||||
"source": { "repository": "https://example.invalid/test-only.git", "revision": "0000000000000000000000000000000000000000", "builder": "test-only", "build_recipe_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000" },
|
||||
"targets": { "categories": ["workstation", "server"], "tiers": ["workstation", "starter", "basic", "pro", "max"], "platform_versions": ">=0.0.0-test.1 <0.0.0-test.3", "ubuntu_release": "22.04.5", "hardware_profiles": [] },
|
||||
"payload": [{ "path": "updates/test-only.bin", "bytes": 1, "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000", "media_type": "application/octet-stream", "install_scope": "base", "immutable_source": "test-only@0000000" }],
|
||||
"requirements": { "download_bytes": 1, "unpacked_bytes": 1, "required_free_bytes": 2, "minimum_ram_bytes": 0, "minimum_vram_bytes": 0, "required_capabilities": [] },
|
||||
"lifecycle": { "from_versions": ">=0.0.0-test.1 <0.0.0-test.2", "to_version": "0.0.0-test.2", "activation": "staged-switch", "reboot": "may-require", "rollback_class": "automatic", "security_floor": "0.0.0-test.1", "health_validation_seconds": 600 },
|
||||
"integrity": { "signature_algorithm": "ed25519", "signing_key_id": "TEST-KEY-DO-NOT-TRUST", "policy_version": "test-only-v1", "revocation_list_version": "test-only-1" },
|
||||
"actions": [{ "order": 1, "kind": "replace", "object": "updates/test-only.bin", "failure_action": "rollback" }, { "order": 2, "kind": "validate", "object": "platform-health", "failure_action": "rollback" }]
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.signature-envelope.v1",
|
||||
"manifest_digest": "sha256:179cde97d373c6a7abef8d9ce205534cb8c3f7ef61d05f186e3b30b9ce587fbb",
|
||||
"algorithm": "ed25519",
|
||||
"key_id": "TEST-KEY-DO-NOT-TRUST",
|
||||
"signed_at": "2000-01-01T00:00:00Z",
|
||||
"policy_version": "test-only-v1",
|
||||
"signature": "Y04SAyj+yu1miC3b4ER8yjECsS4Uio1J6dhtvw3ByZAKdHDO2qx7qBGBOP4tR4cdic2XsPJCETgwjItZLxrKDw=="
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate Nexus One AI specification fixtures; never validates production artifacts."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
from jsonschema import Draft202012Validator
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
SCHEMAS = ROOT.parent / "schemas"
|
||||
MANIFEST_SCHEMA = json.loads((SCHEMAS / "artifact-manifest.schema.json").read_text())
|
||||
SIGNATURE_SCHEMA = json.loads((SCHEMAS / "signature-envelope.schema.json").read_text())
|
||||
PROFILE_RECEIPT_SCHEMA = json.loads(
|
||||
(SCHEMAS / "profile-membership-verification-receipt.schema.json").read_text()
|
||||
)
|
||||
|
||||
|
||||
def load(name: str):
|
||||
return json.loads((ROOT / name).read_text())
|
||||
|
||||
|
||||
def canonical(value) -> bytes:
|
||||
return (json.dumps(value, sort_keys=True, separators=(",", ":")) + "\n").encode()
|
||||
|
||||
|
||||
def mutate(value, changes):
|
||||
result = copy.deepcopy(value)
|
||||
for dotted, replacement in changes.items():
|
||||
target = result
|
||||
parts = dotted.split(".")
|
||||
for part in parts[:-1]:
|
||||
target = target[part]
|
||||
target[parts[-1]] = replacement
|
||||
return result
|
||||
|
||||
|
||||
def semver(value: str):
|
||||
match = re.fullmatch(r"(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?", value)
|
||||
if not match:
|
||||
raise AssertionError(f"unsupported semantic version: {value}")
|
||||
major, minor, patch = map(int, match.group(1, 2, 3))
|
||||
prerelease = match.group(4)
|
||||
return major, minor, patch, (0, prerelease) if prerelease is not None else (1, "")
|
||||
|
||||
|
||||
def validate_schemas():
|
||||
Draft202012Validator.check_schema(MANIFEST_SCHEMA)
|
||||
Draft202012Validator.check_schema(SIGNATURE_SCHEMA)
|
||||
Draft202012Validator.check_schema(PROFILE_RECEIPT_SCHEMA)
|
||||
manifest_validator = Draft202012Validator(MANIFEST_SCHEMA)
|
||||
for name in (
|
||||
"workstation-iso-manifest.valid.json",
|
||||
"model-pack-manifest.valid.json",
|
||||
"update-bundle-manifest.valid.json",
|
||||
"trust-bundle-manifest.valid.json",
|
||||
):
|
||||
errors = sorted(manifest_validator.iter_errors(load(name)), key=lambda error: list(error.path))
|
||||
if errors:
|
||||
raise AssertionError(f"{name}: {errors[0].message}")
|
||||
Draft202012Validator(SIGNATURE_SCHEMA).validate(load("workstation-iso-signature.valid.json"))
|
||||
Draft202012Validator(PROFILE_RECEIPT_SCHEMA).validate(
|
||||
load("python-profile-membership-receipt.structural-test.json")
|
||||
)
|
||||
|
||||
|
||||
def validate_signature_cases():
|
||||
manifest = load("workstation-iso-manifest.valid.json")
|
||||
envelope = load("workstation-iso-signature.valid.json")
|
||||
public_key = serialization.load_pem_public_key((ROOT / "ed25519-test-public.pem").read_bytes())
|
||||
cases = load("signature-cases.json")["cases"]
|
||||
for case in cases:
|
||||
candidate = mutate(manifest, case.get("mutation", {}))
|
||||
body = canonical(candidate)
|
||||
digest = "sha256:" + hashlib.sha256(body).hexdigest()
|
||||
key_id = case.get("key_id", envelope["key_id"])
|
||||
if key_id != envelope["key_id"]:
|
||||
actual = "KEY_UNKNOWN"
|
||||
elif digest != envelope["manifest_digest"]:
|
||||
actual = "MANIFEST_DIGEST_MISMATCH"
|
||||
else:
|
||||
signature = base64.b64decode(case.get("signature", envelope["signature"]), validate=True)
|
||||
try:
|
||||
public_key.verify(signature, body)
|
||||
actual = "VALID"
|
||||
except InvalidSignature:
|
||||
actual = "SIGNATURE_INVALID"
|
||||
assert actual == case["expected"], f"{case['id']}: expected {case['expected']}, got {actual}"
|
||||
|
||||
|
||||
def validate_artifact_signatures():
|
||||
public_key = serialization.load_pem_public_key((ROOT / "ed25519-test-public.pem").read_bytes())
|
||||
for prefix in ("workstation-iso", "model-pack", "update-bundle", "trust-bundle"):
|
||||
manifest = load(f"{prefix}-manifest.valid.json")
|
||||
envelope = load(f"{prefix}-signature.valid.json")
|
||||
Draft202012Validator(SIGNATURE_SCHEMA).validate(envelope)
|
||||
body = canonical(manifest)
|
||||
digest = "sha256:" + hashlib.sha256(body).hexdigest()
|
||||
assert digest == envelope["manifest_digest"], f"{prefix}: digest mismatch"
|
||||
signature = base64.b64decode(envelope["signature"], validate=True)
|
||||
public_key.verify(signature, body)
|
||||
tampered = copy.deepcopy(manifest)
|
||||
tampered["artifact"]["description"] = "TEST ONLY - tampered"
|
||||
assert "sha256:" + hashlib.sha256(canonical(tampered)).hexdigest() != envelope["manifest_digest"]
|
||||
|
||||
|
||||
def validate_compatibility_cases():
|
||||
manifest = load("workstation-iso-manifest.valid.json")
|
||||
suite = load("compatibility-cases.json")
|
||||
for case in suite["cases"]:
|
||||
candidate = mutate(manifest, case.get("mutation", {}))
|
||||
context = mutate(suite["base_context"], case.get("context_mutation", {}))
|
||||
trust = case.get("trust_mutation", {})
|
||||
targets = candidate["targets"]
|
||||
lifecycle = candidate["lifecycle"]
|
||||
requirements = candidate["requirements"]
|
||||
if trust.get("key_status") == "revoked":
|
||||
actual = "KEY_REVOKED"
|
||||
elif trust.get("signature_valid") is False:
|
||||
actual = "SIGNATURE_INVALID"
|
||||
elif trust.get("object_digests_valid") is False:
|
||||
actual = "OBJECT_DIGEST_MISMATCH"
|
||||
elif candidate["artifact"]["architecture"] not in ("multi", context["architecture"]):
|
||||
actual = "ARCHITECTURE_INCOMPATIBLE"
|
||||
elif context["category"] not in targets["categories"]:
|
||||
actual = "CATEGORY_INCOMPATIBLE"
|
||||
elif context["tier"] not in targets["tiers"]:
|
||||
actual = "TIER_INCOMPATIBLE"
|
||||
elif semver(lifecycle.get("to_version", context["platform_version"])) < semver(context["security_floor"]):
|
||||
actual = "SECURITY_FLOOR_VIOLATION"
|
||||
elif context["ubuntu_release"] != targets["ubuntu_release"]:
|
||||
actual = "UBUNTU_RELEASE_INCOMPATIBLE"
|
||||
elif targets.get("hardware_profiles") and context["hardware_profile"] not in targets["hardware_profiles"]:
|
||||
actual = "HARDWARE_PROFILE_INCOMPATIBLE"
|
||||
elif not set(requirements.get("required_capabilities", [])).issubset(context["capabilities"]):
|
||||
actual = "CAPABILITY_MISSING"
|
||||
elif context["available_bytes"] < requirements["required_free_bytes"]:
|
||||
actual = "SPACE_INSUFFICIENT"
|
||||
elif lifecycle["rollback_class"] != "none" and not context["rollback_prerequisite_verified"]:
|
||||
actual = "ROLLBACK_PREREQUISITE_MISSING"
|
||||
else:
|
||||
actual = "COMPATIBLE"
|
||||
assert actual == case["expected"], f"{case['id']}: expected {case['expected']}, got {actual}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
validate_schemas()
|
||||
validate_artifact_signatures()
|
||||
validate_signature_cases()
|
||||
validate_compatibility_cases()
|
||||
print("Schema fixtures: PASS (Draft 2020-12)")
|
||||
print("Artifact signatures: PASS (4/4)")
|
||||
print("Signature negative cases: PASS (4/4)")
|
||||
print("Compatibility cases: PASS (12/12)")
|
||||
@@ -0,0 +1,18 @@
|
||||
# Test-Vector Verification Evidence
|
||||
|
||||
**Date**: 2026-07-14
|
||||
**Scope**: Specification fixtures only; not release evidence.
|
||||
|
||||
- Every JSON Schema, manifest, envelope, and case file parsed successfully with `jq`.
|
||||
- Canonical Workstation bytes were produced with `jq -cS`, including its single trailing newline.
|
||||
- Canonical SHA-256: `e3c8a7f5ac9c0ad1ebc29c739f32dbd3c533d8ac7378b76cca12f30a5ebd5e10`.
|
||||
- The 64-byte detached signature verified successfully with the committed Ed25519 test public key.
|
||||
- The private test key was generated only for this vector and deleted after signing.
|
||||
- `git diff --check` passed after the fixture additions.
|
||||
- Automated validation using `jsonschema` Draft 2020-12 and `cryptography` passed:
|
||||
`Schema fixtures: PASS (Draft 2020-12)`, `Artifact signatures: PASS (4/4)`,
|
||||
`Signature negative cases: PASS (4/4)`, and `Compatibility cases: PASS (12/12)`.
|
||||
|
||||
This proves the current structural schemas, all four test-only artifact signatures, negative signature
|
||||
cases, and compatibility cases are internally consistent. It does not approve the signing policy,
|
||||
exercise real payload objects, or validate any production artifact.
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.artifact-manifest.v1",
|
||||
"artifact": {
|
||||
"id": "test-only.offline-workstation",
|
||||
"type": "iso-payload",
|
||||
"version": "0.0.0-test.1",
|
||||
"created_at": "2000-01-01T00:00:00Z",
|
||||
"architecture": "amd64",
|
||||
"description": "TEST ONLY - not a release artifact"
|
||||
},
|
||||
"source": {
|
||||
"repository": "https://example.invalid/test-only.git",
|
||||
"revision": "0000000000000000000000000000000000000000",
|
||||
"builder": "test-only",
|
||||
"build_recipe_digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000"
|
||||
},
|
||||
"targets": {
|
||||
"categories": ["workstation"],
|
||||
"tiers": ["workstation"],
|
||||
"platform_versions": ">=0.0.0-test.1 <0.0.0-test.2",
|
||||
"ubuntu_release": "22.04.5",
|
||||
"hardware_profiles": ["test-workstation-amd64"]
|
||||
},
|
||||
"payload": [
|
||||
{
|
||||
"path": "payload/test-only.bin",
|
||||
"bytes": 1,
|
||||
"digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"media_type": "application/octet-stream",
|
||||
"install_scope": "base",
|
||||
"immutable_source": "test-only"
|
||||
}
|
||||
],
|
||||
"requirements": {
|
||||
"download_bytes": 1,
|
||||
"unpacked_bytes": 1,
|
||||
"required_free_bytes": 2,
|
||||
"minimum_ram_bytes": 1,
|
||||
"minimum_vram_bytes": 0,
|
||||
"required_capabilities": []
|
||||
},
|
||||
"lifecycle": {
|
||||
"activation": "install",
|
||||
"reboot": "required",
|
||||
"rollback_class": "restore",
|
||||
"security_floor": "0.0.0-test.1",
|
||||
"health_validation_seconds": 60
|
||||
},
|
||||
"integrity": {
|
||||
"signature_algorithm": "ed25519",
|
||||
"signing_key_id": "TEST-KEY-DO-NOT-TRUST",
|
||||
"policy_version": "test-only-v1",
|
||||
"revocation_list_version": "test-only-1"
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schema": "com.cezen.nexus-one.signature-envelope.v1",
|
||||
"manifest_digest": "sha256:e3c8a7f5ac9c0ad1ebc29c739f32dbd3c533d8ac7378b76cca12f30a5ebd5e10",
|
||||
"algorithm": "ed25519",
|
||||
"key_id": "TEST-KEY-DO-NOT-TRUST",
|
||||
"signed_at": "2000-01-01T00:00:00Z",
|
||||
"policy_version": "test-only-v1",
|
||||
"signature": "G7o7ANH37c6C7eFdavb5Rviyo0p07DZLU0ISBXvBPLNgauJxNc1EqrEKLTUdhlthOrPMfI9vS/zeZH8lgi3UBg=="
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
# Shared Offline Update and Rollback Policy
|
||||
|
||||
**Status**: Approval draft; no implementation authority.
|
||||
|
||||
## Scope
|
||||
|
||||
One signed offline-update format applies to Workstation and Server S/M/L/Max. The manifest selects
|
||||
compatible actions by product category, internal tier, platform version, architecture, provisioned
|
||||
components, and hardware profile. An update never changes commercial entitlement.
|
||||
|
||||
This policy covers platform files, portal/backend, deployment configuration, system services,
|
||||
containers, Python/runtime environments, database schema, models, drivers, kernel/OS packages, trust
|
||||
roots, and local documentation. Each surface declares its rollback class before confirmation.
|
||||
|
||||
## Existing-State Finding
|
||||
|
||||
The current backup helper archives `/opt/cezen/data` and creates a pre-restore data snapshot. Existing
|
||||
SQLite migrations are intended to be transactional and idempotent. This is useful customer-data
|
||||
protection but is **not** a complete platform rollback: it does not prove recovery of application
|
||||
files, service units, Ansible state, container images, Python environments, drivers/kernel, models,
|
||||
trust policy, or every configuration outside the data directory.
|
||||
|
||||
No update may claim rollback solely because the current ZIP backup completed.
|
||||
|
||||
## Update Classes
|
||||
|
||||
| Class | Examples | Required rollback class |
|
||||
|---|---|---|
|
||||
| A — Content/config | Portal, local help, additive configuration | Automatic side-by-side switch where possible |
|
||||
| B — Application/runtime | Backend, Python environment, containers, Ollama/vLLM runtime | Automatic or operator switch to retained last-known-good immutable payload |
|
||||
| C — Data/schema | SQLite schema or data transformation | Transaction rollback before commit; verified data restore after commit |
|
||||
| D — System | Kernel, NVIDIA driver, container runtime, OS packages, systemd/Nginx | Reboot-aware snapshot/package rollback or verified restore/recovery procedure |
|
||||
| E — Trust/security floor | Trust roots, revocation data, minimum accepted version | Operator rollback only when signed policy permits; never below active security floor |
|
||||
| F — Model pack | Model objects, templates, runtime metadata | Atomic activation pointer; retain previous model until inference validation passes |
|
||||
|
||||
An update containing multiple classes inherits the least reversible class. `rollback_class: none` is
|
||||
not allowed for routine release. An exceptional non-reversible update requires a separate signed
|
||||
authorization, verified full recovery image, product/security approval, explicit customer impact, and
|
||||
a controlled-pilot gate.
|
||||
|
||||
## On-Disk State and Retention
|
||||
|
||||
The target architecture maintains:
|
||||
|
||||
- one immutable **current** platform inventory;
|
||||
- one immutable **last-known-good** platform inventory;
|
||||
- one verified pre-update data/config backup compatible with the last-known-good platform;
|
||||
- content-addressed update staging separate from active paths;
|
||||
- current and previous container/runtime/model digests needed for the declared rollback;
|
||||
- durable update operation, audit, manifest, signature, validation, and recovery evidence.
|
||||
|
||||
Current and last-known-good versions MUST be activated through an atomic pointer/symlink or equivalent
|
||||
transactional switch wherever supported. Mutable customer data is never stored inside versioned
|
||||
application trees. Models may remain in a shared content-addressed store; activation metadata is
|
||||
versioned and garbage collection cannot remove an object referenced by current, last-known-good,
|
||||
backup, or active staging state.
|
||||
|
||||
Default retention is current plus one last-known-good version and the newest verified pre-update
|
||||
backup. Additional history is optional and capacity-bound. Preflight computes staging, unpacked,
|
||||
backup/snapshot, previous-version, model, and safety-headroom bytes separately. Insufficient capacity
|
||||
blocks the update before mutation; the updater never deletes last-known-good recovery state to make
|
||||
space automatically.
|
||||
|
||||
## Preflight and Checkpoint
|
||||
|
||||
Before mutation:
|
||||
|
||||
1. Complete trust, signature, object, compatibility, license, security-floor, and capacity checks.
|
||||
2. Reject conflicting installation, update, restore, removal, model-import, or trust operations.
|
||||
3. Inventory current source/build, application files, configs, services, packages, containers,
|
||||
runtimes, schema, models, trust policy, and active hardware profile.
|
||||
4. Verify the current state is healthy enough to distinguish a pre-existing fault from update impact.
|
||||
5. Create the class-required checkpoint and verify readability, checksums, schema compatibility, and
|
||||
restore instructions. A path existing is not verification.
|
||||
6. Display service disruption, reboot requirements, estimated space/time, rollback class and limits,
|
||||
retained/deleted state, and recovery owner before authorization.
|
||||
|
||||
## Activation Order
|
||||
|
||||
Default ordered phases are `received`, `verified`, `staged`, `prechange_saved`, `quiescing`,
|
||||
`data_migrating`, `switching`, `services_starting`, `awaiting_reboot`, `validating`, and terminal
|
||||
`succeeded`, `rolled_back`, `failed_safe`, or `recovery_required`.
|
||||
|
||||
- Stop writes or establish an application-consistent data checkpoint before schema/application switch.
|
||||
- Apply idempotent migrations sequentially in one transaction where SQLite permits.
|
||||
- Switch application/config/container/model references only after all target objects are local.
|
||||
- Restart services in dependency order with bounded timeouts.
|
||||
- A required reboot resumes the same operation ID from durable state.
|
||||
- Do not garbage-collect staging or last-known-good content until validation and approval complete.
|
||||
|
||||
## Health Validation and Commit
|
||||
|
||||
The proposed default validation window is ten minutes after all required services become ready, plus
|
||||
explicit checks for database/schema, portal/API, authentication, license/entitlement, storage,
|
||||
selected local model inference, container/service restart count, and hardware runtime where relevant.
|
||||
The window restarts after a required reboot or unexpected service restart.
|
||||
|
||||
Success requires every mandatory check to pass and the active inventory to match the signed target
|
||||
manifest. Optional remote connectors may remain explicitly unavailable when no approved route exists.
|
||||
Only then does target become current and former current become last-known-good.
|
||||
|
||||
## Rollback Decision
|
||||
|
||||
| Condition | Required action |
|
||||
|---|---|
|
||||
| Failure before active switch | Delete/quarantine staging; current remains active; `failed_safe` |
|
||||
| File/runtime switch fails before data commit | Switch to last-known-good; restart/validate; `rolled_back` |
|
||||
| Transactional migration fails | Roll back transaction; restore application pointer if changed |
|
||||
| Post-commit schema/application validation fails | Stop writes; restore verified pre-update data plus last-known-good application as one recovery unit |
|
||||
| Driver/kernel boot failure | Boot approved previous kernel/snapshot or enter documented local recovery; never loop indefinitely |
|
||||
| Health window fails | Automatic rollback when class permits; otherwise `recovery_required` with checkpoint identity |
|
||||
| Rollback validation fails | Preserve both failure causes and all evidence; stop in `recovery_required`; no repeated automatic loop |
|
||||
|
||||
Automatic rollback is attempted at most once per operation. A retry creates a linked operation and
|
||||
requires renewed preflight. Rollback does not bypass the installed signed security floor.
|
||||
|
||||
## Interruption Matrix
|
||||
|
||||
- Before checkpoint: current remains active; restart verification/staging safely.
|
||||
- During checkpoint: incomplete checkpoint is invalid and cannot authorize activation.
|
||||
- During transactional migration: transaction rolls back; verify DB before retry.
|
||||
- Between migration and application switch: resume declared order or restore checkpoint; never infer
|
||||
completion from file presence alone.
|
||||
- During pointer switch: reconcile signed inventory to exactly current or target, never a mixture.
|
||||
- During service restart: resume validation against recorded active inventory.
|
||||
- During reboot: boot marker resumes the same operation; bounded boot attempts trigger recovery.
|
||||
- During rollback/restore: preserve original and rollback error; require operator recovery if the
|
||||
verified checkpoint cannot be restored.
|
||||
|
||||
## Ownership and Approval
|
||||
|
||||
| Responsibility | Accountable owner |
|
||||
|---|---|
|
||||
| Bundle production, manifest and action ordering | Platform release owner |
|
||||
| Signing, security floor, trust changes, emergency authorization | Security owner |
|
||||
| Migration forward/restore compatibility | Data/backend owner |
|
||||
| Driver/kernel/OS recovery | Platform delivery owner |
|
||||
| Model/runtime compatibility and inference checks | AI platform owner |
|
||||
| Customer disruption, support runbook, recovery exercise | Delivery/support owner |
|
||||
| Release scope and controlled pilot | Product owner |
|
||||
|
||||
## Evidence Gate
|
||||
|
||||
Approval requires positive update and rollback from every supported previous baseline plus negative
|
||||
tests for wrong product/tier/architecture, revoked key, stale policy, corrupted object/cache, low disk,
|
||||
conflicting operation, checkpoint failure, migration failure, service failure, network removal,
|
||||
power loss at every mutating boundary, reboot failure, health-window failure, automatic rollback,
|
||||
restore-based rollback, and rollback failure. Evidence records both active and target inventories,
|
||||
schema versions, checkpoint checksums, operation/correlation IDs, service/model checks, and final
|
||||
recovery status.
|
||||
|
||||
## Owner Decisions Still Open
|
||||
|
||||
- Approve ten-minute health window or choose another measured value.
|
||||
- Select the platform versioned-tree/atomic-switch mechanism and system snapshot mechanism.
|
||||
- Define full backup inventory beyond `/opt/cezen/data`, encryption, external-copy policy, and restore SLA.
|
||||
- Define supported previous-version window, update cadence, retention beyond current+one, and disk quota.
|
||||
- Define kernel/driver rollback mechanism for each supported hardware/OS profile.
|
||||
- Approve exceptional non-reversible/break-glass authority and customer confirmation language.
|
||||
@@ -0,0 +1,108 @@
|
||||
# Offline Workstation Hardware and Starter-Model Baseline
|
||||
|
||||
**Status**: Evidence-backed approval draft; no implementation authority.
|
||||
**Evidence date**: 2026-07-14.
|
||||
|
||||
The first release explicitly excludes AMD GPU acceleration, ROCm, and Strix Halo acceleration. An
|
||||
AMD64 host may still use the truthful CPU-only profile, but no AMD GPU capability is promised.
|
||||
|
||||
## Hardware Architecture Decision Required
|
||||
|
||||
| Hardware family | CPU architecture | Memory / VRAM | Storage | Current conclusion |
|
||||
|---|---|---|---|---|
|
||||
| NVIDIA DGX Spark | ARM64 Grace Blackwell, 20-core CPU | 128 GB unified LPDDR5x | 1 TB or 4 TB NVMe | Not compatible with an AMD64-only Ubuntu ISO; 1 TB variant also contradicts the current 2 TB baseline |
|
||||
| GeForce RTX 5090 Workstation | Host CPU remains an approved AMD64 system decision; GPU is Blackwell | 32 GB GDDR7 GPU memory | Repo baseline says 2 TB NVMe; official GPU page does not define host storage | Candidate for the first AMD64 validation profile |
|
||||
| RTX PRO 6000 Blackwell Workstation Edition | Host CPU remains an approved AMD64 system decision; GPU is Blackwell | 96 GB GDDR7 ECC | Repo baseline says 2 TB NVMe; GPU documentation does not define host storage | Candidate for the second AMD64 validation profile |
|
||||
|
||||
NVIDIA documents DGX Spark as a 20-core ARM64 Grace Blackwell system with 128 GB unified memory and
|
||||
1 TB or 4 TB NVMe. NVIDIA documents RTX 5090 with 32 GB GDDR7 and RTX PRO 6000 Blackwell Workstation
|
||||
Edition with 96 GB GDDR7 ECC. GPU specifications do not establish the surrounding workstation CPU,
|
||||
RAM, storage, firmware, or motherboard support contract.
|
||||
|
||||
### Recommended release decision
|
||||
|
||||
Keep one customer-facing **Offline Workstation** product with a universal, hardware-adaptive payload
|
||||
inside each CPU architecture:
|
||||
|
||||
- `Offline Workstation amd64 ISO` first, supporting compatible AMD64 systems from CPU-only or
|
||||
low-VRAM NVIDIA GPUs through RTX 3050/4090/5090 and RTX PRO-class GPUs. GPU marketing names do not
|
||||
select media; detected VRAM, driver/runtime compatibility, RAM, disk, and capabilities select the
|
||||
safe runtime profile.
|
||||
- `Offline Workstation arm64 ISO` later for DGX Spark, using its supported OS/runtime/container/model
|
||||
stack and independent evidence gate. It is the same Workstation product, not a new commercial tier.
|
||||
|
||||
An alternative single multi-architecture boot image is not recommended until a reproducible Ubuntu
|
||||
boot/build design proves it can boot and install both architectures without duplicating most payloads.
|
||||
Removing DGX Spark from the supported hardware list is the other coherent option. Merely relabelling
|
||||
the existing AMD64 artifact as DGX Spark-compatible is prohibited.
|
||||
|
||||
## Universal AMD64 Capability Profiles
|
||||
|
||||
The ISO MUST boot and install the same core platform across profiles. Hardware discovery chooses which
|
||||
local inference services and starter-model backends are enabled. Unsupported capabilities remain
|
||||
installed-but-disabled or omitted with a truthful reason; the installer does not fail merely because
|
||||
a high-end GPU is absent.
|
||||
|
||||
| Profile | Detected evidence | Required behavior |
|
||||
|---|---|---|
|
||||
| `core` | Less than 32 GB RAM or no supported local inference capacity, including AMD GPU hosts in the first release | Portal, administration, document/workflow surfaces supported within their own RAM/disk prerequisites; local GPU model serving not promised |
|
||||
| `cpu-ai` | At least 32 GB RAM and 8 CPU cores, no usable NVIDIA VRAM | Small quantized Ollama inference may use CPU; vLLM and GPU-only functions disabled with explanation |
|
||||
| `gpu-lite` | NVIDIA GPU with at least 8 GB detected VRAM | Small quantized Ollama chat/embedding enabled; vLLM/fine-tuning disabled; this covers qualifying RTX 3050 variants based on measured VRAM, not name |
|
||||
| `gpu-starter` | At least 24 GB detected VRAM | Ollama plus approved vLLM/fine-tuning starter capabilities; representative RTX 4090/5090-class validation |
|
||||
| `gpu-standard` | At least 48 GB detected VRAM | Higher-capacity single-GPU capabilities; representative RTX PRO-class validation |
|
||||
|
||||
These thresholds reflect the current feasibility checker and are planning baselines, not final
|
||||
support guarantees. The Workstation category remains fixed; these are capability profiles, not Server
|
||||
S/M/L/Max tiers and not commercial entitlements.
|
||||
|
||||
System RAM and disk minimums MUST be expressed per capability. A universal ISO may install the core
|
||||
platform on smaller hardware while blocking local models when RAM, VRAM, or free disk is insufficient.
|
||||
The media itself still needs enough target disk for its embedded payload and recovery headroom.
|
||||
|
||||
## Universal Payload Behavior
|
||||
|
||||
- Embed the common platform and smallest approved starter models once for AMD64.
|
||||
- Prefer Ollama small-model inference for `gpu-lite` and supported CPU fallback.
|
||||
- Enable the embedded vLLM Phi-3 snapshot only when the validated VRAM/runtime profile permits it.
|
||||
- Do not download a different payload during offline installation.
|
||||
- Do not expose different Workstation license tiers based on GPU size.
|
||||
- Do not install ROCm or claim AMD GPU acceleration in the first release.
|
||||
- Allow separately signed optional model packs after installation, subject to hardware, storage,
|
||||
runtime, license, and compatibility checks.
|
||||
- Record the chosen profile and every disabled capability in readiness/support evidence.
|
||||
|
||||
## Immutable Starter-Model Candidates
|
||||
|
||||
| Runtime use | Current mutable input | Approval pin | License evidence | Status |
|
||||
|---|---|---|---|---|
|
||||
| Ollama chat | `phi3:mini` | Ollama manifest `sha256:4f222292793889a9a40a020799cfd28d53f3e01af25d48e06c5e708610fc47e9`; model layer `sha256:633fc5be925f9a484b61d6f9b9a78021eeb462100bd557309f01ba84cac26adf` | MIT | Approved under `CT-G1-2026-008`; packaged file/notice evidence pending |
|
||||
| Ollama embeddings | `nomic-embed-text` | Ollama v1.5 manifest `sha256:0a109f422b47e3a30ba2b10eca18548e944e8a23073ee3f3e947efcf3c45e59f` | Apache-2.0 upstream | Approved under `CT-G1-2026-008`; packaged license blob/attribution evidence pending |
|
||||
| vLLM chat | `microsoft/Phi-3-mini-4k-instruct` | Hugging Face commit `f39ac1d28e925b323eae81227eaba4464caced4e` | MIT | Approved under `CT-G1-2026-008` for validated 24 GB-or-higher profiles; exact downloaded-file inventory/digests and redistribution notice pending |
|
||||
|
||||
Pins are approval candidates, not permission to modify `payload.env` or build media. The release
|
||||
manifest MUST record every actual file/layer digest. Tag and commit identity alone does not replace
|
||||
post-download object verification.
|
||||
|
||||
## Acceptance Still Required
|
||||
|
||||
1. Product owner confirms universal hardware-adaptive behavior per CPU architecture and chooses a
|
||||
later ARM64 DGX Spark artifact, a proven multi-architecture artifact, or removal of DGX Spark.
|
||||
2. Delivery owner approves AMD64 low/mid/high validation machines, including at least CPU-only or
|
||||
sub-8 GB behavior, an 8 GB-class GPU, a 24 GB-class GPU, and a 48 GB-or-higher GPU.
|
||||
3. Platform owner approves `workstation-runtime-compatibility-baseline.md`, resolves its branch-level
|
||||
baseline to exact immutable package/image/object locks, and validates it separately for AMD64 and
|
||||
any future ARM64 artifact.
|
||||
4. AI/platform and legal owners approve model revisions, redistribution, attribution, safety/use
|
||||
boundaries, and local inference acceptance prompts.
|
||||
5. Firmware/UEFI/Secure Boot, no-GPU, driver-missing, 6 GB, 8 GB, 24 GB, 32 GB, 48 GB-or-higher,
|
||||
insufficient RAM/storage, multi-GPU, and driver rollback cases are added to the disconnected matrix.
|
||||
|
||||
## Official Evidence
|
||||
|
||||
- NVIDIA DGX Spark hardware overview: https://docs.nvidia.com/dgx/dgx-spark/hardware.html
|
||||
- NVIDIA GeForce RTX 5090 specifications: https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5090/
|
||||
- NVIDIA RTX PRO 6000 Blackwell architecture/specifications: https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/quadro-product-literature/pdf/NVIDIA-RTX-Blackwell-PRO-GPU-Architecture-v1_1.pdf
|
||||
- Ollama Phi-3 tags and license: https://ollama.com/library/phi3/tags
|
||||
- Ollama Nomic Embed Text tags: https://ollama.com/library/nomic-embed-text/tags
|
||||
- Hugging Face Phi-3 Mini model and MIT license: https://huggingface.co/microsoft/Phi-3-mini-4k-instruct
|
||||
- Nomic Embed Text v1.5 upstream license: https://huggingface.co/nomic-ai/nomic-embed-text-v1.5
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
# Offline Workstation Runtime Compatibility Baseline
|
||||
|
||||
**Status**: G1-14 direction approved under `CT-G1-2026-007`; immutable locks and executed evidence
|
||||
remain open; no implementation authority.
|
||||
**Evidence date**: 2026-07-14.
|
||||
|
||||
## Repository Finding
|
||||
|
||||
The current runtime declarations are not one compatible immutable stack:
|
||||
|
||||
- `ansible/roles/nvidia/tasks/main.yml` installs `nvidia-driver-550-open`, CUDA Toolkit/CUDART 12.4
|
||||
and unversioned cuDNN 9 packages;
|
||||
- `ansible/starter.yml` declares CUDA 12.6 and says RTX 5090 requires 12.6 or later;
|
||||
- `autoinstall/offline/container-images.txt` and the vLLM role use `vllm/vllm-openai:v0.10.2`
|
||||
without an image digest;
|
||||
- the vLLM 0.10.2 production image identifies its CUDA runtime as 12.8.1 in upstream diagnostics;
|
||||
- Docker, NVIDIA Container Toolkit, Ollama, Python/Conda packages and the Ubuntu kernel are acquired
|
||||
without a complete exact-version/digest lock.
|
||||
|
||||
NVIDIA's published support matrix identifies CUDA 12.8 as the first CUDA Toolkit support for
|
||||
Blackwell architectures. CUDA 12.8.1 requires Linux driver 570.124.06 or later for the toolkit-driver
|
||||
pair. Therefore driver 550/CUDA 12.4 cannot be the accepted universal baseline while RTX 5090 and RTX
|
||||
PRO Blackwell profiles are in scope.
|
||||
|
||||
## Proposed AMD64 Release Baseline
|
||||
|
||||
| Surface | Proposed decision | Immutable release evidence still required |
|
||||
|---|---|---|
|
||||
| OS installer | Ubuntu Server 22.04.5 AMD64 | Canonical ISO digest/signature and redistribution record |
|
||||
| Kernel | Ubuntu 22.04 HWE kernel compatible with the selected R570 open module | Exact package/version/digest set, Secure Boot signing path, boot/rollback evidence on every physical profile |
|
||||
| NVIDIA driver | R570 open-kernel-module branch; exact release MUST be at least 570.124.06 and identical across accepted NVIDIA profiles unless a signed exception matrix exists | Exact Ubuntu package versions/digests, supported GPU IDs, module signing and rollback package set |
|
||||
| Host CUDA | CUDA Toolkit/CUDART 12.8.1 only where native build/training tools require it; container-only inference MUST NOT depend on an accidental host toolkit | Exact packages/digests and proof that native consumers require them |
|
||||
| cuDNN | CUDA 12-compatible cuDNN release selected and locked with the native framework set | Exact version/packages/digests and framework compatibility |
|
||||
| vLLM | `vllm/vllm-openai:v0.10.2` candidate with CUDA 12.8.1, stored and referenced by OCI digest rather than tag | Registry manifest/config/layer digests, architecture, SBOM/license, Phi-3 smoke inference on 24 GB and higher profiles |
|
||||
| NVIDIA Container Toolkit | Stable `1.19.1-1` candidate and matching `base`, `libnvidia-container-tools`, and `libnvidia-container1` packages | Exact Ubuntu packages/digests; Docker and containerd configuration/reload tests |
|
||||
| Container engine | One approved Docker/containerd package set; no `latest` repository resolution | Exact packages/digests/config and GPU smoke test after daemon reload/reboot |
|
||||
| Ollama | One release binary/runtime bundle valid for AMD64 CPU and NVIDIA profiles | Exact version, archive/object digests, license/SBOM and CPU/8 GB/24 GB smoke evidence |
|
||||
| Python/Conda | One explicit lock per environment, including Python, PyTorch, Transformers, PEFT, bitsandbytes and training dependencies | Exact interpreter/package/wheel/conda build IDs, hashes, indexes, licenses and import/inference tests |
|
||||
|
||||
The accepted artifact MUST record actual package versions and digests, not only the branch-level values
|
||||
above. A repository snapshot may choose a later R570 maintenance release, but it cannot silently move
|
||||
to R575/R580 or another CUDA/vLLM baseline without a new compatibility decision and regression run.
|
||||
|
||||
## Capability Behavior
|
||||
|
||||
- `core` and `cpu-ai` MUST install and remain healthy without NVIDIA packages being a readiness
|
||||
prerequisite. Ollama CPU smoke inference is required only for `cpu-ai`.
|
||||
- NVIDIA profiles MUST verify GPU PCI identity, loaded driver/module, Secure Boot state, container
|
||||
runtime GPU enumeration, CUDA container smoke test and declared model-runtime smoke inference.
|
||||
- `gpu-lite` uses Ollama only unless a separately tested vLLM configuration fits the exact 8 GB target.
|
||||
- `gpu-starter` and `gpu-standard` may enable vLLM only after the selected model fits and passes the
|
||||
declared memory/health window. VRAM threshold alone never proves model compatibility.
|
||||
- A driver/module load failure degrades to the truthful CPU profile when CPU prerequisites pass; it
|
||||
MUST NOT claim GPU readiness or automatically fetch a driver.
|
||||
- AMD GPU/ROCm remains absent. An AMD64 host with an AMD GPU follows the CPU-only behavior.
|
||||
|
||||
## Required Compatibility Evidence
|
||||
|
||||
Before G1-14 is complete:
|
||||
|
||||
1. Resolve every package/binary/image/environment object to version, architecture, size, digest and
|
||||
license in the signed inventory.
|
||||
2. Prove the selected HWE kernel and driver across no-GPU, 8 GB, 24 GB and 48 GB-or-higher physical
|
||||
targets, including Secure Boot enabled/disabled as supported.
|
||||
3. Test install, reboot persistence, daemon reload, missing/corrupt driver, kernel upgrade, driver
|
||||
upgrade, rollback and rollback failure without network access.
|
||||
4. Run CUDA container enumeration and model smoke tests from the exact OCI digests; record peak RAM,
|
||||
VRAM, disk and startup time.
|
||||
5. Prove CPU-only installation does not fail because NVIDIA components are absent.
|
||||
6. Reconcile the resolved runtime inventory against ISO contents, SBOM, provenance and rollback
|
||||
checkpoint.
|
||||
|
||||
## Approval Decision
|
||||
|
||||
Cezen Technologies approved this direction as G1-14 under `CT-G1-2026-007`, while leaving exact
|
||||
package/image/object digests evidence-open. Gate 1 still fails until the immutable lock, physical compatibility results and
|
||||
rollback evidence exist. Approval MUST also acknowledge that current driver 550/CUDA 12.4 automation
|
||||
is contradictory legacy behavior and cannot be used unchanged for Blackwell-capable release media.
|
||||
|
||||
## Official Evidence
|
||||
|
||||
- NVIDIA CUDA 12.8 release notes and driver requirements:
|
||||
https://docs.nvidia.com/cuda/archive/12.8.0/cuda-toolkit-release-notes/index.html
|
||||
- NVIDIA driver architecture support matrix:
|
||||
https://docs.nvidia.com/datacenter/tesla/pdf/NVIDIA_Datacenter_Drivers.pdf
|
||||
- NVIDIA Container Toolkit install guide and current package pin example:
|
||||
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html
|
||||
- NVIDIA Container Toolkit supported platforms:
|
||||
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/supported-platforms.html
|
||||
- vLLM 0.10.2 GPU installation and production image documentation:
|
||||
https://docs.vllm.ai/en/v0.10.2/getting_started/installation/gpu.html
|
||||
https://docs.vllm.ai/en/v0.10.2/deployment/docker.html
|
||||
- vLLM 0.10.2 PyPI release files and embedded wheel metadata used to derive the matching
|
||||
`torch==2.8.0`, `torchaudio==2.8.0` and `torchvision==0.23.0` candidate pins:
|
||||
https://pypi.org/project/vllm/0.10.2/
|
||||
- PyTorch 2.8.0 CPU and CUDA 12.8 index selection matrix:
|
||||
https://pytorch.org/get-started/previous-versions/
|
||||
Reference in new issue
Block a user