Initial public ModelForge release

This commit is contained in:
Jens
2026-09-01 21:30:16 +02:00
commit 7082ab955a
490 changed files with 104252 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
# ITWorx ModelForge v1.2.1
A packaging and provenance patch over v1.2.0. No new capability, no UX change, no API contract
change, no schema change and no runtime-behaviour change. Schema stays `20260828_0022` and no
migration runs.
v1.2.0 is functionally healthy and remains historical truth, including the fact that its production
acceptance found two defects after publication. v1.2.1 fixes them forward rather than reissuing
v1.2.0.
Both defects share a shape worth naming: **the source was correct and the artifact was wrong.** No
amount of unit testing, linting or label inspection could see either, because both only exist once
an image has been built.
## Fixed
### The published console could not reach its own API
Vite inlines `VITE_API_BASE_URL` into the bundle at build time. `scripts/release_build.py` never
passed it, so every release image since v1.1.0 compiled the Dockerfile's development default —
`http://localhost:8000` — into an immutable artifact. The nginx CSP is derived from the same build
argument, so `connect-src` hardcoded the same wrong origin: the console asked the wrong address, and
its own policy forbade the right one.
In production this presented as a console that loaded perfectly and displayed nothing, with
CORS errors visible only in a browser devtools console.
A release build now takes the origin as an explicit input and refuses to package without it:
```bash
python scripts/release_build.py --output dist \
--public-api-origin https://modelforge.example.com
# or: MODELFORGE_PUBLIC_API_ORIGIN=https://modelforge.example.com
```
The value must be an absolute `http(s)` origin with no path, query or fragment. A missing or
malformed origin fails the build before any image is built.
### The Node Agent's identity could drift from its tag
`docker-compose.node-agent.yml` declared a `build:` block with no `args:`. A Compose-built agent
therefore fell back to version `0.0.0` with empty `revision` and `created` labels, while still being
tagged from whatever `MODELFORGE_VERSION` happened to be. Production ran an image tagged `1.1.1`
whose contents reported `1.2.0` and whose OCI provenance was blank.
The projection now passes `MODELFORGE_VERSION`, `MODELFORGE_COMMIT` and `MODELFORGE_BUILT_AT`,
exactly as the API and console projections already did. The Node Agent's certified behaviour is
unchanged: same Debian/glibc base, NVML preflight, fail-closed NVIDIA validation, non-root runtime,
`cap_drop: ALL`, `no-new-privileges`, protocol 1 and persisted-identity semantics.
## Added
`scripts/release_image_acceptance.py` reads the **built** console image rather than the source that
produced it: the origins compiled into its JavaScript, the `connect-src` in its rendered nginx
policy, and its OCI labels. The release build runs it before packaging and refuses to publish an
image that cannot reach the API it was built for.
It was validated against the exact image that broke production — `modelforge-web:1.1.0` fails three
of its checks — and against the corrected image, which passes all thirteen.
Regression coverage was added for both defects, including proof that each new test fails when its
fix is reverted.
## Compatibility
| Contract | v1.2.1 |
| --- | --- |
| Version | `1.2.1` |
| Channel | `stable` |
| Database schema | `20260828_0022` — unchanged, no migration |
| Agent protocol | `1`, accepts `1` |
| Minimum direct upgrade | `v1.0.0` |
| Minimum PostgreSQL major | `16` |
## Upgrade
Application-only from any v1.2.x. Replace the API, console and Node Agent images with the published
v1.2.1 artifacts. Schema is `20260828_0022` before and after.
Operators upgrading from v1.1.0 or the original v1.2.0 images should note that the console image is
the one that actually changes behaviour here: the previous images cannot reach a non-localhost API,
regardless of how the deployment is configured, because the origin is compiled in.
## Known limitations
- The console's API origin remains a **build-time** property. A single published console image is
therefore bound to one API origin; deployments behind a different origin need an image built for
it. Making this a runtime property is a larger change than a patch release should carry.
- Node Agent HIGH/CRITICAL findings from its digest-pinned Debian base are unchanged from v1.1.1 and
v1.2.0, and none has an upstream fix available.
- Unmanaged GPU workloads can legitimately cause `EXTERNAL_GPU_PRESSURE`; ModelForge observes but
never reclaims them.
- Point-in-time database recovery remains `NOT_SUPPORTED`.