CI and images / lint (push) Successful in 3s
CI and images / extension-version (push) Successful in 2s
CI and images / frontend-build (push) Successful in 19s
extension / lint (push) Successful in 21s
CI and images / backend-lint-and-test (push) Successful in 33s
CI and images / integration (push) Successful in 2m25s
CI and images / sign-extension (push) Successful in 4s
CI and images / build-web (push) Successful in 2m1s
CI and images / smoke-web (push) Successful in 1m2s
CI and images / build-agent (push) Successful in 10m7s
CI and images / promote (push) Skipped
Operator: the agent's build string could not identify the agent. VERSION was a
literal in app.py an author was meant to bump, and nobody did — the September
image printed the same "2026-07-17.1" as the July one, so the one surface
meant to answer "did my pull work?" answered the same either way.
Nothing new was needed. scripts/artifacts.sh has derived a version per
artifact since milestone 313, and build-agent has been computing the agent's
on every run and printing it to the log. The image just never carried it.
Three values, never folded together (rule 149):
FC_VERSION YYYY.MM.DD.HHMM from the COMMIT its shipped files last changed
in — identical on dev and main for the same source, which is
what makes "am I running production's code?" answerable.
FC_CHANNEL a sibling field, never a suffix inside the name.
FC_REVISION the 12-char sha; the same string as the fc.revision LABEL, so
the image and the registry cannot disagree about which commit
this is.
The page SHOWS the version and COMPARES the revision. Those were one value
before, which is how a version acquires a second job and then cannot be
changed without breaking the reload banner. An unstamped local build reads
`unknown` and compares `local` — absent rather than empty, one spelling of
"cannot say".
scripts/artifacts.sh joins the AGENT path set in the same commit, and it had
to: a version has no backstop. A revision that is computed differently stops
matching the published label and forces a rebuild, so it self-corrects; a
version is compared against nothing, so a change to cmd_version alone would
leave the agent publishing the old format with nothing to contradict it. That
is #3202's finding, and the agent was rightly exempt only while it had no
version of its own. tests/test_artifact_paths.py pins it.
Also corrects two build.yml comments claiming agent/ had not changed since
2026-07-17. Both were already false — it changed 2026-09-23 — and one of them
is the stated rationale for the force_build escape hatch. Rewritten without
dates: how long an artifact has been quiet is a `git log` question, and its
answer in a comment is wrong the next time anyone commits (lesson #4383).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
80 lines
3.5 KiB
Python
80 lines
3.5 KiB
Python
"""What this agent build IS — stamped at image build time, not configurable.
|
|
|
|
The mirror of `backend/app/build_info.py`, for the same reasons and with the
|
|
same posture. Kept as its own module rather than as constants in `app.py`
|
|
because it is stdlib-only and therefore importable by the test suite, which
|
|
cannot import `app` (torch, transformers and ultralytics are not in the CI
|
|
image — see build.yml's "Agent syntax check").
|
|
|
|
## Why this replaced a hand-written string
|
|
|
|
`app.VERSION` used to be a literal an author was asked to bump, carrying a
|
|
version AND a changelog in one string:
|
|
|
|
VERSION = "2026-07-17.1 · idle model-unload: after ~5 min idle ..."
|
|
|
|
Nobody bumped it. The September image printed the identical string to the July
|
|
one, so the one surface that was supposed to answer *"did my pull work?"*
|
|
answered *"2026-07-17.1"* either way. An artifact that cannot identify itself
|
|
is worse than one that says nothing, because the stale value reads as an
|
|
answer.
|
|
|
|
The values are now derived by `scripts/artifacts.sh` from the commit its
|
|
shipped files last changed in — the same derivation the web image has used
|
|
since milestone 313, and the same one the reuse check already ran for the
|
|
agent and discarded.
|
|
|
|
## Three values, never folded together (rule 149)
|
|
|
|
* `FC_VERSION` — the NAME, `YYYY.MM.DD.HHMM` UTC, derived from COMMIT time.
|
|
For people to read and quote. Identical on `dev` and `main` for the same
|
|
source, which is the property that makes "am I running the same code as
|
|
production?" answerable at a glance.
|
|
* `FC_CHANNEL` — a SIBLING field, never a suffix inside the name.
|
|
* `FC_REVISION` — the 12-char commit sha, the artifact's IDENTITY. This is
|
|
what the reuse check already keys on as the `fc.revision` image label.
|
|
|
|
**Absent rather than empty when unknown.** A locally built image has no
|
|
stamp, and neither does any image predating this module. One spelling of
|
|
"cannot say" instead of two.
|
|
"""
|
|
|
|
import os
|
|
|
|
FC_VERSION = os.environ.get("FC_VERSION", "").strip()
|
|
FC_CHANNEL = os.environ.get("FC_CHANNEL", "").strip()
|
|
FC_REVISION = os.environ.get("FC_REVISION", "").strip()
|
|
|
|
|
|
def display_version() -> str:
|
|
"""The build, as a line for a human: `2026.09.24.1052 (dev)`.
|
|
|
|
`unknown` rather than a blank when unstamped — an empty slot in the meta
|
|
line reads as "no version", which is a different and false claim from "this
|
|
build does not carry one".
|
|
"""
|
|
if not FC_VERSION:
|
|
return "unknown"
|
|
return f"{FC_VERSION} ({FC_CHANNEL})" if FC_CHANNEL else FC_VERSION
|
|
|
|
|
|
def build_id() -> str:
|
|
"""The token the control page compares against `/status` to notice it is
|
|
showing a CACHED page from a previous build.
|
|
|
|
Deliberately NOT `display_version()`. That is the value for reading; this
|
|
is the value for deciding, and folding the two is what rule 149 is about.
|
|
The revision is the better discriminator of the two — two builds of the
|
|
same commit ARE the same agent and should not prompt a reload, and two
|
|
different commits always differ here even when they land in the same
|
|
minute and derive one version name.
|
|
|
|
A locally built image falls through to a constant, so the reload banner
|
|
cannot fire for it. That is honest rather than a gap: nothing in an
|
|
unstamped image knows what source it was built from, and a per-process
|
|
nonce would make every ordinary container RESTART claim a new version had
|
|
arrived — a false positive on the exact surface the banner exists to keep
|
|
trustworthy.
|
|
"""
|
|
return FC_REVISION or FC_VERSION or "local"
|