Stack (DEP-91)
Split from #1662 for reviewability, then rescoped: main has since landed #1681 (dependency/toolchain CVEs) and #1693 (hoophq/hoopagent), which superseded two PRs of the original stack.
-
#1683 — Go dependency + toolchain CVE bumps— closed, superseded by #1681 -
#1685 — opt-in— closed, superseded by #1693hoophq/hoopdev-minimal -
#1684 — 1. agent-tools: drop kernel-header CVEs, modernize clean train
-
#1686 — 2. Vulnerability gates for hoopagent + govulncheck
-
#1687 — 3. SBOM + bundled-tool manifest on releases
-
#1688 — 4. Weekly base-OS rebuild of hoopagent ← you are here
-
#1689 — 5. Image release integrity hardening
Merge in order, bottom-up. Each PR targets the one below it.
The remaining work is what main still lacks: the fat image's kernel-header CVEs, and any vulnerability gate, SBOM, or scheduled OS patching for hoophq/hoopagent.
What
Weekly scheduled rebuild of hoophq/hoopagent:-minimal against current OS security patches, republished only when the OS layer is free of fixable CRITICAL/HIGH vulnerabilities.
Published tags:
:latest-minimal— moving, always the latest patches:<release>-minimal-<YYYYMMDD>— weekly patched snapshot
The immutable :<release>-minimal tag is left untouched.
Why
Releases already rebuild every image; this closes the gap between releases so the moving tags do not accrue unpatched OS CVEs for weeks.
Design note — this is not a plain rebuild
Dockerfile.agent pins its base (ARG UBUNTU_IMAGE=ubuntu:noble-<date>) for reproducibility, and does not run apt-get upgrade. A plain rebuild would therefore reproduce identical bytes and patch nothing.
This job instead resolves the current ubuntu:noble digest and overrides the UBUNTU_IMAGE build-arg. The pinned default in Dockerfile.agent is untouched — bumping it stays a deliberate PR, per the policy in that file.
Only the minimal flavour is rebuilt: distroless installs no OS packages, so an OS re-patch has nothing to fix there.
Risk
Scheduled workflow only. Gated on the same enforcing Trivy check per arch before any push, so a vulnerable rebuild is never published. Pin by digest when immutable bytes matter.
How to test
Trigger Slim Agent Weekly Rebuild via workflow_dispatch. Expected: resolves the latest release, stages both arch tarballs, builds against current noble, passes both gates, then publishes.
Part of DEP-91.
Automated by MisterMal
Activity
9Code Review by Qodo
🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)
1. DEP-91 not comment-prefixed 📘 Rule violation ⚙ Maintainability
Description
A new comment mentions DEP-91 but does not start with the ticket ID, violating the required Linear ticket comment prefix format. This makes automated linkage/search for ticket references unreliable.
Code
.github/workflows/minimal-image-rebuild.yml[2]+# (hoophq/hoopdev-minimal). Closes DEP-91 point 4: "weekly base-OS patches".
Evidence
PR Compliance ID 2362449 requires that any comment mentioning a Linear ticket begin with the ticket ID. In the new workflow file, line 2 mentions DEP-91 but the comment begins with (hoophq/hoopdev-minimal)..., not DEP-91:.
Rule 2362449: Prefix external issue IDs in code comments that reference Linear tickets.github/workflows/minimal-image-rebuild.yml[1-2]
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution ## Issue description A new comment references a Linear ticket (`DEP-91`) but the comment text does not begin with the ticket ID token as required. ## Issue Context The compliance rule requires any comment referencing a Linear ticket to start with the ticket ID in the format `[A-Z]+-[0-9]+` immediately after the comment delimiter. ## Fix Focus Areas - .github/workflows/minimal-image-rebuild.yml[1-3]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
2. Checksum verify can no-op 🐞 Bug ⛨ Security
Description
The workflow uses sha256sum -c --ignore-missing without asserting that the downloaded tarballs were actually verified; if checksums.txt ever lists just basenames (a format supported by the repo’s checksum parser) or otherwise doesn’t match dist/binaries/..., the verification can silently skip all relevant entries and still succeed, allowing unverified binaries to be republished.
Code
.github/workflows/minimal-image-rebuild.yml[R79-82]+ # checksums.txt paths are ./dist/binaries/...; verify from the repo root. + # --ignore-missing skips the other-platform entries but still fails if + # a staged tarball mismatches or none were verified. + sha256sum -c --ignore-missing dist/binaries/checksums.txt
Relevance
●● ModerateSecurity-hardening suggestion; no close repo precedent for enforcing non-no-op sha256sum verification in workflows.
ⓘ Recommendations generated based on similar findings in past PRs
Evidence
The workflow claims verification “fails closed” but uses --ignore-missing and does not check that any tarball was verified. The repo’s release checksum generation and client-side verification logic indicate checksum entries may include paths or just basenames, making path-dependent sha256sum -c brittle when paired with --ignore-missing.
.github/workflows/minimal-image-rebuild.yml[57-85]Makefile[178-184]Makefile[297-301]client/upgrade/installer.go[155-177]client/upgrade/installer_test.go[113-120]
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution ## Issue description The weekly rebuild workflow runs `sha256sum -c --ignore-missing` but does not ensure that the specific staged tarballs were verified (i.e., at least one/each expected tarball produced an `OK`). With `--ignore-missing`, a checksum file that doesn’t reference the staged paths can result in a no-op check that still exits 0. ## Issue Context The repo’s own checksum parsing logic matches by basename (not full path), so the checksum file format is intentionally flexible; relying on path-matching plus `--ignore-missing` is brittle and can defeat the intended “fail closed” behavior. ## Fix Focus Areas - .github/workflows/minimal-image-rebuild.yml[57-85] ### Concrete fix idea - Extract the checksum lines for the two exact tarballs you downloaded (x86_64 and aarch64) using `grep` on `checksums.txt` (matching by basename), write those to a temporary file, then run `sha256sum -c` **without** `--ignore-missing` on that temp file. - Additionally, assert both expected artifacts were found in the checksum file before proceeding (e.g., count matches == 2).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
3. No secrets preflight 🐞 Bug ☼ Reliability
Description
The workflow attempts Docker Hub login using secrets.DOCKER_LOGIN/secrets.DOCKER_PASSWORD without an explicit preflight check, so misconfiguration yields a less actionable failure message than a dedicated “missing secret” error.
Code
.github/workflows/minimal-image-rebuild.yml[R52-55]+ uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_LOGIN }} + password: ${{ secrets.DOCKER_PASSWORD }}
Relevance
●●● StrongTeam previously accepted failing early when required secrets are missing in workflows for clearer errors (#1595).
ⓘ Recommendations generated based on similar findings in past PRs
Evidence
The workflow directly passes Docker Hub secrets into the login action without validation. A prior accepted workflow fix in this repo added early secret checks to improve failure clarity for misconfigured secrets.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution ## Issue description Add an explicit early step that fails with a clear message if required Docker Hub secrets are missing/empty, improving diagnosability of scheduled/manual rebuild failures. ## Issue Context This repo has previously accepted adding early secret validation to avoid confusing failures later in workflows. ## Fix Focus Areas - .github/workflows/minimal-image-rebuild.yml[45-56] ### Concrete fix idea Insert a step before `docker/login-action`: - `if: ${{ secrets.DOCKER_LOGIN == '' || secrets.DOCKER_PASSWORD == '' }}` - Emit `::error::DOCKER_LOGIN/DOCKER_PASSWORD not set` and exit 1.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Context used
39 rules✅ Cross-repo context
repo: hoophq/infra (sha: 801e2c0a)hoophq/libhoophoophq/documentationhoophq/changelogTo customize comments, go to the Qodo configuration screen, or learn more in the docs.
Migration Safety Analysis
No database migrations were changed in this PR. Safe to deploy to sandbox.
✅ Build Completed with Success, Version=1688.0.0-g862482d
PR Summary by Qodo
Weekly rebuild and republish of hoopdev-minimal with OS-layer Trivy gate
✨ Enhancement⚙️ Configuration changes📝 Documentation🕐 20-40 MinutesAI Description
Diagram
High-Level Assessment
1. Rebuild from source on schedule (cut a ‘nightly’ release)
2. Only rebuild/push on base-image digest change
3. Use registry-side automated rebuilds (if supported)
Files changed (2)
+198 / -0Documentation (1)
+20 / -0custom-agent-image.md
Document minimal image tag semantics and weekly OS patch cadence+20/-0Other (1)
+178 / -0minimal-image-rebuild.yml
Add weekly minimal-image rebuild workflow with per-arch Trivy OS gate+178/-0