Skip to content

fix: unify CLI image discovery and standardize Go tooling#738

Merged
Aureliolo merged 4 commits intomainfrom
fix/fix-cli-image-finding
Mar 22, 2026
Merged

fix: unify CLI image discovery and standardize Go tooling#738
Aureliolo merged 4 commits intomainfrom
fix/fix-cli-image-finding

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Fix digest-only image discovery: Docker's --filter "reference=..." misses images pulled by digest only (no tag), causing synthorg uninstall and synthorg cleanup to skip the sandbox image. New internal/images package lists all images and filters by repo prefix in Go.
  • Eliminate duplicated image logic: Extract shared images.ListLocal, images.RefForService, images.ServiceNames, and images.InspectID -- replacing 3 duplicate constants and 4 duplicate function implementations across update_cleanup, update_health, diagnostics, and update commands.
  • Standardize all Go tooling on go -C cli: Add golangci-lint as a tool directive in go.mod, replace all (cd cli && ...) and bash -c 'cd cli && ...' patterns in pre-commit hooks and documentation.

Test plan

  • New internal/images package has full test coverage: TestServiceNames, TestRefForService, TestLocalImage_ServiceName, TestParseImageList (including digest-only case), TestParseImageListFieldValues, FuzzRefForService, FuzzParseImageList
  • Existing tests updated to call shared functions (TestRefForService in cmd, TestDiagnosticImageRefPriority in diagnostics)
  • go -C cli build ./... passes
  • go -C cli vet ./... passes
  • go -C cli test ./... all packages pass
  • go -C cli tool golangci-lint run reports 0 issues
  • Pre-commit hooks pass (golangci-lint, go-vet, go-test all use new go -C cli pattern)
  • Pre-push hooks pass

Review coverage

Pre-reviewed by 4 agents (docs-consistency, go-reviewer, go-conventions-enforcer, infra-reviewer). 6 findings addressed:

  1. Added images to CLAUDE.md Package Structure
  2. Removed duplicate fuzz target from cmd package
  3. Derived display prefix from images.RepoPrefix instead of hardcoding
  4. Replaced misleading path traversal guard with intentional-fallback documentation
  5. Added converse fuzz invariant (no @ when digest is empty)
  6. Silent-fallback behaviour documented as intentional

🤖 Generated with Claude Code

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1cfb24ec-63e5-41c8-be58-a3a33f8521c1

📥 Commits

Reviewing files that changed from the base of the PR and between c6bd5cb and 98bbce4.

⛔ Files ignored due to path filters (1)
  • cli/go.sum is excluded by !**/*.sum
📒 Files selected for processing (12)
  • .github/workflows/dependency-review.yml
  • .pre-commit-config.yaml
  • CLAUDE.md
  • cli/cmd/update.go
  • cli/cmd/update_cleanup.go
  • cli/cmd/update_health.go
  • cli/cmd/update_health_test.go
  • cli/go.mod
  • cli/internal/diagnostics/collect.go
  • cli/internal/diagnostics/collect_test.go
  • cli/internal/images/images.go
  • cli/internal/images/images_test.go
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: CLI Test (macos-latest)
  • GitHub Check: CLI Test (windows-latest)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{py,ts,tsx,js,vue,go}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{py,ts,tsx,js,vue,go}: Keep functions under 50 lines and files under 800 lines
Handle errors explicitly and never silently swallow exceptions
Validate input at system boundaries (user input, external APIs, config files)

Files:

  • cli/cmd/update.go
  • cli/internal/diagnostics/collect_test.go
  • cli/cmd/update_health_test.go
  • cli/cmd/update_health.go
  • cli/internal/diagnostics/collect.go
  • cli/cmd/update_cleanup.go
  • cli/internal/images/images_test.go
  • cli/internal/images/images.go
cli/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cli/**/*.go: Use Cobra commands for CLI structure; use go -C cli instead of cd cli to avoid poisoning shell cwd
Run Go tests with go -C cli test ./... and lint with go -C cli vet and golangci-lint run in a subshell

Files:

  • cli/cmd/update.go
  • cli/internal/diagnostics/collect_test.go
  • cli/cmd/update_health_test.go
  • cli/cmd/update_health.go
  • cli/internal/diagnostics/collect.go
  • cli/cmd/update_cleanup.go
  • cli/internal/images/images_test.go
  • cli/internal/images/images.go
.pre-commit-config.yaml

📄 CodeRabbit inference engine (CLAUDE.md)

.pre-commit-config.yaml: Pre-commit hooks include: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks, hadolint
Disable pre-commit.ci autoupdate (autoupdate_schedule: never); Dependabot owns hook version bumps

Files:

  • .pre-commit-config.yaml
cli/**/*_test.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use Go native testing.F fuzz functions for property-based testing in CLI

Files:

  • cli/internal/diagnostics/collect_test.go
  • cli/cmd/update_health_test.go
  • cli/internal/images/images_test.go
