2026-05-10: Versioning Env Badge Fix
Problem
Section titled “Problem”Three surfaces, wrong labels:
| Surface | Currently shows | Should show |
|---|---|---|
docker:dev → http://localhost:8001/docs/ | v1.0.0 PROD | v1.0.0 DEV |
docker:prod | v1.0.0 PROD | v1.0.0 PROD ✅ |
| https://strata.ducatillon.net/docs | v0.0.0-dev+062ec83 DEV | v1.0.0 (no badge) |
Display rules (finalized):
- DEV: full git describe + badge →
v1.0.0-3-gabc1234 — DEV - PROD: clean tag only, no badge →
v1.0.0
Root Cause Analysis
Section titled “Root Cause Analysis”docker:dev shows PROD
Section titled “docker:dev shows PROD”docker:reset / docker:nuke call gen-version.mjs all. On a clean tag (v1.0.0), git describe → 1.0.0 → isClean=true → env=production. That version.ts is COPY-ed into the docs Docker image. docker:dev = docker-compose up (no rebuild) → reuses image → shows PROD.
strata.ducatillon.net shows 0.0.0-dev DEV
Section titled “strata.ducatillon.net shows 0.0.0-dev DEV”Cloudflare Pages does a shallow clone (depth=1). git describe finds no tags → falls back to 0.0.0-dev+sha. Not a clean semver → isClean=false → env=development. Both version number and env label are wrong.
Root fix — package.json fallback (zero dashboard config)
Section titled “Root fix — package.json fallback (zero dashboard config)”When git returns 0.0.0-dev (no tags / shallow clone), read version from root package.json. Since release.mjs always bumps package.json in sync with git tags, it always holds the correct version string (e.g. 1.0.0). A clean semver → isClean=true → env=production is derived automatically. No STRATA_ENV env var needed for Cloudflare Pages.
AGENTS.md Compliance Checklist
Section titled “AGENTS.md Compliance Checklist”| # | Convention | Check |
|---|---|---|
| 1 | Documentation | ✅ Update versioning.md with STRATA_ENV + fallback |
| 2 | All 4 test gates | ✅ Script/config changes only — run all gates for regression check |
| 3 | Self-review | ✅ See below |
| 4 | Endpoint coverage | n/a |
| 5 | Bug-to-Test | n/a — build-time display |
| 6 | Seed isolation | n/a |
| 7 | Transaction invariants | n/a |
| 8 | Plan history | ✅ This file |
| 9 | Infra test gate | ✅ Verify node scripts/version.mjs --json in all scenarios |
| 10 | Environment compat | ✅ Plain env var; synchronous fs.readFileSync |
| 11 | Do-no-harm | ✅ Verify docker:prod still shows v1.0.0 (no badge) |
| 12 | Execution summary | ✅ Append after done |
| 13 | Doc Grep Rule | ✅ No paths renamed |
Self-review
Section titled “Self-review”VERSION_OVERRIDEpath inversion.mjsuntouched — docker:prod still works ✅STRATA_ENVonly overridesenvfield; version string always comes from git/package.json ✅- package.json fallback triggers only when version starts with
0.0.0-dev✅ - Cloudflare Pages:
0.0.0-dev→ fallback →1.0.0→isClean=true→env=production→ no badge shown ✅ - No circular deps; no runtime code changes
Implementation
Section titled “Implementation”1. scripts/version.mjs — STRATA_ENV override + package.json fallback
Section titled “1. scripts/version.mjs — STRATA_ENV override + package.json fallback”Add readFileSync import and readPkgVersion() helper. Two additive changes:
STRATA_ENVoverride: when set todevelopment/production, forceenvfieldpackage.jsonfallback: when version starts with0.0.0-dev, replace withpackage.jsonversion
2. root package.json — docker:reset + docker:nuke
Section titled “2. root package.json — docker:reset + docker:nuke”Prepend STRATA_ENV=development to gen-version.mjs all call in both scripts. docker:prod unchanged.
3. docs/src/components/DocsSiteTitle.astro
Section titled “3. docs/src/components/DocsSiteTitle.astro”- DEV: full
VERSION.version+— DEVbadge - PROD:
VERSION.version.split('-')[0]only, no badge - Remove unused
.env-badge.prodCSS rule
4. docs/src/content/docs/versioning.md
Section titled “4. docs/src/content/docs/versioning.md”Document STRATA_ENV and package.json fallback behavior.
Execution Summary
Section titled “Execution Summary”Commit: b7ea452
Actual changes
Section titled “Actual changes”| File | Change |
|---|---|
scripts/version.mjs | Added readPkgVersion() helper + STRATA_ENV override + package.json fallback |
package.json | docker:reset + docker:nuke prefixed with STRATA_ENV=development |
docs/src/components/DocsSiteTitle.astro | DEV: full version + — DEV badge; PROD: clean tag only, no badge; removed .env-badge.prod CSS |
docs/src/content/docs/versioning.md | Added STRATA_ENV override + package.json fallback docs; updated surface table |
docs/src/content/docs/plans/2026-05-versioning-env-badge-fix.md | Plan doc (this file) |
Deviations from plan
Section titled “Deviations from plan”None. Implementation matched the plan exactly.
Test results
Section titled “Test results”| Gate | Result |
|---|---|
| Backend unit | ✅ 315 passed (30 suites) |
| Backend e2e | ✅ 70 passed (8 suites) |
| Frontend unit | ✅ 394 passed (63 files) |
| Frontend e2e | ⏭ skipped (no UI code changed) |
| Docs build | ✅ 56 pages built successfully |
Key discoveries
Section titled “Key discoveries”-
The
package.jsonfallback alone fixes Cloudflare Pages — a clean semver frompackage.json→isClean=true→env=productionis derived automatically. NoSTRATA_ENVdashboard variable needed. -
docker:dev(no rebuild) will show version frozen from lastdocker:reset/docker:nuke— this is acceptable behaviour, documented in plan. -
The old PROD badge in
DocsSiteTitle.astrowas redundant by design — removed per user request. -
npm run docker:reset→ http://localhost:8001/docs/ →v1.0.0 — DEV(or full sha if past tag) -
npm run docker:prod→v1.0.0(no badge) -
node scripts/version.mjs --json(no tags, shallow simulation) →version=1.0.0, env=production -
STRATA_ENV=development node scripts/version.mjs --json→env=development -
strata.ducatillon.net (after next CF Pages deploy) →
v1.0.0(no badge) -
All backend unit + e2e tests pass
-
All frontend unit + e2e tests pass