Skip to main content

Agent Versioning

Every agent that registers with the platform — UI Test, Playwright, Scanner, Artillery, ZAP — reports a version string when it registers and on each heartbeat. The platform displays that string on the Admin → Health page (/admin/health) so operators can confirm which agent build is actually running in cluster.

Where to see versions

https://app.proofarc.ai/admin/health — the Version column on each row in the agents table shows whatever the agent reported on its most recent registration.

How the version string is built

Every registered agent reports a string in one of two shapes:

FormWhen you see it
1.1.0Local run (no git SHA env injected)
1.1.0+a1b2c3dCI-built image (Dockerfile receives the short SHA)

The suffix after the + is the first 7 characters of the git commit SHA the image was built from. This is the durable answer to "which commit is deployed?" — the tag (latest / v3.10.x) tells you which release line the image belongs to; the SHA tells you the exact source it was built from.

Two things vary independently:

  • Base version — bumped manually in the agent's source when you intend to signal a meaningful change (compat-breaking change, major feature, etc.). Lives in:
    • ui-test-agent/build.gradle (and application.yml for runtime override)
    • scanner-agent/config.yaml
    • playwright-agent/agent.py (the AGENT_BASE_VERSION constant)
  • Build SHA suffix — set automatically by the docker-publish.yml workflow as --build-arg GIT_COMMIT_SHORT=$(git rev-parse --short=7 HEAD). Each Dockerfile turns that ARG into a GIT_COMMIT_SHORT env var, which the agent reads at startup.

Per-agent source of truth

AgentImageCode reading the versionWhere to bump base version
UI Test (Java)ghcr.io/proofarc/seleniumBackendApiClient.buildVersionString()ui-test-agent/build.gradle and ui-test-agent/src/main/resources/application.yml
Scanner (Python)ghcr.io/proofarc/scannercore/config.Config.agent_version propertyscanner-agent/config.yaml
Artillery (Python)ghcr.io/proofarc/artillerysame as Scanner — inherited via FROM ${BASE_IMAGE}same as Scanner (shares the codebase)
ZAP (Python)ghcr.io/proofarc/zapsame as Scanner — inherited via FROM ${BASE_IMAGE}same as Scanner (shares the codebase)
Playwright (Python)ghcr.io/proofarc/playwrightPlaywrightAgent._version_string()playwright-agent/agent.py (AGENT_BASE_VERSION constant)

The Scanner / Artillery / ZAP images share the same Python codebase — only their installed tools differ — so they report the same version. That's by design: same code, same version. The agent's identity (scanner vs. artillery vs. zap) shows up separately on the health page via the agent_id, hostname, and capabilities columns.

When to bump the base version

The build SHA suffix changes on every build automatically, so you don't need to bump the base version to make a new deploy distinguishable. Bump the base version only when the change is meaningful enough that an operator reading "Version 1.2.0+abc1234" should know something about the codebase beyond just "newer commit":

  • Bump minor (1.1.01.2.0) for a feature addition or behaviour change visible to test authors (a new YAML action, a new capability, a wire-protocol field).
  • Bump major (1.x.x2.0.0) for a breaking change to YAML schema, the registration protocol, or job payload shape.
  • Bump patch (1.1.01.1.1) for a notable bug fix you want to be greppable from the health page (e.g. the cross-engine timing fix in the Playwright agent).
  • Don't bump for routine commits, refactors, or doc changes — the SHA suffix already differentiates the build.

Cluster check — what version is each agent reporting right now?

PG_PASS=$(kubectl -n proofarc get secret proofarc-secrets -o jsonpath='{.data.postgres-password}' | base64 -d)
kubectl -n proofarc exec proofarc-postgres-<pod> -- env PGPASSWORD="$PG_PASS" \
psql -U secadmin -d security_agent -c "
SELECT agent_id, agent_version, status, hostname, last_seen_at
FROM agent_registration
ORDER BY agent_id;
"

…or just open /admin/health and read the Version column.

What if every agent shows 1.0.0?

That was the symptom that motivated this work (May 2026). Every agent was hardcoded to report 1.0.0 with no per-build differentiation, so the health page was useless for confirming what was actually deployed.

The fix that landed:

  1. Each agent's base version was bumped to a distinct number reflecting recent work (UI Test → 1.1.0 for the Spring Boot 3.5 migration; Playwright → 1.1.0 for cross-engine fixes; Scanner → 1.0.1).
  2. Each agent now appends the build's git short SHA to its base version at startup, read from a GIT_COMMIT_SHORT env var injected by the Dockerfile.
  3. The docker-publish.yml workflow passes GIT_COMMIT_SHORT=$(git rev-parse --short=7 HEAD) as a build arg to the Scanner, UI Test, and Playwright image builds.

If you ever see every agent reporting 1.0.0 again, the most likely cause is the GIT_COMMIT_SHORT build-arg wiring broke — check that the docker-publish.yml job for that agent still has the build-args: GIT_COMMIT_SHORT=… block. The Dockerfile defaults the ARG to empty, so a missing build-arg silently falls back to the bare base version with no suffix.

Agents that aren't on this page

The readiness-agent and orchestrator-agent exist in the repo and have their own Docker images, but they do not register via /api/agent/register — they're internal services, not job-execution agents. They don't appear on the /admin/health agents table. If you need to check what version of those is deployed, look at the image tag on the deployment:

kubectl -n proofarc get deploy proofarc-orchestrator -o jsonpath='{.spec.template.spec.containers[0].image}'
kubectl -n proofarc get deploy proofarc-readiness -o jsonpath='{.spec.template.spec.containers[0].image}'