🧠 Learnings (30)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/cli.yml : CLI workflow: Go lint (golangci-lint + go vet) + test (-race -coverprofile) + build (cross-compile: linux/darwin/windows × amd64/arm64) + govulncheck + fuzz testing (main-only, 30s/target, continue-on-error, matrix over 4 packages). cli-pass gate includes fuzz as informational. GoReleaser release on v* tags. Cosign keyless signing of checksums.txt. SLSA L3 provenance attestations. Sigstore bundle (.sigstore.json) attached. Post-release appends checksums/verification/provenance to draft release notes.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/docker.yml : Docker workflow: builds backend + web + sandbox images, pushes to GHCR, signs with cosign. SLSA L3 provenance attestations via actions/attest-build-provenance. Scans: Trivy (CRITICAL = hard fail, HIGH = warn) + Grype (critical cutoff) + CIS Docker Benchmark v1.6.0 compliance (informational). CVE triage via .github/.trivyignore.yaml and .github/.grype.yaml. Images only pushed after scans pass. Triggers on push to main and version tags (v*).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Dependabot: auto-updates Docker image digests and versions daily.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T12:00:18.113Z
Learning: Applies to .github/workflows/docker.yml : CI Docker: build → scan → push to GHCR + cosign sign + SLSA L3 provenance via attest-build-provenance (images only pushed after Trivy/Grype scans pass).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/*.yml : Dependabot: daily updates for uv + github-actions + npm + pre-commit + docker + gomod, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on cli/**/*.go) (fast gate before push, skipped in pre-commit.ci — dedicated CI jobs already run these).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T19:52:03.656Z
Learning: Applies to cli/**/*.go : Lint CLI Go code with golangci-lint and go vet; test with go test -race; check vulnerabilities with govulncheck
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Pre-push hooks include: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI); skipped in pre-commit.ci
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/*.yml : Dependabot: daily updates for uv + github-actions + npm + pre-commit + docker + gomod, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.

Applied to files:

  • .github/workflows/dependency-review.yml
  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/cli.yml : CLI workflow: Go lint (golangci-lint + go vet) + test (-race -coverprofile) + build (cross-compile: linux/darwin/windows × amd64/arm64) + govulncheck + fuzz testing (main-only, 30s/target, continue-on-error, matrix over 4 packages). cli-pass gate includes fuzz as informational. GoReleaser release on v* tags. Cosign keyless signing of checksums.txt. SLSA L3 provenance attestations. Sigstore bundle (.sigstore.json) attached. Post-release appends checksums/verification/provenance to draft release notes.

Applied to files:

  • .github/workflows/dependency-review.yml
  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.

Applied to files:

  • .github/workflows/dependency-review.yml
  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/cla-signatures.json : CLA signatures stored in .github/cla-signatures.json on the cla-signatures branch (unprotected, so the action can commit directly). CLA check via contributor-assistant/github-action on pull_request_target and issue_comment. Skips Dependabot.

Applied to files:

  • .github/workflows/dependency-review.yml
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Pre-push hooks include: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI); skipped in pre-commit.ci

Applied to files:

  • .pre-commit-config.yaml
  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on cli/**/*.go) (fast gate before push, skipped in pre-commit.ci — dedicated CI jobs already run these).

Applied to files:

  • .pre-commit-config.yaml
  • CLAUDE.md
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Applies to cli/**/*.go : Run Go tests with `go -C cli test ./...` and lint with `go -C cli vet` and `golangci-lint run` in a subshell

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Applies to cli/**/*.go : Use Cobra commands for CLI structure; use `go -C cli` instead of `cd cli` to avoid poisoning shell cwd

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
  • cli/cmd/update_health.go
  • cli/cmd/update_cleanup.go
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Applies to .pre-commit-config.yaml : Pre-commit hooks include: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks, hadolint

Applied to files:

  • .pre-commit-config.yaml
  • CLAUDE.md
📚 Learning: 2026-03-16T19:52:03.656Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T19:52:03.656Z
Learning: Applies to cli/**/*.go : Lint CLI Go code with golangci-lint and go vet; test with go test -race; check vulnerabilities with govulncheck

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
📚 Learning: 2026-03-19T11:30:29.217Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:30:29.217Z
Learning: Applies to cli/**/*.go : Run Go lint via `golangci-lint run`, vet via `go vet`, tests via `go test ./...`, and fuzz via `go test -fuzz=FuzzTarget -fuzztime=30s`

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Pre-commit hooks: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks, hadolint (Dockerfile linting).

Applied to files:

  • .pre-commit-config.yaml
  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to cli/** : CLI: Go 1.26+, dependencies in cli/go.mod (Cobra, charmbracelet/huh).

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
  • cli/cmd/update_health.go
  • cli/cmd/update_cleanup.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to cli/**/*.go : Lint Go code with `golangci-lint` and `go vet`. Run tests with `-race` flag to detect race conditions.

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/**/*.go : Go CLI (Go 1.26+) uses Cobra for commands, charmbracelet/huh for interactive CLI, charmbracelet/lipgloss for styled output. Cross-platform builds (linux/darwin/windows × amd64/arm64). GoReleaser for releases with cosign keyless signing of checksums.txt. SLSA L3 provenance attestations via actions/attest-build-provenance.

Applied to files:

  • .pre-commit-config.yaml
  • cli/go.mod
  • CLAUDE.md
  • cli/cmd/update_health.go
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/go.mod : Go CLI dependencies: Go 1.26+, Cobra (commands), charmbracelet/huh (interactive CLI), charmbracelet/lipgloss (styled output).

Applied to files:

  • cli/go.mod
  • CLAUDE.md
  • cli/cmd/update_health.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).

Applied to files:

  • cli/go.mod
  • cli/cmd/update_health.go
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Applies to cli/**/*_test.go : Use Go native `testing.F` fuzz functions for property-based testing in CLI

Applied to files:

  • cli/cmd/update_health_test.go
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:30:29.217Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:30:29.217Z
Learning: Applies to cli/**/*.go : Use native `testing.F` fuzz functions (`Fuzz*`) for fuzz testing Go code

Applied to files:

  • cli/cmd/update_health_test.go
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to cli/**/*.go : Use native Go testing with `testing.F` fuzz functions (`Fuzz*`) for fuzz testing.

Applied to files:

  • cli/cmd/update_health_test.go
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-15T20:45:14.430Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T20:45:14.430Z
Learning: Shell commands: for Go CLI work, cd cli is an exception because Go tooling requires working directory to be the module root. Go commands require `cd cli` for other work, never use `cd`.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T12:00:18.113Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T12:00:18.113Z
Learning: Commits: <type>: <description> — types: feat, fix, refactor, docs, test, chore, perf, ci. Enforced by commitizen (commit-msg hook). Signed commits: required on main via branch protection — all commits must be GPG/SSH signed.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: All commits on main must be GPG/SSH signed (required by branch protection)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T15:39:41.418Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T15:39:41.418Z
Learning: Applies to docker/Dockerfile* : Dockerfile linting with hadolint must pass pre-commit hooks and CI

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/docker.yml : Docker workflow: builds backend + web + sandbox images, pushes to GHCR, signs with cosign. SLSA L3 provenance attestations via actions/attest-build-provenance. Scans: Trivy (CRITICAL = hard fail, HIGH = warn) + Grype (critical cutoff) + CIS Docker Benchmark v1.6.0 compliance (informational). CVE triage via .github/.trivyignore.yaml and .github/.grype.yaml. Images only pushed after scans pass. Triggers on push to main and version tags (v*).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Dependabot: auto-updates Docker image digests and versions daily.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T12:00:18.113Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T12:00:18.113Z
Learning: Applies to .github/workflows/docker.yml : CI Docker: build → scan → push to GHCR + cosign sign + SLSA L3 provenance via attest-build-provenance (images only pushed after Trivy/Grype scans pass).

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/finalize-release.yml : Finalize Release workflow: publishes draft releases created by Release Please. Triggers on workflow_run completion of Docker and CLI workflows. Verifies both workflows succeeded for the associated tag before publishing. Extracts CLI checksums, cosign verification, and container verification data from HTML comments, assembles into combined Verification section. Guards against PR-triggered runs. Handles TOCTOU races. Immutable releases enabled—once published, release assets and body cannot be modified.

