94 lines
4.5 KiB
Markdown
94 lines
4.5 KiB
Markdown
# 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`.
|