Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions voltage/images/buzz-agent/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
# Build from the repository root so the image packages the checked-out Buzz
# source; Dockerfile.dockerignore next to this file selects the context.
FROM rust:1.95-alpine3.22@sha256:064dfc925d68d1a63f4fd2871bd7dc6e6ea56692989a487185855d62885d90aa AS source
RUN apk add --no-cache bash build-base cmake git musl-dev openssl-dev \

Check warning on line 5 in voltage/images/buzz-agent/Dockerfile

View workflow job for this annotation

GitHub Actions / Lint Dockerfiles

Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
openssl-libs-static perl pkgconf protoc python3 procps
WORKDIR /build
ENV CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=2
COPY . .
FROM source AS package-checks
RUN apk add --no-cache tini \

Check warning on line 11 in voltage/images/buzz-agent/Dockerfile

View workflow job for this annotation

GitHub Actions / Lint Dockerfiles

Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
&& tini -s -- cargo test --locked -p sprig -p buzz-acp -p buzz-agent -p buzz-dev-mcp -- --test-threads=1

FROM source AS builder
Expand All @@ -16,10 +16,20 @@
&& strip target/sprig/sprig

FROM rust:1.97.1-slim-trixie@sha256:8e8cf8f7fd54a2d23d5a743b3a03f56e26b6c774276c33fa0595111704ebb15c AS development-rust
# cargo-llvm-cov (the engineering-skills rust-crap-score skill) reads coverage
# with the toolchain's LLVM tools.
RUN rustup component add llvm-tools-preview

# knots 1.16.0, the complexity analyzer rust-crap-score requires. Its releases
# have no linux arm64 binary, so build it from crates.io with its published
# Cargo.lock; cargo checks the crate against the registry checksum.
FROM development-rust AS crap-tools
RUN cargo install --locked --version 1.16.0 knots --root /opt/crap-tools \
&& strip /opt/crap-tools/bin/knots

FROM node:22-trixie-slim@sha256:154ba2f4d6fec323d28e4f4bb86bba4677f1223391a1979cf521304e03a98dfa
LABEL maintainer="Voltage <hello@voltage.cloud>"
RUN apt-get update \

Check warning on line 32 in voltage/images/buzz-agent/Dockerfile

View workflow job for this annotation

GitHub Actions / Lint Dockerfiles

Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
&& apt-get install -y --no-install-recommends bash ca-certificates curl git gh gnupg openssh-client socat tini \
build-essential clang cmake pkg-config libssl-dev protobuf-compiler \
python3 python3-venv python3-pip golang-go postgresql-client sqlite3 \
Expand All @@ -33,21 +43,23 @@
# Release assets are public and pinned by checksum per architecture;
# credentials enter only at runtime.
ARG TARGETARCH
RUN case "$TARGETARCH" in \

Check warning on line 46 in voltage/images/buzz-agent/Dockerfile

View workflow job for this annotation

