diff --git a/scripts/artifacts.sh b/scripts/artifacts.sh index fcce132..6a3df2f 100755 --- a/scripts/artifacts.sh +++ b/scripts/artifacts.sh @@ -49,15 +49,22 @@ ROOT=$(git rev-parse --show-toplevel) # frontend/public/extension/ before the docker build), so an extension change # changes the web image. The extension's packaged set is appended in cmd_paths # rather than restated — one definition, per #2397. -WEB_PATHS='Dockerfile requirements.txt backend alembic alembic.ini entrypoint.sh frontend :(exclude)frontend/test :(exclude)frontend/test/**' +WEB_PATHS='Dockerfile requirements.txt requirements-ml.txt backend alembic alembic.ini entrypoint.sh frontend :(exclude)frontend/test :(exclude)frontend/test/**' -# ml (Dockerfile, context `.`) — no frontend, no extension. Note it copies -# BOTH requirements-ml.txt and requirements.txt. -# Dockerfile, not Dockerfile.ml: the images merged at milestone 422 step 6 -# and Dockerfile.ml is gone. A path set naming a deleted file silently -# stops contributing to the derived revision, which is what the reuse -# check and the version string both read (#3202's shape). -ML_PATHS='Dockerfile requirements-ml.txt requirements.txt backend alembic alembic.ini entrypoint.sh' +# ml — THE SAME IMAGE as web since milestone 422 step 6, built from the same +# Dockerfile with the same context and published under a second name only +# because the operator's Swarm stack still references it. +# +# So it is the same path set, by assignment rather than by a copy that would +# drift. This was two lists describing one image for about an hour, and the +# artifact-paths guard caught it immediately: the merged Dockerfile carries +# the frontend-builder stage, so the ml image copies `frontend/package.json`, +# and the old ml list did not cover it — its version would not have moved when +# the frontend changed, and a pinned build would serve stale bytes (#3202). +# +# `requirements-ml.txt` is in WEB_PATHS for the mirror-image reason: the web +# image now installs the ML requirements, so changing them changes it. +ML_PATHS="$WEB_PATHS" # agent (agent/Dockerfile, context `agent`) — copies requirements.txt and # fc_agent only. agent/README.md, agent/docker-compose.yml and agent/ruff.toml @@ -108,7 +115,9 @@ ext_paths() { cmd_paths() { case "$1" in web) echo "$WEB_PATHS $DERIVER $(ext_paths)" ;; - ml) echo "$ML_PATHS" ;; + # Identical to web, deliberately: it IS web's image. That includes the + # deriver and the bundled extension — the XPI is in these bytes too. + ml) echo "$ML_PATHS $DERIVER $(ext_paths)" ;; agent) echo "$AGENT_PATHS" ;; extension) ext_paths ;; *) usage ;;