Applied to files:

  • CLAUDE.md
🧬 Code graph analysis (7)
cli/cmd/update.go (1)
cli/internal/images/images.go (1)
  • RepoPrefix (15-15)
cli/internal/diagnostics/collect_test.go (1)
cli/internal/images/images.go (1)
  • RefForService (30-36)
cli/cmd/update_health_test.go (1)
cli/internal/images/images.go (1)
  • RefForService (30-36)
cli/cmd/update_health.go (1)
cli/internal/images/images.go (3)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • InspectID (98-104)
cli/internal/diagnostics/collect.go (1)
cli/internal/images/images.go (4)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • InspectID (98-104)
  • RepoPrefix (15-15)
cli/cmd/update_cleanup.go (1)
cli/internal/images/images.go (5)
  • ListLocal (58-66)
  • RepoPrefix (15-15)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • InspectID (98-104)
cli/internal/images/images_test.go (1)
cli/internal/images/images.go (4)
  • RepoPrefix (15-15)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • LocalImage (39-45)
🔇 Additional comments (33)
.github/workflows/dependency-review.yml (1)

57-78: LGTM — Well-documented GPL exemptions for dev-only tool dependencies.

The rationale is sound: tool directive dependencies in cli/go.mod are invoked at dev/CI time only and never compiled into the SynthOrg binary, so GPL copyleft does not apply to the project output. The per-package exemptions are appropriate given the action cannot distinguish tool deps from runtime deps.

cli/cmd/update.go (2)

19-19: LGTM — Import of shared images package.

Consolidates image reference logic to avoid duplication across commands.


641-641: LGTM — Correctly uses shared images.RepoPrefix.

This replaces the file-local imageRepoPrefix constant, aligning with the PR's goal of consolidating duplicated image logic into cli/internal/images. The resulting reference format (ghcr.io/aureliolo/synthorg-<service>) remains unchanged.

.pre-commit-config.yaml (1)

76-98: LGTM — Standardized Go tooling with go -C cli.

The updated hook entries correctly:

  1. Use go -C cli to change directory without polluting shell cwd
  2. Invoke golangci-lint via go tool leveraging the tool directive in cli/go.mod
  3. Maintain appropriate stages (lint on pre-commit/pre-push, test on pre-push only)

As per coding guidelines: "use go -C cli instead of cd cli to avoid poisoning shell cwd".

CLAUDE.md (2)

60-68: LGTM — Clear documentation of Go tooling standardization.

The note correctly explains:

  1. Why go -C cli is preferred (avoids poisoning shell cwd)
  2. How golangci-lint is registered as a tool in cli/go.mod
  3. The resulting invocation pattern (go -C cli tool golangci-lint)

135-135: LGTM — Internal package list updated with images submodule.

Correctly reflects the new cli/internal/images package introduced in this PR.

cli/cmd/update_health_test.go (1)

9-116: LGTM — Test correctly validates shared images.RefForService.

The table-driven test comprehensively covers:

  • Digest-pinned references for all services
  • Tag-based fallbacks (nil map, empty map, empty value, missing key)
  • Edge case documentation for empty imageTag

The fuzz test removal is appropriate since fuzz coverage is now in cli/internal/images/images_test.go as noted in the PR description.

cli/internal/diagnostics/collect_test.go (1)

389-476: LGTM — Test validates diagnostic image ref priority correctly.

