Blueprint: modeld Setup Artifact Detection
Status: draft implementation blueprint. Scope is the
contenox setupcheck that discovers, downloads, verifies, installs, and validates a prebuiltmodeldpackage for the current machine. Release production is covered by modeld release artifacts.
Problem
contenox setup currently treats local llama and openvino providers as a
source-build-only path. Selecting either provider prints instructions to clone the
runtime repository and build modeld locally.
That is no longer the desired default. Official modeld packages are published to
the public release prefix in S3, keyed by version and platform. The contenox CLI
should check that public release surface first. If a package exists for the CLI
version and current OS/architecture, setup should install it. If not, setup should
fall back to the existing source-build instructions.
Goals
- Bake the public
modeldrelease base URL into the releasedcontenoxbinary. - Detect the current platform from
runtime.GOOSandruntime.GOARCH. - Resolve the exact expected
modeldpackage for the running CLI version. - Check public S3/HTTPS for that package without requiring AWS credentials or the AWS CLI.
- Download only final
modeldpackages, never native dependency bundles. - Verify the downloaded archive against its
.sha256file before extraction. - Install
modeldinto a per-user location that setup and runtime can find. - Validate the installed binary with
modeld version --json. - Start
modeldnormally; backend autodetection and live backend choice belong tomodeld, notcontenox setup. - Keep source-build instructions as the fallback for unsupported platforms, unpublished versions, network failures, or failed validation.
Non-Goals
- No public download of
modeld-deps/native dependency bundles. - No runtime rebuild of llama.cpp, OpenVINO, CUDA, HIP, or Metal.
- No service manager design in this blueprint. Starting
modeld, background lifecycle, launchd/systemd/Windows service integration, and auto-restart are follow-up work. - No “latest” channel. The default check is exact-version only so
contenoxandmodeldstay aligned. - No dependency on a repo-local
.env. End users must not need environment setup. - No setup-side backend forcing. Setup must not ask users to set
CONTENOX_MODELD_BACKENDand must not use it as the normal launch path.
Public Release Contract
The public base URL is compiled into the CLI:
const defaultModeldReleaseBaseURL = "https://contenox-modeld-artifacts-573643652148.s3.amazonaws.com/modeld"
The released binary must use that compiled default. Tests can inject an alternate base URL through internal package options; end users should not set environment variables for normal setup.
Only the final package prefix is public:
https://contenox-modeld-artifacts-573643652148.s3.amazonaws.com/modeld/
The native dependency prefix remains private:
s3://contenox-modeld-artifacts-573643652148/modeld-deps/
contenox setup should use HTTPS. It should not shell out to aws, require AWS
credentials, list the bucket, or know anything about dependency bundle
fingerprints.
Artifact Naming
The release path is deterministic:
<base-url>/<version>/<artifact-name>
<base-url>/<version>/<artifact-name>.sha256
Unix artifacts:
modeld-<version>-<goos>-<goarch>.tar.gz
Windows artifacts:
modeld-<version>-windows-<goarch>.zip
Examples:
https://contenox-modeld-artifacts-573643652148.s3.amazonaws.com/modeld/v0.32.5/modeld-v0.32.5-linux-amd64.tar.gz
https://contenox-modeld-artifacts-573643652148.s3.amazonaws.com/modeld/v0.32.5/modeld-v0.32.5-linux-amd64.tar.gz.sha256
The platform string is:
platform := runtime.GOOS + "-" + runtime.GOARCH
Supported package extensions:
| GOOS | Extension |
|---|---|
linux | .tar.gz |
darwin | .tar.gz |
windows | .zip |
Unsupported GOOS/GOARCH pairs should skip download and print source-build instructions.
Version Selection
The normal version source is the compiled CLI version:
version := strings.TrimSpace(contenoxcli.CLIVersion())
The default download path should only run when version is an official release
tag, currently a string beginning with v, for example v0.32.5.
For development builds where the CLI version is empty, dev, main, or otherwise
not a release tag, setup should not silently download an arbitrary package. It
should fall back to source-build instructions. Tests can inject a release version
through internal package options.
Check Algorithm
When the selected provider is llama or openvino, setup should:
- Probe any already installed
modeld. - If a compatible local
modeldexists and has the compiled capability needed by the selected provider, use it. - Resolve the desired release artifact from CLI version and platform.
- Fetch
<artifact>.sha256over HTTPS. - If
.sha256returns404, report that no prebuilt package exists for this version/platform and print source-build instructions. - If
.sha256returns another HTTP or network error, report the download check failed and print source-build instructions. - Download the archive to a temporary file under the user cache/temp directory.
- Verify the archive SHA-256 against the downloaded
.sha256. - Extract into a versioned per-user install directory.
- Run installed
modeld version --json. - Verify compiled capability:
- provider
llama:backendsmust includellama. - provider
openvino:backendsmust includeopenvino.
- provider
- Persist enough state for future CLI runs to find the installed binary.
- Start
modeldnormally, or print the normal start command if service/startup management has not landed yet. - Continue setup by showing model-pull choices for the selected provider.
The .sha256 file is the availability check. Do not list S3. Listing public S3 is
unnecessary, slower, and makes the CLI depend on bucket-specific behavior.
Setup does not choose the live backend. A package may contain both llama and
openvino; modeld serve probes the host and selects its live backend internally.
Setup and doctor can report what the live daemon selected after startup, but they
must not preselect it.
Existing modeld Probe
Before downloading, setup should check for an already usable binary:
CONTENOX_MODELD_BIN, if set.- Previously installed Contenox-managed
modeld. modeldonPATH.
For each candidate:
modeld version --json
The JSON must parse and include:
{
"version": "v0.32.5",
"backends": ["llama", "openvino"]
}
Compatibility rules:
- Prefer exact version match with the CLI version.
- Reject a candidate that does not report the compiled capability needed by the selected provider.
- For setup UX, an older/newer user-provided
CONTENOX_MODELD_BINcan be reported clearly instead of overwritten automatically.
Download And Verification
Use the standard Go HTTP client with a timeout. The implementation should:
- Send a clear
User-Agent, for examplecontenox/<version> modeld-setup. - Limit redirect behavior to normal HTTPS redirects.
- Stream archive downloads to disk, not memory.
- Write to a temp file and atomically move only after checksum verification.
- Parse
.sha256as the first hex token on the first non-empty line. - Compute SHA-256 over the archive bytes.
- Reject mismatches and delete the temp archive.
Pseudo-code:
sumText, err := getSmallText(ctx, sumURL)
if notFound(err) {
return ErrNoPrebuiltArtifact
}
want := parseSHA256(sumText)
archivePath, err := downloadToTemp(ctx, archiveURL)
if err != nil {
return err
}
got, err := sha256File(archivePath)
if err != nil {
return err
}
if got != want {
return fmt.Errorf("modeld checksum mismatch: got %s want %s", got, want)
}
Install Location
The default install root should be per-user and independent of workspace
.contenox/ directories:
~/.contenox/modeld/<version>/<platform>/
Example:
~/.contenox/modeld/v0.32.5/linux-amd64/
modeld
modeld.bin
lib/llamacpp/...
modeld-libs/...
manifest.json
LICENSES/...
Windows:
%USERPROFILE%\.contenox\modeld\v0.32.5\windows-amd64\
modeld.cmd
modeld.exe
lib\llamacpp\...
modeld-libs\...
After extraction, setup should persist or derive the installed binary path. A simple first step is to set the local process path for the current setup run and print the path:
~/.contenox/modeld/<version>/<platform>/modeld
Follow-up work can decide whether to persist a modeld-bin config key, generate a
shim on PATH, or start a background service.
Safe Extraction
Archive extraction must reject unsafe paths:
- absolute paths
- empty paths
..path traversal- symlinks or hardlinks that escape the destination
- files that would overwrite outside the destination
The extractor should create a fresh staging directory:
~/.contenox/modeld/.staging/<version>-<platform>-<random>/
Then atomically replace or rename into:
~/.contenox/modeld/<version>/<platform>/
On Windows, replacement may fail if a process is using the old binary. In that
case setup should leave the existing install in place and explain that modeld
must be stopped before updating.
Validation
After extraction, run:
<install>/modeld version --json
For Windows:
<install>\modeld.cmd version --json
Validation must assert:
- command exits 0
- JSON parses
versionmatches the CLI version, unless a dev override is activebackendscontainsllamafor providerllamabackendscontainsopenvinofor provideropenvino
If validation fails, setup should not mark the binary as installed. It should keep the error visible and print source-build fallback instructions.
This validation is about compiled package capability only. It is not backend
selection. Live backend selection happens when modeld serve starts.
Setup UX
For local providers, setupProviders labels should stop saying “source build” as
the primary path. They should communicate local modeld:
Llama.cpp GGUF (local modeld)
OpenVINO IR (local modeld)
Happy path output:
Local modeld provider selected: openvino
Checking prebuilt modeld package for v0.32.5 linux-amd64...
Found modeld-v0.32.5-linux-amd64.tar.gz
Downloading 243 MB...
Verified checksum e4fcaf5a...
Installed modeld to ~/.contenox/modeld/v0.32.5/linux-amd64/modeld
Validated modeld version v0.32.5 with compiled backends: llama, openvino
No artifact path:
No prebuilt modeld package is published for v0.32.5 darwin-arm64 yet.
Use the source-build path for now:
...
Network failure path:
Could not check prebuilt modeld packages: request timed out.
Config is saved. You can rerun `contenox setup` or use the source-build path:
...
Checksum failure path:
Downloaded modeld package failed checksum verification.
The package was not installed.
Local Provider Registration
The existing setup flow does not register local llama or openvino backends in
the same way hosted providers are registered. That can remain unchanged for the
artifact detection step if runtime discovery continues to use modeld leases.
However, after installation setup should make the next action clear:
Start modeld:
~/.contenox/modeld/v0.32.5/linux-amd64/modeld serve
Install a local model:
contenox model pull qwen2.5-coder-0.5b-ov
modeld autodetects the live backend at startup. Service management can replace
this manual start command later.
Error Semantics
Suggested internal errors:
var (
ErrNoOfficialVersion = errors.New("modeld setup: CLI version is not an official release")
ErrNoPrebuiltArtifact = errors.New("modeld setup: no prebuilt artifact for version/platform")
ErrChecksumMismatch = errors.New("modeld setup: checksum mismatch")
ErrUnsupportedPlatform = errors.New("modeld setup: unsupported platform")
ErrBackendMissing = errors.New("modeld setup: installed modeld lacks required compiled backend")
)
ErrNoOfficialVersion, ErrNoPrebuiltArtifact, ErrUnsupportedPlatform, and
transient network errors should fall back to source-build instructions.
ErrChecksumMismatch should be treated as a hard failure: do not silently continue
as if the package is unavailable.
Package Boundary
Create an internal package so setup code stays readable:
runtime/internal/modeldinstall/
artifact.go # version/platform/name/url resolution
remote.go # HTTPS .sha256 check and archive download
checksum.go # sha256 parsing and verification
extract_tar.go # safe tar.gz extraction
extract_zip.go # safe zip extraction
install.go # staging, atomic install, validation
probe.go # existing modeld candidates and version --json
runtime/contenoxcli/setup_cmd.go should call this package from the llama and
openvino branches instead of printing source-build instructions immediately.
Tests
Unit tests:
- Artifact name resolution for linux/darwin/windows.
- Official-version detection.
- Base URL override only affects tests/dev.
.sha256parser accepts the current checksum format.- Checksum mismatch is rejected.
- 404 on
.sha256maps toErrNoPrebuiltArtifact. - 403 on
.sha256reports a public download configuration problem. - Safe tar extraction rejects absolute paths and
... - Safe zip extraction rejects absolute paths and
... - Capability validation accepts
llamawhen backends are["llama", "openvino"]. - Capability validation rejects
openvinowhen backends are only["llama"].
Setup tests:
- Local provider setup prints prebuilt-check text before source-build fallback.
- With a fake HTTP server and fake archive, setup installs and validates modeld.
- With no fake artifact, setup keeps the existing source-build guidance.
- Current model choices remain visible after install/fallback.
Manual verification:
curl -fsSL \
https://contenox-modeld-artifacts-573643652148.s3.amazonaws.com/modeld/v0.32.5/modeld-v0.32.5-linux-amd64.tar.gz.sha256
Expected current checksum:
e4fcaf5a6ffba8c2e28d7182914c48aeb767b7c46a3ffa0d60b19267487e0066 modeld-v0.32.5-linux-amd64.tar.gz
Open Questions
- Whether setup should persist a
modeld-binconfig key or derive the path from version/platform every time. - Whether setup should start
modeld serveimmediately after install or only print the normal start command until service management lands. - Whether CLI patch releases may use a compatible older
modeldpackage, or whether exact version matching remains mandatory. - Whether public downloads should move from direct S3 URLs to CloudFront before wide release.