feat(settings): the instance reports which build it is (318 step 6)
CI / lint (push) Successful in 4s
Build images / sign-extension (push) Successful in 4s
CI / extension-version (push) Successful in 4s
Build images / build-agent (push) Successful in 4s
CI / frontend-build (push) Successful in 21s
extension / lint (push) Successful in 25s
CI / backend-lint-and-test (push) Successful in 32s
Build images / build-ml (push) Successful in 2m50s
Build images / build-web (push) Successful in 2m49s
CI / integration (push) Successful in 3m52s

A dim line at the foot of Settings: `FabledCurator 2026.08.28.1249 · dev`.

This is no longer a convenience. Milestone 318 stopped publishing version
image tags, so an instance's own report is the ONLY answer to "which build is
this?" — there is no registry name left to check it against. Note #3127 §5
says it directly: a wrong answer here has no second source to contradict it.

Three states, kept distinct because collapsing any two of them lies:

  not asked yet         render nothing
  asked, no version     render "unknown"
  asked, has a version  render it

A blank footer reads as "no version", which is a different claim from "I
cannot say". And a failed health call deliberately does NOT mark the build
loaded — a network blip says nothing about the image, and presenting it as
"unknown" would look like a defective build.

Carried on /api/health rather than a new route: it answers at the same cost
(two module constants, no I/O) and TopNav already fetches it app-wide, so a
separate endpoint would mean a second request for two strings.

Both fields are OMITTED when unset rather than sent empty. Absence already
means "cannot say" — an image predating the field says exactly that by not
having the key — so a second spelling would make every reader special-case
it. The pre-existing test asserting the body is EXACTLY {"status": "ok"} is
what keeps a well-meaning `or ""` default from creeping in.

FC_CHANNEL now has one definition. It was read from the environment in
extension.py and would have been read again here; the new build_info module
holds both, and extension.py binds it as a module-level name so existing
tests monkeypatch it exactly as before. Separate from config.py on purpose:
those are operator settings meant to be changed, these describe the artifact.

Channel sits beside the version, never inside it (rule 149), asserted from
both ends. A `-dev` suffix would read as a 0 segment to the extension's
parseInt comparator and make every dev build compare equal — #2993 exactly.

Not hidden, per the operator and §7: the JS bundle and asset hashes
fingerprint the build anyway, and "I'm on 2026.08.28.1249" is the single most
useful line in a bug report.
This commit is contained in:
2026-08-28 18:08:31 -04:00
parent 5771fd5770
commit bce894ba24
9 changed files with 268 additions and 14 deletions
+25 -1
View File
@@ -5,6 +5,18 @@ import { useApi } from '../composables/useApi.js'
export const useSystemStore = defineStore('system', () => {
const api = useApi()
const healthy = ref(null) // null=unknown, true=ok, false=down
// What the instance says it is. Since milestone 318 stopped publishing
// version image tags, this is the only answer to "which build is this?" —
// there is no registry name left to check it against.
//
// Three states, and collapsing any two of them would lie:
// buildLoaded=false we have not asked yet -> render nothing
// buildLoaded=true, version='' the build cannot say -> render "unknown"
// buildLoaded=true, version=x this build is x
// A blank footer would read as "no version", which is a different claim.
const buildVersion = ref('')
const buildChannel = ref('')
const buildLoaded = ref(false)
const stats = ref(null)
const statsLoading = ref(false)
@@ -12,8 +24,17 @@ export const useSystemStore = defineStore('system', () => {
try {
const body = await api.get('/api/health')
healthy.value = body.status === 'ok'
// Absent means "cannot say" — the server omits these rather than
// sending empty strings, so `?? ''` preserves that rather than
// inventing a value for it.
buildVersion.value = body.version ?? ''
buildChannel.value = body.channel ?? ''
buildLoaded.value = true
} catch {
healthy.value = false
// Deliberately NOT setting buildLoaded: a failed health call tells us
// nothing about the build, and claiming "unknown" would present a
// network blip as a defective image.
}
}
@@ -26,5 +47,8 @@ export const useSystemStore = defineStore('system', () => {
}
}
return { healthy, stats, statsLoading, refreshHealth, refreshStats }
return {
healthy, stats, statsLoading, refreshHealth, refreshStats,
buildVersion, buildChannel, buildLoaded,
}
})