The test comprehensively covers the compose-ref-first priority used by checkImages:

  1. Compose ref takes precedence over state digests
  2. Fallback to images.RefForService (digest > tag) when no compose ref
  3. Cross-service isolation (compose ref for backend doesn't affect web)
  4. Edge cases: nil maps, empty digest values

The inline priority logic (lines 465-470) correctly mirrors the actual implementation.

cli/cmd/update_health.go (2)

12-12: LGTM — Import of shared images package.


120-134: LGTM — Correctly uses shared image utilities.

The refactoring:

  1. Uses images.ServiceNames(state.Sandbox) for service iteration (handles sandbox toggle)
  2. Uses images.RefForService for digest-vs-tag reference construction
  3. Uses images.InspectID for Docker image inspection

Context cancellation handling (lines 126-130) is correctly preserved to avoid false positives when Docker is unresponsive.

cli/go.mod (1)

294-295: LGTM — tool directive correctly declares golangci-lint as a module tool.

This enables go -C cli tool golangci-lint run without requiring separate installation, aligning with the standardized Go tooling approach. Version v2.11.3 is the latest release and current.

cli/cmd/update_cleanup.go (4)

13-13: LGTM!

Clean import of the new images package that centralizes image discovery logic.


70-93: LGTM!

The refactoring to use images.ListLocal correctly addresses the digest-only image discovery bug. The iteration over LocalImage structs is cleaner than parsing raw docker output, and the nil-map safety comment is helpful.


97-100: LGTM!

The display string derivation correctly uses the shared images.RepoPrefix constant, and the comment clearly explains the transformation from full GHCR path to user-friendly synthorg-<service> format.


126-149: LGTM!

Clean adoption of the centralized images.ServiceNames, RefForService, and InspectID helpers. The dual ID storage (full + short) correctly handles the format difference between docker image inspect (full IDs) and docker images --format {{.ID}} (short IDs).

cli/internal/diagnostics/collect.go (3)

20-20: LGTM!

Clean import of the centralized images package.


306-325: LGTM!

The refactored checkImages correctly implements the priority chain (compose ref → verified digest → tag fallback) using the centralized helpers. The per-service error reporting in status is preserved.


335-379: LGTM!

The updated parseComposeImageRefs properly uses the shared images.RepoPrefix constant and the new documentation clearly explains the intentional silent-error behavior for diagnostic resilience. The filepath.Clean canonicalization with the documented internal-only path construction is appropriate.

cli/internal/images/images_test.go (8)

1-14: LGTM!

Clean test file setup with parallel execution. The TestRepoPrefix test validates the constant's expected value.


16-44: LGTM!

Thorough tests for ServiceNames including the important slice independence check. The mutation test at lines 35-43 confirms callers can safely modify returned slices without affecting subsequent calls.


46-107: LGTM!

Comprehensive table-driven tests for RefForService covering all fallback scenarios: digest-pinned, nil map, empty-string digest, and missing service key. Good edge case coverage.


109-131: LGTM!

Good coverage of ServiceName() extraction including the fallback behavior when the repository doesn't match RepoPrefix.


133-209: LGTM!

Excellent test coverage for parseImageList including the critical digest-only image case (lines 159-164) that validates the PR's main bug fix. The Windows CRLF handling test ensures cross-platform compatibility.


211-236: LGTM!

Valuable test that verifies exact field population from parsed docker output, ensuring the tab-delimited parsing correctly maps to LocalImage struct fields.


238-270: LGTM!

Well-structured fuzz test with proper invariant checks. The converse invariant at lines 265-268 (empty digest → no @) complements the forward check, ensuring complete coverage of the digest/tag selection logic. As per coding guidelines, native testing.F fuzz functions are used correctly.


272-287: LGTM!

Good fuzz test that validates the core filtering invariant: parseImageList should only ever return images with repositories starting with RepoPrefix, regardless of what arbitrary input it receives.

cli/internal/images/images.go (7)

1-15: LGTM!

Clean package structure with proper documentation. The RepoPrefix constant correctly derives from the verify package, ensuring consistency across the codebase.


17-24: LGTM!

Simple and correct implementation. Returning slice literals ensures each caller gets an independent slice, as verified by the tests.


26-36: LGTM!

The digest check at line 32 correctly handles all edge cases: nil map, missing key, and empty-string value all fall through to the tag-based reference.


38-51: LGTM!

Well-documented struct with clear field descriptions. The ServiceName() method's use of TrimPrefix provides a safe fallback when the prefix doesn't match.


53-66: LGTM!

The implementation correctly addresses the digest-only image discovery bug by listing all images and filtering in Go rather than relying on Docker's --filter "reference=..." which misses untagged images. The tab-delimited format aligns with parseImageList's expectations.


68-94: LGTM!

Clean parsing implementation using strings.SplitSeq (Go 1.24+ iterator API). The CRLF normalization ensures Windows compatibility, and the 5-field minimum check safely rejects malformed lines. The RepoPrefix filter correctly limits results to SynthOrg images only.


96-104: LGTM!

Clean wrapper around docker image inspect with proper whitespace trimming for the output. The function correctly handles both digest-pinned and tag-based references as noted in the documentation.


Walkthrough

This pull request centralizes SynthOrg container image discovery and reference construction into a new cli/internal/images package, consolidating image-handling logic used by multiple CLI commands. It adds exported helpers for repo prefix, service enumeration, reference construction (digest pinning), local image listing, and image inspection, and updates callers to use them. Additionally, pre-commit hooks were changed to invoke Go via go -C cli ..., tests were reorganized, and golangci-lint was declared as a Go tool dependency.

Suggested labels

autorelease: tagged

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: fixing CLI image discovery (digest-only images) and standardizing Go tooling across the codebase.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing the three key improvements (digest-only image discovery fix, elimination of duplicated image logic, and standardization of Go tooling) with clear test coverage and review information.
Docstring Coverage ✅ Passed Docstring coverage is 57.69% which is sufficient. The required threshold is 40.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 22, 2026

Dependency Review

The following issues were found:

  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 51 package(s) with unknown licenses.
  • ⚠️ 23 packages with OpenSSF Scorecard issues.

View full job summary

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the CLI's robustness and maintainability by centralizing Docker image management and standardizing Go tooling practices. The changes ensure that all SynthOrg images, including those pulled by digest, are correctly identified and managed, preventing silent failures in cleanup operations. Furthermore, the adoption of go -C cli streamlines development workflows and enhances consistency across the project.

Highlights

  • Unified Image Discovery: Implemented a new internal/images package to reliably discover Docker images, addressing an issue where Docker's --filter command missed digest-only images, which previously caused synthorg uninstall and synthorg cleanup to overlook the sandbox image.
  • Eliminated Duplicated Image Logic: Refactored and consolidated image-related functions and constants into the new internal/images package, removing redundant implementations across update_cleanup, update_health, diagnostics, and update commands.
  • Standardized Go Tooling: Standardized all Go tooling commands in pre-commit hooks and documentation to use go -C cli for consistent execution from the module root, and registered golangci-lint as a tool directive in go.mod.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant and beneficial refactoring. It correctly fixes a bug in Docker image discovery for digest-only images by implementing a more robust listing method. It also greatly improves code maintainability by centralizing duplicated image-related logic into a new internal/images package. The standardization of Go tooling to use go -C cli is a good consistency improvement. The new images package is well-tested, including fuzz tests. I have one suggestion to make the image list parsing slightly more efficient and idiomatic.

Comment on lines +71 to +94
func parseImageList(raw string) []LocalImage {
var images []LocalImage
for line := range strings.SplitSeq(strings.TrimSpace(strings.ReplaceAll(raw, "\r\n", "\n")), "\n") {
if line == "" {
continue
}
parts := strings.SplitN(line, "\t", 5)
if len(parts) < 5 {
continue
}
repo := parts[0]
if !strings.HasPrefix(repo, RepoPrefix) {
continue
}
images = append(images, LocalImage{
Repository: repo,
Tag: parts[1],
Size: parts[2],
ID: parts[3],
Digest: parts[4],
})
}
return images
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better performance and more idiomatic Go, consider using a bufio.Scanner to process the raw string line by line. This avoids creating intermediate strings with strings.ReplaceAll and strings.TrimSpace on the entire input, making it more memory-efficient, especially if the docker images output is large. bufio.Scanner also handles both \n and \r\n line endings automatically.

You'll need to add import "bufio" to your imports.

func parseImageList(raw string) []LocalImage {
	var images []LocalImage
	scanner := bufio.NewScanner(strings.NewReader(raw))
	for scanner.Scan() {
		line := scanner.Text()
		if line == "" {
			continue
		}
		parts := strings.SplitN(line, "\t", 5)
		if len(parts) < 5 {
			continue
		}
		repo := parts[0]
		if !strings.HasPrefix(repo, RepoPrefix) {
			continue
		}
		images = append(images, LocalImage{
			Repository: repo,
			Tag:        parts[1],
			Size:       parts[2],
			ID:         parts[3],
			Digest:     parts[4],
		})
	}
	return images
}

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cli/cmd/update.go (1)

615-617: 🧹 Nitpick | 🔵 Trivial

Consider deriving regex pattern from images.RepoPrefix for consistency.

The imageLinePattern regex hardcodes ghcr.io/aureliolo/synthorg- while line 641 uses images.RepoPrefix. While functionally correct (the regex matches existing compose content), deriving the pattern from the constant would ensure consistency if the prefix ever changes.

However, since regex patterns require escaping and the prefix is unlikely to change, this is a minor observation rather than a required change.

Also applies to: 641-641

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli/cmd/update.go` around lines 615 - 617, The regex variable
imageLinePattern currently hardcodes the repo prefix; change its initialization
to build the pattern from images.RepoPrefix so the code stays consistent if the
prefix changes: compose the pattern string using
regexp.QuoteMeta(images.RepoPrefix) (to escape special chars) and fmt.Sprintf to
insert the quoted prefix into the existing pattern that still matches (e.g.
`(\s+image:\s+)<quotedPrefix>(backend|web|sandbox)[\S]*`), then call
regexp.MustCompile on that string to set imageLinePattern.
cli/cmd/update_health_test.go (1)

9-117: 🧹 Nitpick | 🔵 Trivial

Consider consolidating with images_test.go to reduce duplication.

This test file now tests images.RefForService from the cmd package, while cli/internal/images/images_test.go has comprehensive tests for the same function. The test cases largely overlap (digest-pinned, tag-based, nil/empty digests, service not in map, etc.).

Options:

  1. Keep both if the intent is to test from the caller's perspective (integration-style).
  2. Remove this file and rely on images_test.go for unit coverage.
  3. Reduce this file to a few smoke tests and let images_test.go handle edge cases.

Given the PR description mentions "Existing tests updated to call shared functions," keeping caller-side tests may be intentional for regression detection.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli/cmd/update_health_test.go` around lines 9 - 117, The TestRefForService
file duplicates coverage already exercised by cli/internal/images/images_test.go
for images.RefForService; either delete this test file
(cli/cmd/update_health_test.go) and rely on images_test.go for unit coverage, or
reduce it to 2–3 caller-level smoke tests that only assert a couple of
representative behaviors (e.g., digest-pinned and tag-based) and remove
overlapping table-driven cases; update or remove references to TestRefForService
and ensure remaining tests call images.RefForService to preserve any intended
integration/caller-level checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@cli/cmd/update_health_test.go`:
- Around line 9-117: The TestRefForService file duplicates coverage already
exercised by cli/internal/images/images_test.go for images.RefForService; either
delete this test file (cli/cmd/update_health_test.go) and rely on images_test.go
for unit coverage, or reduce it to 2–3 caller-level smoke tests that only assert
a couple of representative behaviors (e.g., digest-pinned and tag-based) and
remove overlapping table-driven cases; update or remove references to
TestRefForService and ensure remaining tests call images.RefForService to
preserve any intended integration/caller-level checks.

In `@cli/cmd/update.go`:
- Around line 615-617: The regex variable imageLinePattern currently hardcodes
the repo prefix; change its initialization to build the pattern from
images.RepoPrefix so the code stays consistent if the prefix changes: compose
the pattern string using regexp.QuoteMeta(images.RepoPrefix) (to escape special
chars) and fmt.Sprintf to insert the quoted prefix into the existing pattern
that still matches (e.g.
`(\s+image:\s+)<quotedPrefix>(backend|web|sandbox)[\S]*`), then call
regexp.MustCompile on that string to set imageLinePattern.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 271f5783-59eb-4823-83e1-953455974205

📥 Commits

Reviewing files that changed from the base of the PR and between 677eb15 and c6bd5cb.

⛔ Files ignored due to path filters (1)
  • cli/go.sum is excluded by !**/*.sum
📒 Files selected for processing (11)
  • .pre-commit-config.yaml
  • CLAUDE.md
  • cli/cmd/update.go
  • cli/cmd/update_cleanup.go
  • cli/cmd/update_health.go
  • cli/cmd/update_health_test.go
  • cli/go.mod
  • cli/internal/diagnostics/collect.go
  • cli/internal/diagnostics/collect_test.go
  • cli/internal/images/images.go
  • cli/internal/images/images_test.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CLI Test (windows-latest)
  • GitHub Check: CLI Test (macos-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (1)
cli/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

cli/**/*.go: Go CLI must use Cobra for command structure, charmbracelet libraries for terminal UI, sigstore-go for signature verification, go-containerregistry for Docker image handling, go-tuf for TUF verification
Go CLI binaries must verify cosign signatures and SLSA provenance at pull time; provide --skip-verify bypass option

Files:

  • cli/cmd/update.go
  • cli/cmd/update_health_test.go
  • cli/internal/diagnostics/collect_test.go
  • cli/cmd/update_health.go
  • cli/cmd/update_cleanup.go
  • cli/internal/diagnostics/collect.go
  • cli/internal/images/images_test.go
  • cli/internal/images/images.go
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/cli.yml : CLI workflow: Go lint (golangci-lint + go vet) + test (-race -coverprofile) + build (cross-compile: linux/darwin/windows × amd64/arm64) + govulncheck + fuzz testing (main-only, 30s/target, continue-on-error, matrix over 4 packages). cli-pass gate includes fuzz as informational. GoReleaser release on v* tags. Cosign keyless signing of checksums.txt. SLSA L3 provenance attestations. Sigstore bundle (.sigstore.json) attached. Post-release appends checksums/verification/provenance to draft release notes.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/docker.yml : Docker workflow: builds backend + web + sandbox images, pushes to GHCR, signs with cosign. SLSA L3 provenance attestations via actions/attest-build-provenance. Scans: Trivy (CRITICAL = hard fail, HIGH = warn) + Grype (critical cutoff) + CIS Docker Benchmark v1.6.0 compliance (informational). CVE triage via .github/.trivyignore.yaml and .github/.grype.yaml. Images only pushed after scans pass. Triggers on push to main and version tags (v*).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Dependabot: auto-updates Docker image digests and versions daily.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T12:00:18.113Z
Learning: Applies to .github/workflows/docker.yml : CI Docker: build → scan → push to GHCR + cosign sign + SLSA L3 provenance via attest-build-provenance (images only pushed after Trivy/Grype scans pass).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on `cli/**/*.go`) -- fast gate before push, skipped in pre-commit.ci
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Applies to cli/**/*.go : Go CLI must use Cobra for command structure, charmbracelet libraries for terminal UI, sigstore-go for signature verification, go-containerregistry for Docker image handling, go-tuf for TUF verification
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T19:52:03.656Z
Learning: Applies to cli/**/*.go : Lint CLI Go code with golangci-lint and go vet; test with go test -race; check vulnerabilities with govulncheck
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on cli/**/*.go) (fast gate before push, skipped in pre-commit.ci — dedicated CI jobs already run these).
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Applies to cli/** : CLI: Go 1.26+, dependencies in cli/go.mod (Cobra, charmbracelet/huh).

Applied to files:

  • cli/cmd/update.go
  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
  • cli/cmd/update_health.go
  • cli/cmd/update_cleanup.go
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Applies to cli/**/*.go : Go CLI must use Cobra for command structure, charmbracelet libraries for terminal UI, sigstore-go for signature verification, go-containerregistry for Docker image handling, go-tuf for TUF verification

Applied to files:

  • cli/cmd/update.go
  • CLAUDE.md
  • cli/go.mod
  • cli/cmd/update_health.go
  • cli/cmd/update_cleanup.go
  • cli/internal/diagnostics/collect.go
  • cli/internal/images/images.go
📚 Learning: 2026-03-16T19:52:03.656Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T19:52:03.656Z
Learning: Applies to cli/**/*.go : Lint CLI Go code with golangci-lint and go vet; test with go test -race; check vulnerabilities with govulncheck

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:30:29.217Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:30:29.217Z
Learning: Applies to cli/**/*.go : Run Go lint via `golangci-lint run`, vet via `go vet`, tests via `go test ./...`, and fuzz via `go test -fuzz=FuzzTarget -fuzztime=30s`

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to .github/workflows/cli.yml : CLI workflow: Go lint (golangci-lint + go vet) + test (-race -coverprofile) + build (cross-compile: linux/darwin/windows × amd64/arm64) + govulncheck + fuzz testing (main-only, 30s/target, continue-on-error, matrix over 4 packages). cli-pass gate includes fuzz as informational. GoReleaser release on v* tags. Cosign keyless signing of checksums.txt. SLSA L3 provenance attestations. Sigstore bundle (.sigstore.json) attached. Post-release appends checksums/verification/provenance to draft release notes.

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: For CLI Go commands requiring module root as cwd, use `go -C cli` (changes directory internally) instead of `cd cli` (poisons the shell cwd)

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Run Go linting with `golangci-lint run` from a subshell (use `(cd cli && golangci-lint run)` instead of `go -C cli lint` which doesn't exist)

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
📚 Learning: 2026-03-15T20:45:14.430Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T20:45:14.430Z
Learning: Shell commands: for Go CLI work, cd cli is an exception because Go tooling requires working directory to be the module root. Go commands require `cd cli` for other work, never use `cd`.

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/go.mod : Go CLI dependencies: Go 1.26+, Cobra (commands), charmbracelet/huh (interactive CLI), charmbracelet/lipgloss (styled output).

Applied to files:

  • CLAUDE.md
  • cli/go.mod
  • cli/cmd/update_health.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to cli/**/*.go : Lint Go code with `golangci-lint` and `go vet`. Run tests with `-race` flag to detect race conditions.

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
📚 Learning: 2026-03-15T21:32:02.880Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T21:32:02.880Z
Learning: Applies to cli/**/*.go : Go CLI (Go 1.26+) uses Cobra for commands, charmbracelet/huh for interactive CLI, charmbracelet/lipgloss for styled output. Cross-platform builds (linux/darwin/windows × amd64/arm64). GoReleaser for releases with cosign keyless signing of checksums.txt. SLSA L3 provenance attestations via actions/attest-build-provenance.

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
  • cli/cmd/update_health.go
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Use `go -C cli` to run Go commands in CLI directory (build, test, vet, fuzz) without changing shell cwd

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Use `go -C cli test -fuzz=FuzzYamlStr -fuzztime=30s ./internal/compose/` for fuzzing Go CLI code

Applied to files:

  • CLAUDE.md
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: CLI workflow (`.github/workflows/cli.yml`) runs Go lint (golangci-lint + go vet) + test (race, coverage) + build (cross-compile matrix) + vulnerability check (govulncheck) + fuzz testing. Cross-compiles for linux/darwin/windows × amd64/arm64. GoReleaser release on v* tags with cosign keyless signing and SLSA L3 attestations.

Applied to files:

  • CLAUDE.md
  • .pre-commit-config.yaml
  • cli/go.mod
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Applies to site/**/*.astro : Use Astro for the synthorg.io landing page; include `/get/` CLI install page, contact form, SEO

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on `cli/**/*.go`) -- fast gate before push, skipped in pre-commit.ci

Applied to files:

  • .pre-commit-config.yaml
📚 Learning: 2026-03-15T18:17:43.675Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:17:43.675Z
Learning: Pre-push hooks: mypy type-check + pytest unit tests + golangci-lint + go vet + go test (CLI, conditional on cli/**/*.go) (fast gate before push, skipped in pre-commit.ci — dedicated CI jobs already run these).

Applied to files:

  • .pre-commit-config.yaml
📚 Learning: 2026-03-19T11:30:29.217Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:30:29.217Z
Learning: Applies to cli/**/*.go : Use native `testing.F` fuzz functions (`Fuzz*`) for fuzz testing Go code

Applied to files:

  • cli/cmd/update_health_test.go
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to cli/**/*.go : Use native Go testing with `testing.F` fuzz functions (`Fuzz*`) for fuzz testing.

Applied to files:

  • cli/cmd/update_health_test.go
  • cli/internal/images/images_test.go
📚 Learning: 2026-03-19T11:19:40.044Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T11:19:40.044Z
Learning: Applies to go.mod : Maintain Go 1.26+ requirement. Dependencies: Cobra (CLI framework), charmbracelet/huh and charmbracelet/lipgloss (UI), sigstore-go (code signing), go-containerregistry (container image verification), go-tuf (TUF client for Sigstore).

Applied to files:

  • cli/go.mod
  • cli/cmd/update_health.go
📚 Learning: 2026-03-22T14:41:20.060Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-22T14:41:20.060Z
Learning: Applies to docker/Dockerfile* : Docker images: backend (Chainguard distroless, non-root), web (nginx-unprivileged, SPA + API proxy), sandbox (Python + Node.js, non-root)

Applied to files:

  • cli/internal/images/images.go
🧬 Code graph analysis (7)
cli/cmd/update.go (1)
cli/internal/images/images.go (1)
  • RepoPrefix (15-15)
cli/cmd/update_health_test.go (1)
cli/internal/images/images.go (1)
  • RefForService (30-36)
cli/internal/diagnostics/collect_test.go (1)
cli/internal/images/images.go (1)
  • RefForService (30-36)
cli/cmd/update_health.go (1)
cli/internal/images/images.go (3)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • InspectID (98-104)
cli/cmd/update_cleanup.go (1)
cli/internal/images/images.go (5)
  • ListLocal (58-66)
  • RepoPrefix (15-15)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • InspectID (98-104)
cli/internal/diagnostics/collect.go (1)
cli/internal/images/images.go (4)
  • ServiceNames (19-24)
  • RefForService (30-36)
  • InspectID (98-104)
  • RepoPrefix (15-15)
cli/internal/images/images.go (2)
cli/internal/verify/identity.go (2)
  • RegistryHost (27-27)
  • ImageRepoPrefix (30-30)
cli/internal/docker/client.go (1)
  • RunCmd (116-125)
🪛 GitHub Actions: Dependency Review
cli/go.mod

[error] 1-1: Dependency review detected incompatible licenses. Examples: github.com/alfatraining/structtag@1.0.0 (BSD-3-Clause AND CC-BY-3.0), github.com/denis-tingaikin/go-header@0.5.0 (GPL-3.0 AND GPL-3.0-only), github.com/fatih/structtag@1.2.0 (BSD-3-Clause AND CC-BY-3.0), github.com/ldez/structtags@0.6.1 (GPL-3.0 AND GPL-3.0-only), github.com/leonklingele/grouper@1.1.2 (GPL-3.0 AND GPL-3.0-only), github.com/xen0n/gosmopolitan@1.3.0 (GPL-1.0-or-later AND GPL-3.0 AND GPL-3.0-only), github.com/golangci/golangci-lint/v2@2.11.3 (GPL-3.0).

🔇 Additional comments (21)
.pre-commit-config.yaml (2)

76-82: Hook depends on the tool directive in go.mod.

The go -C cli tool golangci-lint run command requires the tool directive added in go.mod. If the license compliance issue is resolved by removing that directive, this hook entry will need to revert to the previous approach (e.g., ensuring golangci-lint is installed externally and using bash -c 'cd cli && golangci-lint run').

If the tool directive remains, this change correctly follows the go -C cli pattern. Based on learnings: "For CLI Go commands requiring module root as cwd, use go -C cli (changes directory internally) instead of cd cli."


84-98: LGTM!

The go vet and go test hooks correctly use go -C cli to run commands in the CLI module directory without changing the shell's working directory.

CLAUDE.md (2)

60-68: LGTM!

The documentation accurately explains the go -C cli pattern and the golangci-lint tool registration. The note about avoiding cd cli is helpful for maintaining consistent shell behavior.


135-135: LGTM!

The images submodule is correctly added to the internal directory listing, reflecting the new package introduced in this PR.

cli/internal/images/images.go (4)

19-24: Note: ServiceNames returns a new slice each call (by design).

The function returns a fresh slice literal on each invocation, which is intentional to prevent callers from mutating a shared slice. This is validated by TestServiceNames/"returns fresh slice" in the test file. Good defensive design.


30-36: LGTM!

RefForService correctly prioritizes digest-pinned references when a verified digest exists, falling back to tag-based references. The empty-string check on the digest value prevents malformed refs like repo@.


58-66: LGTM!

ListLocal and InspectID properly delegate to docker.RunCmd and handle the output parsing. The --format template ensures consistent output across Docker versions. InspectID correctly trims whitespace from the output.

Also applies to: 98-104


71-94: Use of strings.SplitSeq is compatible with Go 1.26 requirement.

strings.SplitSeq was added in Go 1.24 and is available in Go 1.26+. The parsing logic correctly handles CRLF normalization, skips empty lines and malformed rows, and properly filters to only SynthOrg images by RepoPrefix.

cli/cmd/update.go (1)

19-19: LGTM!

The import of the new images package enables the consolidation of image reference logic.

cli/internal/images/images_test.go (3)

159-164: Excellent test case documenting the bug fix.

The "digest-only image (no tag) -- the bug this fixes" test case directly validates the core issue this PR addresses: ensuring images pulled by digest (with <none> tag) are correctly discovered.


238-270: LGTM!

The fuzz test validates key invariants:

  1. Output always starts with RepoPrefix + svc
  2. Separator is always @ or :
  3. @ is used iff digest is non-empty

This provides strong guarantees about RefForService behavior across arbitrary inputs.


35-43: Good defensive test for slice independence.

Testing that ServiceNames returns independent slices prevents a subtle bug where callers could accidentally mutate shared state.

cli/cmd/update_cleanup.go (3)

70-93: LGTM!

The refactored listNonCurrentImages now uses the centralized images.ListLocal for image discovery, which correctly finds both tagged and digest-only images. The iteration over images.LocalImage struct fields is cleaner than parsing raw output inline.


126-149: LGTM!

collectCurrentImageIDs correctly:

  1. Gets service names from images.ServiceNames
  2. Builds references via images.RefForService (handling digest vs tag)
  3. Resolves IDs via images.InspectID
  4. Stores both full (sha256:...) and short (12-char) IDs for matching

This ensures cleanup won't accidentally delete current images regardless of how Docker reports IDs.


97-100: LGTM!

The display prefix derivation using strings.TrimPrefix(repo, images.RepoPrefix) followed by re-adding "synthorg-" creates readable output like synthorg-backend:0.4.6 while using the centralized constant.

cli/cmd/update_health_test.go (1)

6-6: LGTM!

The test correctly imports and calls images.RefForService instead of the removed local helper. The test cases validate the function behaves correctly from the command layer's perspective.

Also applies to: 111-111

cli/internal/diagnostics/collect_test.go (1)

389-458: LGTM! Test correctly validates the compose-ref-first priority.

The test accurately replicates the inline priority logic from checkImages: compose ref takes precedence, then falls back to images.RefForService which handles digest-vs-tag selection. The test cases comprehensively cover compose-ref priority, digest fallback, tag fallback, and service mismatch scenarios.

cli/cmd/update_health.go (1)

120-134: LGTM! Clean consolidation of image detection logic.

The refactoring correctly delegates to the centralized images package:

  • images.ServiceNames for service enumeration (including conditional sandbox)
  • images.RefForService for digest-vs-tag reference construction
  • images.InspectID for local image inspection

The context cancellation handling (lines 126-130) is appropriately preserved to avoid false positives when Docker is unresponsive.

cli/internal/diagnostics/collect.go (3)

311-324: LGTM! Clean refactoring to centralized image utilities.

The checkImages function correctly delegates to the images package:

  • Service enumeration via images.ServiceNames(sandbox)
  • Compose-ref-first priority with images.RefForService fallback
  • Image inspection via images.InspectID

The priority logic (compose ref > verified digest > tag) is preserved and now consistent with other commands.


338-355: Good documentation and safe path handling.

The updated doc comment clearly explains the intentional silent error handling for diagnostics robustness.

The removal of the explicit .. path traversal check is safe because composePath is always constructed internally via checkComposeFile which uses filepath.Join(dataDir, name) with name from the hardcoded composeFileNames slice and dataDir from config.SecurePath. The filepath.Clean call provides additional normalization.


367-379: LGTM! Consistent use of centralized prefix constant.

Using images.RepoPrefix instead of a local constant ensures consistency across all image-handling code paths. The suffix extraction logic correctly handles both tag (:) and digest (@) separators.

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 22, 2026
Aureliolo and others added 4 commits March 22, 2026 16:39
Docker's --filter "reference=..." misses digest-only images (no tag),
causing `synthorg uninstall` and `synthorg cleanup` to skip images like
the sandbox that were pulled by digest.

Extract shared `internal/images` package with:
- ListLocal: lists ALL local SynthOrg images (tagged + digest-only)
- RefForService: single source of truth for image ref construction
- ServiceNames: canonical service name list
- InspectID: shared docker image inspect wrapper

Eliminates duplicated image constants and logic across update_cleanup,
update_health, diagnostics, and update commands.

Also standardizes all Go tooling to use `go -C cli`:
- Add golangci-lint as `tool` directive in go.mod
- Replace all subshell and bash-c directory-change patterns
- Update pre-commit hooks, CLAUDE.md, and examples

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add images package to CLAUDE.md Package Structure section
- Remove duplicate FuzzRefForService from cmd package (canonical home
  is internal/images)
- Derive display prefix from images.RepoPrefix instead of hardcoding
- Remove misleading path traversal guard, add intentional-fallback doc
- Add converse fuzz invariant (no @ when digest is empty)

Pre-reviewed by 4 agents, 6 findings addressed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… review

CC-BY-3.0 and CC-BY-4.0 are permissive (attribution-only) and broadly
compatible -- added to the global allow-licenses list.

golangci-lint and its GPL-licensed linter deps are dev-only tool
dependencies (go.mod `tool` directive) that never get compiled into the
SynthOrg binary. GPL copyleft does not apply. Added per-package
exemptions since the action cannot distinguish tool vs runtime deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update CLAUDE.md CI section: dep review allows weak-copyleft + GPL
  exemptions, not "permissive only"
- Update CLAUDE.md pre-commit hooks: golangci-lint and go vet now run
  at pre-commit stage (not just pre-push)
- Restore 2 dropped test cases in TestDiagnosticImageRefPriority
  (nil maps, empty digest value)
- Rename local var `images` to `result` in parseImageList to avoid
  shadowing the package identifier

Pre-reviewed by 3 local agents + 2 external reviewers, 4 findings fixed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Aureliolo Aureliolo merged commit 712a785 into main Mar 22, 2026
39 checks passed
@Aureliolo Aureliolo deleted the fix/fix-cli-image-finding branch March 22, 2026 15:53
Aureliolo added a commit that referenced this pull request Mar 22, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.4.7](v0.4.6...v0.4.7)
(2026-03-22)


### Features

* add system user for CLI-to-backend authentication
([#710](#710))
([dc6bd3f](dc6bd3f))
* dev channel builds with incremental pre-releases between stable
releases ([#715](#715))
([0e8a714](0e8a714))
* replace hardcoded name pools with Faker multi-locale name generation
([#714](#714))
([5edc6ec](5edc6ec))


### Bug Fixes

* dev-release tag creation, dependabot coverage, go -C cli convention
([#730](#730))
([7634843](7634843))
* improve name generation step UX and fix sentinel expansion bug
([#739](#739))
([f03fd05](f03fd05))
* settings page UX polish -- toggle bug, source badges, form
improvements ([#712](#712))
([d16a0ac](d16a0ac))
* switch dev tags to semver and use same release pipeline as stable
([#729](#729))
([4df6b9b](4df6b9b)),
closes [#713](#713)
* unify CLI image discovery and standardize Go tooling
([#738](#738))
([712a785](712a785))
* use PAT in dev-release workflow to trigger downstream pipelines
([#716](#716))
([d767aa3](d767aa3))


### CI/CD

* bump astral-sh/setup-uv from 7.4.0 to 7.6.0 in
/.github/actions/setup-python-uv in the minor-and-patch group
([#731](#731))
([7887257](7887257))
* bump the minor-and-patch group with 3 updates
([#735](#735))
([7cd253a](7cd253a))
* bump wrangler from 4.75.0 to 4.76.0 in /.github in the minor-and-patch
group ([#732](#732))
([a6cafc7](a6cafc7))
* clean up all dev releases and tags on stable release
([#737](#737))
([8d90f5c](8d90f5c))


### Maintenance

* bump the minor-and-patch group across 2 directories with 2 updates
([#733](#733))
([2b60069](2b60069))
* bump the minor-and-patch group with 3 updates
([#734](#734))
([859bc25](859bc25))
* fix dependabot labels and add scope tags
([#736](#736))
([677eb15](677eb15))
* remove redundant pytest.mark.timeout(30) markers
([#740](#740))
([9ec2163](9ec2163))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant