Files
home-network-k3s-impl/infra/agent/versions.env
T
jakman85andClaude Opus 5.5 e539109830 feat(images): build, verify and publish the three images in CI; Renovate carries the digests
Operator rule 2026-10-29: image creation, hosting and lifecycle belong to CI/CD, never to a
workstation build/push. Nothing had ever been pushed to the Gitea registry.

- .gitea/workflows/images.yaml + scripts/images.sh: PRs build+verify (no credential); main
  builds, verifies and pushes toolbox, agent-runner (FROM toolbox) and conformance-runner as
  sha-<commit> + main, reading the digest back from the registry. Only changed images build.
- Each image's own build-image.sh does the build and in-image verification, now engine-neutral
  (DinD: no podman-only calls, probe over stdin not a bind mount). New toolbox build-image.sh.
- Digest references carry `# renovate-digest:` markers; renovate.json5 gains a custom.regex
  manager for them. The worker Job template is deliberately untracked (it would loop).
- renovate.yaml pins renovate-version 44.167.0: the action's default (39.264.0) rejects the
  current config's managerFilePatterns, so every run would have died at CONFIG_VALIDATION.
- Push credential: REGISTRY_PUSH_TOKEN secret; the Actions token has no package scope in
  Gitea 1.24.3 (container.go Authenticate). Retention: infra/gitea/registry-retention.sh.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 23:59:55 -05:00

54 lines
3.4 KiB
Bash

# infra/agent/versions.env — pins for the `agent-runner` image (the PM agent service).
#
# WHAT THIS FILE DOES *NOT* PIN: the platform toolchain. The agent-runner is built FROM
# the pinned dev toolbox (infra/devcontainer/), which already pins fedora, python3,
# git, sops, age, flux, kubectl, kyverno, chainsaw, promtool, yamllint and
# check-jsonschema in ONE place. A worker agent runs `./ci/gate.sh` before it pushes, so
# it needs exactly that toolchain — and CLAUDE.md §3 is explicit that only the pinned
# toolbox result counts. Re-pinning those versions here would create a second source of
# truth and, the first time the two drifted, the worker's "green" would stop meaning the
# gate's green. So this file pins ONLY what the toolbox does not carry.
# The toolbox image the runner is layered on: the PUBLISHED toolbox, by digest. CI builds and
# publishes it (.gitea/workflows/images.yaml) and Renovate moves this line onto each new digest
# of its `main` tag via the marker below, in a pull request — nobody edits it by hand.
#
# ALL-ZERO UNTIL THE FIRST PUBLISH. The first run of the image pipeline on main sees this
# placeholder, builds and publishes the toolbox first, and builds agent-runner FROM that fresh
# digest. For a LOCAL build on a local toolbox, override it:
# infra/devcontainer/dev.sh build && AGENT_BASE_IMAGE=home-k3s-dev:local infra/agent/build-image.sh
# renovate-digest: image=gitea.home.keithjackson.dev/home-network/toolbox tag=main
AGENT_BASE_IMAGE=gitea.home.keithjackson.dev/home-network/toolbox@sha256:0000000000000000000000000000000000000000000000000000000000000000
# Node.js — the runtime for the Claude Code CLI, installed from the Fedora base's module
# stream. A major version, not a patch: the CLI supports the active LTS line and the
# distro package is the reproducible way to get it inside a pinned base.
NODEJS_MAJOR=22
# Claude Code CLI (npm `@anthropic-ai/claude-code`), EXACT version.
#
# WHY 2.1.285 AND NOT `latest`: `latest` makes the image non-reproducible, and the
# autoupdater is disabled in the runtime anyway (see the Containerfile), so a floating
# tag would only move under us at build time. 2.1.285 is the version the registry
# publishes under the `stable` dist-tag (measured 2026-10-05:
# `curl -s https://registry.npmjs.org/@anthropic-ai/claude-code | jq .'dist-tags'`
# -> {"stable":"2.1.285","latest":"2.1.290","next":"2.1.290"}).
#
# FLOOR, NOT PREFERENCE: pm-dispatch and pm-worker both pass
# `--permission-prompts none`, which requires >= 2.1.259. A downgrade below that floor
# does not fail at build — it fails at 3am with a worker waiting forever for a
# permission answer nobody can give. build-image.sh asserts the floor.
CLAUDE_CODE_VERSION=2.1.285
CLAUDE_CODE_MIN_VERSION=2.1.259
# The model the PM persona and the worker agents run on. `claude-opus-5` is the current
# most-capable general model; the worker does real repository work against a gate, so this
# is deliberately not a cheaper tier. Overridable per-deployment via the ConfigMap
# (PM_MODEL / PM_WORKER_MODEL) without rebuilding the image.
AGENT_MODEL=claude-opus-5
# Image coordinates. The repository path is NOT a preference: the admission policy
# platform/kyverno/admission/pm-agent-job-shape.yaml admits a worker Job only when its
# image is `${AGENT_IMAGE_REPO}@sha256:<digest>`. A different path is a DENIED Job.
AGENT_IMAGE_REPO=gitea.home.keithjackson.dev/home-network/agent-runner