9e8f1bbeed
Dashboard / frontend (push) Failing after 0s
Dashboard / api (push) Failing after 0s
Lint PowerShell / powershell-lint (ubuntu-latest) (push) Failing after 1s
Python Lint / Lint Python with Ruff (push) Failing after 1s
ShellCheck / Lint shell scripts (push) Failing after 1s
Matrix Smoke / linux-smoke (push) Failing after 1s
Matrix Smoke / distro: cachyos (push) Failing after 15s
Matrix Smoke / distro: linux-mint-21.3 (push) Failing after 15s
Matrix Smoke / distro: debian-12 (push) Failing after 5m21s
Matrix Smoke / distro: fedora-41 (push) Failing after 4m56s
Matrix Smoke / distro: ubuntu-24.04 (push) Failing after 2m13s
Matrix Smoke / distro: rocky-9 (push) Failing after 10m39s
Matrix Smoke / distro: manjaro (push) Failing after 12m11s
Matrix Smoke / distro: opensuse-tw (push) Failing after 11m53s
Matrix Smoke / distro: archlinux (push) Failing after 20m3s
Matrix Smoke / distro: ubuntu-22.04 (push) Failing after 13m49s
Validate .env Schema / tier-1-env-validation (push) Successful in 52s
Validate .env Schema / tier-2-env-validation (push) Successful in 44s
Validate .env Schema / tier-3-env-validation (push) Successful in 52s
Validate .env Schema / tier-4-env-validation (push) Successful in 51s
Validate Extensions Catalog / Check catalog is up-to-date (push) Failing after 9m47s
Secret Scan / Scan for secrets (push) Failing after 21m4s
Validate Docker Compose / Validate Docker Compose files (push) Has been cancelled
Python Type Check / Type check with mypy (push) Has been cancelled
Validate .env Schema / tier-0-env-validation (push) Has been cancelled
Test Linux / integration-smoke (push) Has been cancelled
Lint PowerShell / powershell-lint (windows-latest) (push) Has been cancelled
Matrix Smoke / macos-smoke (push) Has been cancelled
160 lines
5.5 KiB
Markdown
160 lines
5.5 KiB
Markdown
# Forkability And Independent Operation
|
|
|
|
ODS is Apache-licensed infrastructure. The upstream repository is a
|
|
coordination point, not a hosted control plane. Operators should be able to
|
|
inspect the rules, run their own node, validate their own hardware, and maintain
|
|
their own fork.
|
|
|
|
This document describes the project posture for downstream maintainers,
|
|
hardware builders, labs, schools, companies, and individuals who want to fork,
|
|
mirror, audit, customize, or run ODS independently.
|
|
|
|
## Goals
|
|
|
|
ODS should be:
|
|
|
|
- forkable without asking upstream for permission;
|
|
- auditable from a cold clone;
|
|
- customizable through documented extension points;
|
|
- reproducible from pinned refs and mirrored artifacts;
|
|
- validated by repeatable public and private test layers;
|
|
- understandable by maintainers who did not write the original installer.
|
|
|
|
Upstream is one implementation and coordination point. It is not meant to be a
|
|
single point of control.
|
|
|
|
## What To Fork
|
|
|
|
Fork the repository when you need a durable downstream edition, such as:
|
|
|
|
- a hardware appliance image with fixed service defaults;
|
|
- a lab or school distribution with curated models and workflows;
|
|
- a company-local appliance with private extensions;
|
|
- a research workstation image with extra tooling;
|
|
- an offline or low-connectivity distribution;
|
|
- a security-reviewed variant with stricter policies.
|
|
|
|
For smaller changes, prefer extensions, model catalogs, presets, and docs over
|
|
patching installer internals. A small extension is easier to keep current than a
|
|
large fork.
|
|
|
|
## Recommended Fork Strategy
|
|
|
|
Pick a source ref deliberately. `main` is the active development channel. Tagged
|
|
releases are the stable default for forks, appliances, and lab images. If you
|
|
need a commit between tags, record the exact commit and its validation receipt.
|
|
See [RELEASE_CHANNELS.md](RELEASE_CHANNELS.md) for the channel policy.
|
|
|
|
Most downstreams should choose one of two patterns:
|
|
|
|
- **Fork-and-pin:** start from a tagged release or audited commit, apply a small
|
|
downstream layer, and update only on a cadence you control.
|
|
- **Fork-and-mirror:** operate your own mirror of the repository and allowed
|
|
artifacts, then merge selected upstream tags or commits after local
|
|
validation.
|
|
|
|
In both cases, keep your customization layer small and explicit.
|
|
|
|
Recommended downstream layout:
|
|
|
|
```text
|
|
extensions/services/<your-service>/
|
|
extensions/library/services/<your-library-service>/
|
|
docs/<your-edition>/
|
|
config/<your-edition>/
|
|
DOWNSTREAM.md
|
|
```
|
|
|
|
Keep a `DOWNSTREAM.md` in your fork that records:
|
|
|
|
- upstream commit or release tag last merged;
|
|
- changed defaults;
|
|
- added, removed, or disabled services;
|
|
- hardware assumptions;
|
|
- model and image pins;
|
|
- private patches to installer, CLI, compose, or dashboard code;
|
|
- validation commands and fleet receipts used after each upstream merge.
|
|
|
|
## What To Avoid Patching First
|
|
|
|
These areas are powerful but high blast radius:
|
|
|
|
- `install-core.sh` and `installers/phases/*`;
|
|
- `ods-cli`;
|
|
- `installers/lib/compose-select.sh`;
|
|
- `scripts/resolve-compose-stack.sh`;
|
|
- `docker-compose.base.yml` and hardware overlays;
|
|
- dashboard-api auth, host-agent, and extension install routes;
|
|
- generated config writers for `.env`, LiteLLM, Hermes, OpenCode, and Perplexica.
|
|
|
|
Patch them when you need to, but do it with the validation map in
|
|
[HIGH_RISK_CHANGE_MAP.md](HIGH_RISK_CHANGE_MAP.md).
|
|
|
|
## Safer Extension Points
|
|
|
|
Prefer these first:
|
|
|
|
- `extensions/services/*` for bundled Docker services;
|
|
- `extensions/library/services/*` for optional dashboard-installable services;
|
|
- `extensions/templates/*` for local starter patterns;
|
|
- `config/model-library.json` for model catalog changes;
|
|
- `config/ports.json` for deliberate port policy changes;
|
|
- `.env.example` for downstream defaults;
|
|
- dashboard theme or branding files for a distinct product surface;
|
|
- docs under `docs/<your-edition>/`.
|
|
|
|
The extension path lets forks add value without diverging from upstream
|
|
installer and lifecycle behavior.
|
|
|
|
## Pinning Upstream
|
|
|
|
For a reproducible fork release:
|
|
|
|
1. Pick an upstream commit or tag.
|
|
2. Record it in `DOWNSTREAM.md`.
|
|
3. Record model, image, driver, and package-manager assumptions.
|
|
4. Run the validation subset appropriate to your changes.
|
|
5. Keep the validation result with the release notes.
|
|
|
|
Do not build a downstream release from an unnamed local checkout. Future you
|
|
should be able to answer exactly what upstream code was used.
|
|
|
|
## Validation Expectations
|
|
|
|
At minimum, a downstream fork should run:
|
|
|
|
```bash
|
|
git diff --check
|
|
python scripts/audit-extensions.py --project-dir .
|
|
python scripts/validate-generated-configs.py
|
|
python scripts/validate-golden-paths.py
|
|
```
|
|
|
|
If you touch installer, compose, lifecycle, dashboard-api, model routing, or
|
|
service manifests, use [HIGH_RISK_CHANGE_MAP.md](HIGH_RISK_CHANGE_MAP.md) to
|
|
choose the stronger validation path.
|
|
|
|
If you publish a hardware image, keep a release receipt with:
|
|
|
|
- upstream ref;
|
|
- downstream ref;
|
|
- install command;
|
|
- target hardware;
|
|
- enabled services;
|
|
- model selected and served;
|
|
- validation gates passed, skipped, or deferred.
|
|
|
|
## Relationship To Upstream
|
|
|
|
Good fork hygiene helps everyone:
|
|
|
|
- keep local-only changes documented;
|
|
- upstream bug fixes that help the shared platform;
|
|
- avoid private patches to generated runtime files when an extension or config
|
|
contract would work;
|
|
- report validation gaps when a fork reveals a new hardware or distro class.
|
|
|
|
ODS should be useful whether you stay close to upstream or maintain a
|
|
private appliance. The project is healthier when independent operators can own
|
|
their stack without needing centralized approval.
|