GitHub Actions / Lint Dockerfiles

Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
amd64) via=x86_64 gitleaks=x64 sccache=x86_64 \
amd64) via=x86_64 gitleaks=x64 sccache=x86_64 llvm_cov=x86_64 \
kubectl_sha=874d5e72dbb819f43cff16bcd1e4f8bac5b7f2361fe1e55049b0a6c676fb0cbf \
via_sha=9e5a7f9384cacda29061d814e9397e7b6d90a72ee4663775362978ac9b65d8b7 \
op_sha=198b05dcf9a0972778ce5a4e262c459979b0c837257b5da65e2fba6187734226 \
gitleaks_sha=551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb \
depot_sha=7a469c767bd3b7e67b3174f91af9c6315fea0ced4871948ee9d41a006fb2347e \
sccache_sha=45f1447fbe231e3037bde351ef70677dd212216c8d62ae7ca409fecc4d6acc89 ;; \
arm64) via=arm64 gitleaks=arm64 sccache=aarch64 \
sccache_sha=45f1447fbe231e3037bde351ef70677dd212216c8d62ae7ca409fecc4d6acc89 \
llvm_cov_sha=e9fc23dbbdc502ee9267544f8c6e8e162c6d7df8fb2e3f62d8289a4c0bd240ce ;; \
arm64) via=arm64 gitleaks=arm64 sccache=aarch64 llvm_cov=aarch64 \
kubectl_sha=cc749967b62f4422260bc9c0aa7a7c55f45175ae38cb8d95767b5d2b7e04c1fd \
via_sha=26cc174802c875424b9846a398d4b2d890b911506f7c574dee96859620caa535 \
op_sha=7b5c361a23e738a3969cf676960f4843af4aa9aa68dbec23d18a9134da428ba3 \
gitleaks_sha=e4a487ee7ccd7d3a7f7ec08657610aa3606637dab924210b3aee62570fb4b080 \
depot_sha=042d846f544919e6b5bcb328387b1963af4e298bfa441a41f36bc46663202f2b \
sccache_sha=2b3284d5da3b46a47dc4229e75bb7b88ac4aa99c8d754fb7d2f84997e5a4354a ;; \
sccache_sha=2b3284d5da3b46a47dc4229e75bb7b88ac4aa99c8d754fb7d2f84997e5a4354a \
llvm_cov_sha=bc14a4551e633b12ec89bb15469e6099b4ddc998a5d1bcad0fd95320b148a40f ;; \
*) echo "Unsupported architecture: $TARGETARCH" >&2; exit 1 ;; \
esac \
&& curl -fsSL "https://github.com/tee8z/via/releases/download/v0.6.1/via-linux-$via.tar.gz" -o /tmp/via.tar.gz \
Expand All @@ -70,7 +82,10 @@
&& curl -fsSL "https://dl.k8s.io/release/v1.35.8/bin/linux/${TARGETARCH}/kubectl" -o /usr/local/bin/kubectl \
&& echo "$kubectl_sha /usr/local/bin/kubectl" | sha256sum -c - \
&& chmod 0755 /usr/local/bin/kubectl \
&& rm /tmp/via.tar.gz /tmp/op.zip /tmp/gitleaks.tar.gz /tmp/depot.tar.gz /tmp/sccache.tar.gz
&& curl -fsSL "https://github.com/taiki-e/cargo-llvm-cov/releases/download/v0.8.5/cargo-llvm-cov-$llvm_cov-unknown-linux-musl.tar.gz" -o /tmp/cargo-llvm-cov.tar.gz \
&& echo "$llvm_cov_sha /tmp/cargo-llvm-cov.tar.gz" | sha256sum -c - \
&& tar -xzf /tmp/cargo-llvm-cov.tar.gz -C /usr/local/bin cargo-llvm-cov \
&& rm /tmp/via.tar.gz /tmp/op.zip /tmp/gitleaks.tar.gz /tmp/depot.tar.gz /tmp/sccache.tar.gz /tmp/cargo-llvm-cov.tar.gz
COPY voltage/images/buzz-agent/checkpoint-gitleaks.toml /opt/agent-tools/checkpoint-gitleaks.toml
WORKDIR /opt/buzz-runtimes
COPY voltage/images/buzz-agent/package.json voltage/images/buzz-agent/package-lock.json ./
Expand All @@ -79,6 +94,7 @@
&& rm -rf node_modules/@anthropic-ai/*-linux-*-musl \
&& npm cache clean --force
COPY --from=builder /build/target/sprig/sprig /usr/local/bin/sprig
COPY --from=crap-tools /opt/crap-tools/bin/knots /usr/local/bin/knots
COPY --chmod=0755 voltage/images/buzz-agent/account.py /usr/local/bin/buzz-agent-account
COPY --chmod=0755 voltage/images/buzz-agent/profile.py /usr/local/bin/buzz-agent-profile
COPY --chmod=0755 voltage/images/buzz-agent/cache.py /usr/local/bin/buzz-agent-cache
Expand Down
1 change: 1 addition & 0 deletions voltage/images/buzz-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Staging agent workers are Graviton (`arm64`); the tool downloads in the Dockerfi
Each developer supplies their own accounts at runtime.

The image contains Codex and Claude ACP adapters, Rust, Node, Go, Python, Git, GitHub CLI, `via`, `kubectl`, and SQL clients.
For the `rust-crap-score` engineering skill, it also has `cargo-llvm-cov` 0.8.5 (checksum-pinned release), `knots` 1.16.0 (built from crates.io with its published lockfile), and the toolchain's `llvm-tools-preview` component. The skill rejects other versions.
Buzz selects the runtime, model, persona, and arguments for each session.
The image builds the Buzz source of the commit it is built from; npm dependencies use the committed lockfile.

Expand Down
16 changes: 16 additions & 0 deletions voltage/images/buzz-agent/test-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,21 @@ docker run --rm --tmpfs /home/agent:uid=10001,gid=10001,mode=0700 \
claude --version >/dev/null
command -v codex-acp claude-agent-acp buzz-dev-mcp >/dev/null
'
# rust-crap-score accepts exactly these versions. Collect real coverage and
# complexity for a one-function crate, offline, as the skill does.
docker run --rm --entrypoint /bin/bash "$IMAGE" -ceu '
test "$(cargo llvm-cov --version)" = "cargo-llvm-cov 0.8.5"
test "$(knots --version)" = "knots 1.16.0"
rustup component list --installed | grep -q "^llvm-tools"
cd "$(mktemp -d)"
cargo new --quiet --vcs none --lib crap-smoke
cd crap-smoke
printf "%s\n" "pub fn magnitude(x: i32) -> i32 { if x > 0 { x } else { -x } }" \
"#[test] fn negative() { assert_eq!(magnitude(-1), 1); }" > src/lib.rs
cargo llvm-cov --offline --lcov --output-path lcov.info 2>/dev/null
grep -q "^SF:.*src/lib.rs" lcov.info
knots --recursive --language rust --count-anonymous-closures --format json src \
| python3 -c "import json, sys; json.load(sys.stdin)"
'
python3 "$(dirname "$0")/test-review.py" "$IMAGE"
printf 'PASS: agent adapter packaging and unauthenticated ACP initialization (%s)\n' "$IMAGE"
Loading