Skip to content

refactor(cli): single source of truth for DHI image tags + Renovate manager#1723

Merged
Aureliolo merged 5 commits into
mainfrom
chore/dhi-tag-source-of-truth
May 3, 2026
Merged

refactor(cli): single source of truth for DHI image tags + Renovate manager#1723
Aureliolo merged 5 commits into
mainfrom
chore/dhi-tag-source-of-truth

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

Hoists the DHI image-tag literals (dhi.io/postgres:18-debian13, dhi.io/nats:2.12-debian13) into a single source of truth so a future Renovate bump propagates to every call site instead of a single line.

  • cli/internal/config/state.go keeps the canonical DefaultPostgresImageTag / DefaultNATSImageTag constants and now carries // renovate: datasource=docker depName=dhi.io/{postgres,nats} annotations
  • cli/internal/verify/dhi.go package vars derive from those constants instead of duplicating the literal
  • cli/cmd/start.go thirdPartyImages() builds image refs from the constants
  • cli/internal/verify/dhi_test.go, cli/cmd/init_postgres_test.go, cli/internal/compose/generate_test.go assertions reference the constants (so a Renovate bump that only updates one location fails the test instead of silently dropping verification)
  • cli/cmd/update_test.go left alone — those fixtures are intentional historical compose.yml snapshots used to test upgrade transitions, not current state
  • renovate.json adds a customManager for the new annotations on Default*ImageTag so Renovate watches the constants, grouped under the same depName=dhi.io/{nats,postgres} as the existing dhiPinnedIndexDigests map manager — both bump together
  • Doc references in cli/CLAUDE.md, docs/reference/cli-persistence-backends.md, README.md now point at the SoT constant location instead of duplicating the literal version, so prose stays valid across future bumps

Why

Unblocks #1698 (Container deps update). That PR's Renovate run only updated the dhiPinnedIndexDigests map line in cli/internal/verify/dhi.go, leaving 9 other call sites still hardcoding 2.12-debian13. TestDHIPinnedIndexDigest and the cross-platform CLI Test jobs failed as a result. With this refactor, every literal lives in one place; the Renovate update on #1698 (or its replacement) will sweep all consumers in one diff.

Validation plan

After this merges:

  1. Comment @renovatebot rebase on PR chore: Update Container dependencies #1698
  2. Confirm the resulting diff bumps all dhi.io/nats:2.12-debian13 references (not just one map line)
  3. CI on chore: Update Container dependencies #1698 should now go green (CLI tests included)

If any location is still missed, the Renovate regex needs another iteration — but the test gate (TestDHIPinnedIndexDigest deriving its key from the SoT constant) makes any drift a loud test failure rather than silent verification loss at runtime.

Test plan

  • go -C cli vet ./...
  • go -C cli build ./...
  • go -C cli test ./... — full suite passes, including TestDHIPinnedIndexDigest and TestParseDHIRef after the constant-reference refactor
  • Pre-push gate: golangci-lint + go vet + go test all green

Review coverage

Pre-reviewed by 4 agents:

  • docs-consistency — 4 findings, all addressed (docs now reference the SoT instead of the literal)
  • comment-quality-rot — clean (the doc-block in dhi.go and the test rationale comment in dhi_test.go explain WHY, not origin/review context; commit-body #1698 reference is justificatory git-log venue)
  • go-reviewer — clean / APPROVE (no verifyconfigverify cycle, init-order safe, drift detection enforced at test time)
  • go-conventions-enforcer — clean (file sizes within budget, vars are correctly vars not consts because Configure() mutates them at runtime)

@github-actions
Copy link
Copy Markdown
Contributor

ghost commented May 3, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4520ccdb-ccc3-4c80-9bf6-f2dff8c5f4f4

📥 Commits

Reviewing files that changed from the base of the PR and between 94f89ad and f844820.

📒 Files selected for processing (1)
  • .claude/skills/review-dep-pr/SKILL.md

Walkthrough

Updated runtime and test code to derive DHI Postgres and NATS image tags from cli/internal/config/state.go (DefaultPostgresImageTag and DefaultNATSImageTag) instead of hardcoded tag strings. Documentation and CLI help were updated to reference the config constants. Tests and compose-generation assertions were adjusted to use those constants. Added inline // renovate: metadata on the constants and a Renovate customManagers regex entry to track them. No exported APIs or runtime behavior values were changed.

Suggested labels

type:infra, dependencies

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: refactoring DHI image tags into a single source of truth and adding Renovate manager support.
Description check ✅ Passed The description is thorough and directly related to the changeset, explaining the rationale, validation plan, and review coverage for consolidating image tag constants and Renovate integration.
Docstring Coverage ✅ Passed Docstring coverage is 40.00% which is sufficient. The required threshold is 40.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


Review rate limit: 2/5 reviews remaining, refill in 34 minutes and 52 seconds.

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

@Aureliolo Aureliolo temporarily deployed to cloudflare-preview May 3, 2026 09:50 — with GitHub Actions Inactive
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 centralizes the default image tags for Postgres and NATS into constants within cli/internal/config/state.go and configures a Renovate custom manager to keep them updated. It also updates various tests and documentation to reference these new constants. A critical issue was identified in cli/cmd/start.go where the thirdPartyImages function ignores user-provided image tag overrides, potentially leading to security verification bypasses when custom tags are used.

Comment thread cli/cmd/start.go
Comment on lines 660 to 665
if state.PersistenceBackend == "postgres" {
images = append(images, thirdPartyImage{"postgres", "dhi.io/postgres:18-debian13"})
images = append(images, thirdPartyImage{"postgres", "dhi.io/postgres:" + config.DefaultPostgresImageTag})
}
if state.BusBackend == "nats" {
images = append(images, thirdPartyImage{"nats", "dhi.io/nats:2.12-debian13"})
images = append(images, thirdPartyImage{"nats", "dhi.io/nats:" + config.DefaultNATSImageTag})
}
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.

high

The thirdPartyImages function now hardcodes the use of config.DefaultPostgresImageTag and config.DefaultNATSImageTag, which ignores any user-provided overrides in state.PostgresImageTag or state.NATSImageTag (e.g., set via environment variables or config.json).

This is a significant issue because thirdPartyImages is used in hasDHIDigests to determine if verification can be skipped based on the cache. If an operator provides a custom image tag, the CLI will check the cache for the default image tag instead. If the default tag is cached, the CLI will proceed to pull and run the custom image without any verification, potentially bypassing security checks. The function should respect the values in the state object, falling back to the defaults only when the state fields are empty.

	if state.PersistenceBackend == "postgres" {
		tag := state.PostgresImageTag
		if tag == "" {
			tag = config.DefaultPostgresImageTag
		}
		images = append(images, thirdPartyImage{"postgres", "dhi.io/postgres:" + tag})
	}
	if state.BusBackend == "nats" {
		tag := state.NATSImageTag
		if tag == "" {
			tag = config.DefaultNATSImageTag
		}
		images = append(images, thirdPartyImage{"nats", "dhi.io/nats:" + tag})
	}

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 3, 2026
Aureliolo added 3 commits May 3, 2026 11:55
…anager

Default*ImageTag in cli/internal/config/state.go is now the only place
the postgres + nats DHI tags are spelled out. verify/dhi.go vars,
start.go's third-party image list, and the dhi_test.go fixtures all
derive from it. Update_test.go fixtures stay literal because they
represent historical compose.yml snapshots used to test upgrade
transitions, not current state.

Adds a Renovate customManager that watches the new // renovate:
annotations on Default*ImageTag so a future tag bump propagates to
both the constant and the dhiPinnedIndexDigests map line in one PR
(grouped under depName=dhi.io/{nats,postgres}). The previous PR
#1698 missed 9 call sites because the existing manager only updated
the digest map line.
cli/CLAUDE.md (Persistence Backends + env-vars), README.md (intro), and
docs/reference/cli-persistence-backends.md were each duplicating the
literal dhi.io/postgres:18-debian13 tag. Replaced with prose pointing
at DefaultPostgresImageTag in cli/internal/config/state.go (Renovate-
managed) so the prose stays valid across future tag bumps.

Pre-reviewed by 4 agents (docs-consistency, comment-quality-rot,
go-reviewer, go-conventions-enforcer); 4 docs-consistency findings
addressed.
… merge

Adds a new mandatory 'Approve with rationale' step shared by all three
merge paths (Merge as-is, Improve and merge, Fix CI and merge). Every
merge now goes through gh pr review NN --approve --body ... first,
recording the bump-type decision, a 2-4 bullet changelog digest splitting
relevant vs reviewed-but-not-relevant items, and any deferred follow-ups.
Without this, merged-by-Renovate PRs leave no audit trail of why they
were accepted; squash messages get rewritten by maintainers and don't
surface in the PR conversation thread, so the approval review is the
canonical venue.
Copy link
Copy Markdown
Contributor

@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 (1)
.claude/skills/review-dep-pr/SKILL.md (1)

358-370: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify that approval applies to lockfile-only and wave-based merge flows.

The lockfile-only batch description (line 358) and wave-based parallel description (line 361) both describe merging PRs but don't explicitly reference the approval step added below at line 368. While line 368 states "MANDATORY before any merge" (which should apply universally), line 370's phrasing "Every merge path below funnels through this step first" creates ambiguity—the lockfile-only and wave-based flows are described above that line.

A reader executing the lockfile-only flow might be unsure whether approval is required or if those PRs skip the approval step.

📝 Suggested clarifications

Option 1 (preferred): Add a brief parenthetical in the lockfile-only and wave-based descriptions:

-Lockfile-only batch (Phase 7 skipped). When Phase 6 detected only lockfile-only overlaps (per the Phase 5 trigger rule, Phase 7 was skipped), there is no user-supplied strategy to apply. Use the implicit lockfile-race default: treat all PRs in the batch as parallel-safe; merge each eligible PR immediately (or queue with `--auto` if a final required check is still pending);
+Lockfile-only batch (Phase 7 skipped). When Phase 6 detected only lockfile-only overlaps (per the Phase 5 trigger rule, Phase 7 was skipped), there is no user-supplied strategy to apply. Use the implicit lockfile-race default: treat all PRs in the batch as parallel-safe; merge each eligible PR immediately (or queue with `--auto` if a final required check is still pending, following the "Merge as-is" flow including approval);

And for the wave-based description:

-- **Wave-based parallel**: process Wave 1 PRs first, all with `--auto`/immediate as appropriate, then for each subsequent wave wait for prior merges to land, trigger a rebase on the next wave's PRs, wait for CI, then merge.
+- **Wave-based parallel**: process Wave 1 PRs first (via the "Merge as-is" flow including approval), all with `--auto`/immediate as appropriate, then for each subsequent wave wait for prior merges to land, trigger a rebase on the next wave's PRs, wait for CI, then merge.

Option 2: Change "below" to make the scope universal:

-**Every merge path below funnels through this step first.**
+**Every merge operation in this phase funnels through this step first.**
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/skills/review-dep-pr/SKILL.md around lines 358 - 370, The
documentation is ambiguous about whether the "Approve with rationale (MANDATORY
before any merge)" step applies to the "Lockfile-only batch" and "Wave-based
parallel" flows; update the text so the approval requirement is explicit for
those paths by either adding a short parenthetical to the "Lockfile-only batch"
and "Wave-based parallel" paragraphs (e.g., "(approve with rationale before
merging per 'Approve with rationale (MANDATORY before any merge)')") or by
changing the sentence "Every merge path below funnels through this step first"
to a universal phrasing like "Every merge path in this document funnels through
this step first," and ensure the header "Approve with rationale (MANDATORY
before any merge)" remains immediately before the approval instructions so
readers see it applies to all flows.
🤖 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 @.claude/skills/review-dep-pr/SKILL.md:
- Around line 358-370: The documentation is ambiguous about whether the "Approve
with rationale (MANDATORY before any merge)" step applies to the "Lockfile-only
batch" and "Wave-based parallel" flows; update the text so the approval
requirement is explicit for those paths by either adding a short parenthetical
to the "Lockfile-only batch" and "Wave-based parallel" paragraphs (e.g.,
"(approve with rationale before merging per 'Approve with rationale (MANDATORY
before any merge)')") or by changing the sentence "Every merge path below
funnels through this step first" to a universal phrasing like "Every merge path
in this document funnels through this step first," and ensure the header
"Approve with rationale (MANDATORY before any merge)" remains immediately before
the approval instructions so readers see it applies to all flows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9d1a8a69-8198-4085-a52a-50cc4192937c

📥 Commits

Reviewing files that changed from the base of the PR and between 2060f7c and 20ad458.

📒 Files selected for processing (11)
  • .claude/skills/review-dep-pr/SKILL.md
  • README.md
  • cli/CLAUDE.md
  • cli/cmd/init_postgres_test.go
  • cli/cmd/start.go
  • cli/internal/compose/generate_test.go
  • cli/internal/config/state.go
  • cli/internal/verify/dhi.go
  • cli/internal/verify/dhi_test.go
  • docs/reference/cli-persistence-backends.md
  • renovate.json
📜 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). (11)
  • GitHub Check: Lighthouse Site
  • GitHub Check: Build Web Assets (melange)
  • GitHub Check: CLI Test (macos-latest)
  • GitHub Check: CLI Test (ubuntu-latest)
  • GitHub Check: CLI Test (windows-latest)
  • GitHub Check: CLI Lint
  • GitHub Check: CLI Bench Regression
  • GitHub Check: Build Preview
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📓 Path-based instructions (11)
cli/**/*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Implement four hint tiers (HintError, HintNextStep, HintTip, HintGuidance) with visibility rules per hints mode (always/auto/never); HintError and HintNextStep shown unless quiet; HintTip deduplicates within session; HintGuidance invisible in default auto mode

Files:

  • cli/internal/verify/dhi_test.go
  • cli/internal/compose/generate_test.go
  • cli/cmd/start.go
  • cli/cmd/init_postgres_test.go
  • cli/internal/config/state.go
  • cli/internal/verify/dhi.go
cli/internal/compose/**/*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Every generated compose.yml includes one-shot data-init helper that chowns named volumes to non-root owner (65532:65532 for backend/NATS, 70:70 mode 0700 for Postgres) before stateful services start; Postgres/NATS declare depends_on: data-init: condition: service_completed_successfully

Files:

  • cli/internal/compose/generate_test.go
cli/internal/{compose,config}/**/*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Port layout: 3000 web / 3001 backend / 3002 postgres / 3003 NATS client; generate.go validates port collisions across all enabled services

Files:

  • cli/internal/compose/generate_test.go
  • cli/internal/config/state.go
cli/cmd/**/*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

All CLI commands accept persistent flags with precedence: flag > env var > config > default (--data-dir, --skip-verify, --quiet, --verbose, --no-color, --plain, --json, --yes, --help-all)

Use exit codes: 0 (success), 1 (runtime error), 2 (usage error), 3 (unhealthy), 4 (unreachable), 10 (updates available)

Files:

  • cli/cmd/start.go
  • cli/cmd/init_postgres_test.go
cli/**/*.{sh,bash,md}

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Use go -C cli instead of bare cd cli in Bash tools to avoid poisoning cwd for subsequent calls; use subshell cd (bash -c "cd cli && <cmd>" or (cd cli && <cmd>)) as sanctioned escape hatch for external tools lacking -C flag

Pass -run='^$' when capturing clean benchmark snapshots to skip Test*, Example*, and Fuzz* seed-corpus functions and execute only Benchmark* functions

Files:

  • cli/CLAUDE.md
cli/**/*.{sh,bash,yml,yaml,md}

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Run bash -c "cd cli && golangci-lint run" for linting since golangci-lint lacks a -C flag (requires scripts/install_cli_tools.sh to be run first)

Files:

  • cli/CLAUDE.md
cli/cmd/init*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Use --persistence-backend sqlite (default, single-node) for in-process SQLite under volume synthorg-data; use --persistence-backend postgres for dhi.io/postgres DHI service on port 3002 (override via --postgres-port) backed by volume synthorg-pgdata

Files:

  • cli/cmd/init_postgres_test.go
cli/internal/config/**/*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Define SYNTHORG_* env vars without corresponding flags in four buckets: Backend/channel overrides, Image/registry overrides (disables verification), Timeouts and retry tuning, Byte caps and ports

Backend auto-wire precedence: when both SYNTHORG_DATABASE_URL and SYNTHORG_DB_PATH present, SYNTHORG_DATABASE_URL wins (Postgres initialized; SQLite path ignored); malformed URL raises loudly at startup rather than silently falling back

Files:

  • cli/internal/config/state.go
cli/internal/{config,images}/**/*.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Overriding any of registry_host, image_repo_prefix, dhi_registry, postgres_image_tag, or nats_image_tag disables image signature + SLSA verification for that invocation only and writes stderr warning on every invocation (not suppressed by --quiet or --json)

Files:

  • cli/internal/config/state.go
cli/internal/config/state.go

📄 CodeRabbit inference engine (cli/CLAUDE.md)

Keep DefaultPostgresImageTag and DefaultNATSImageTag constants in cli/internal/config/state.go current via Renovate customManager watching // renovate: annotations

Files:

  • cli/internal/config/state.go
docs/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

docs/**/*.md: Use D2 (\``d2) for architecture diagrams, nested container layouts, and complex entity relationships, rendered at build time via mkdocs-d2-plugin with dagre layout Use Mermaid (```mermaid) for flowcharts, sequence diagrams, simple hierarchies, and pipelines, rendered client-side via pymdownx.superfences Use Markdown tables for grid/matrix data that is semantically tabular, not for diagrams Never use ```text` blocks with ASCII/Unicode box-drawing characters for diagrams; use D2 or Mermaid instead

Files:

  • docs/reference/cli-persistence-backends.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-03T09:56:28.042Z
Learning: Run `scripts/install_cli_tools.sh` once per development machine to install external `golangci-lint` binary (not a Go `tool` directive) to keep `cli/go.mod` free of GPL-3.0 transitive dependencies
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-03T09:56:28.042Z
Learning: Organize CLI package structure as: `cmd/` for Cobra commands (init, start, stop, status, logs, doctor, update, cleanup, wipe, config, etc.), global options, exit codes, env var constants; `internal/` for version, config, docker, compose, health, diagnostics, images, selfupdate, completion, ui, verify
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-03T09:56:28.042Z
Learning: Atlas migrations run on every backend connection; Atlas binary baked into backend image at /usr/local/bin/atlas from arigaio/atlas:latest-community-distroless pinned by multi-arch manifest digest
🔇 Additional comments (14)
cli/internal/compose/generate_test.go (1)

335-335: Good SoT alignment in compose test assertion.

Using config.DefaultPostgresImageTag here keeps this regression test in sync with the canonical tag source and avoids future hardcoded drift.

README.md (1)

59-59: README update is consistent with the code refactor.

This correctly documents that the Postgres tag is pinned via the config constant instead of a hardcoded literal.

cli/cmd/init_postgres_test.go (1)

276-277: Nice removal of hardcoded Postgres tag in lifecycle test.

This keeps compose assertions coupled to the canonical default image tag and reduces maintenance drift.

cli/cmd/start.go (1)

661-665: Correctly centralized DHI image tag usage in start flow.

Deriving both refs from config defaults here closes the drift class where verification/pull targets diverge from config-managed defaults.

docs/reference/cli-persistence-backends.md (1)

33-33: Doc wording now matches the new tag source-of-truth model.

Good update calling out DefaultPostgresImageTag and Renovate ownership explicitly.

cli/internal/verify/dhi.go (1)

25-25: Good consolidation of verifier default tags.

Sourcing DHI default tags from config.Default*ImageTag removes duplicate literals and keeps verification defaults aligned with config-managed values.

Also applies to: 51-57

renovate.json (1)

211-220: Renovate manager addition looks correct and targeted.

Matching the // renovate: annotation + Default...ImageTag constant pattern in state.go is the right automation hook for this SoT change.

cli/internal/verify/dhi_test.go (1)

7-7: Great test hardening around tag/digest coupling.

Using the config defaults in parse and pinned-digest tests makes drift failures explicit when tags and pinned index digests get out of sync.

Also applies to: 23-34, 120-124, 124-124, 132-132

cli/CLAUDE.md (2)

78-78: LGTM! Documentation accurately reflects the new single source of truth pattern.

The documentation correctly explains that SYNTHORG_POSTGRES_IMAGE_TAG and SYNTHORG_NATS_IMAGE_TAG default to the constants in cli/internal/config/state.go and notes that Renovate keeps them current via the // renovate: annotations.


127-127: LGTM! Correct reference to the canonical constant.

Replacing the hardcoded dhi.io/postgres:18-debian13 with a reference to DefaultPostgresImageTag in cli/internal/config/state.go aligns with the PR's single source of truth objective.

cli/internal/config/state.go (1)

133-139: LGTM! Renovate annotations correctly formatted.

The // renovate: annotations follow the regex pattern defined in renovate.json and will enable automated dependency updates for the DHI image tags. The format correctly includes:

  • datasource=docker for Docker registry lookups
  • depName with full image paths (dhi.io/postgres, dhi.io/nats)
  • Constants positioned immediately after their annotations for regex matching

As per coding guidelines, this establishes the single source of truth for DHI image tags with Renovate automation.

.claude/skills/review-dep-pr/SKILL.md (3)

368-394: Excellent addition of audit trail requirement.

This mandatory approval step with structured rationale is a strong governance practice for dependency updates. The three-part format (decision + changelog digest split into relevant/reviewed + follow-ups) ensures future reviewers and bisects can understand why each update was accepted, not just that it merged.

The guidance to use --body-file for longer rationales and the explicit prohibition against collapsing into squash messages (line 393-394) are both practical and correct.


404-447: Approval step consistently integrated across all merge paths.

The approval requirement is correctly positioned in all three flows (Merge as-is, Improve and merge, Fix CI and merge) and the additional context requirements for "Improve and merge" (line 437: describe improvements) and "Fix CI and merge" (line 446: describe failure + fix) appropriately extend the base rationale format.

Step renumbering is accurate throughout.


465-465: Rules section properly reinforces the approval requirement.

The new rule at line 465 comprehensively documents the mandatory approval step, explains the required rationale content (decision + digest + follow-ups), and clearly articulates why skipping approval is problematic (no audit trail, squash messages get rewritten). This provides good reinforcement for operators who might skip to the rules section.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 3, 2026
…ll merge paths

Removes ambiguity flagged by reviewer: 'Every merge path below funnels
through this step first' could be read as scoping only to the three
per-PR action sub-sections (Merge as-is / Improve and merge / Fix CI and
merge), bypassing the Phase 8 strategy paths (Lockfile-only batch /
Wave-based parallel / Strict sequential / Combine into one PR / Defer
the conflicting subset). Replaces with explicit enumeration of all five
strategy paths plus the three per-PR action sections, and tightens the
parallel rule entry at the bottom for symmetry.
Copy link
Copy Markdown
Contributor

@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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/skills/review-dep-pr/SKILL.md:
- Around line 370-385: The wording is ambiguous about "one-paragraph" vs "2–4
bullets" for the rationale; update the instruction around the gh pr review
command so it explicitly requires three labeled parts (Decision, Changelog
digest, Follow-ups) and allows a multiline review body: keep "Decision" as one
sentence, require "Changelog digest" to be a short paragraph that contains 2–4
clearly marked bullets (allow actual newline bullets) and then a "Follow-ups"
line; modify the text around the gh pr review example (the literal gh pr review
<number> --approve --body "<rationale>") to note that the CLI body may be
multiline (or recommend piping from a heredoc/file) and reference the labels
"Decision", "Changelog digest", and "Follow-ups" so reviewers implement the
consistent format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f5ac67ed-91c2-484a-9206-f4b5afa52f89

📥 Commits

Reviewing files that changed from the base of the PR and between 20ad458 and 94f89ad.

📒 Files selected for processing (1)
  • .claude/skills/review-dep-pr/SKILL.md
📜 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). (10)
  • GitHub Check: Build Web Assets (melange)
  • GitHub Check: CLI Test (windows-latest)
  • GitHub Check: CLI Test (ubuntu-latest)
  • GitHub Check: CLI Bench Regression
  • GitHub Check: CLI Test (macos-latest)
  • GitHub Check: Lighthouse Site
  • GitHub Check: Build Preview
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (python)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-03T10:07:06.748Z
Learning: In the CLI package structure, organize code into `cli/cmd/` for Cobra commands (init, start, stop, status, logs, doctor, update, cleanup, wipe, config, etc.) and global options, and `cli/internal/` for version, config, docker, compose, health, diagnostics, images, selfupdate, completion, ui, and verify logic
🔇 Additional comments (2)
.claude/skills/review-dep-pr/SKILL.md (2)

368-393: Strong auditability improvement in merge workflow.

Good addition making approval rationale mandatory before merge, including --auto paths and a --body-file fallback for long content.


404-447: Nice propagation of the mandatory-approval gate across all merge paths.

The added steps in each execution flow and the explicit rule-level restatement reduce policy drift and make the process enforceable.

Also applies to: 465-465

Comment thread .claude/skills/review-dep-pr/SKILL.md Outdated
…tterns

Resolves a contradiction the reviewer flagged: the prose called for a
'one-paragraph changelog digest' but the structure below required three
labeled parts (Decision / Changelog digest / Follow-ups) with 2-4 bullets
inside the digest. The two descriptions disagreed on shape.

Now: prose explicitly calls out a three-part structured rationale, each
part is required to be prefixed with its literal label so reviewers
across PRs produce a consistent format, and the gh pr review example
is expanded with three concrete invocation patterns: heredoc piped to
the body-file stdin form, body-file with a temp file path, and the
inline body string form reserved for the rare one-line case. The
earlier note about multi-line shell-quoting friendliness is folded
into the new patterns block.
@Aureliolo Aureliolo merged commit 57980a2 into main May 3, 2026
22 of 24 checks passed
@Aureliolo Aureliolo deleted the chore/dhi-tag-source-of-truth branch May 3, 2026 10:13
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview May 3, 2026 10:13 — with GitHub Actions Inactive
Aureliolo pushed a commit that referenced this pull request May 3, 2026
<!-- HIGHLIGHTS_START -->
## Highlights

> _AI-generated summary (model: `openai/gpt-4.1-mini` via GitHub
Models). Commit-based changelog below._

### What you'll notice
- Frontend and UX polishing improves user interface responsiveness and
visual consistency.
- API hygiene and validation enhancements provide smoother and more
reliable interactions.

### What's new
- Introduced typed-boundary helpers enabling better type safety and
parse_typed workflows.
- Added codebase-audit skill prompt tuning for improved project
auditing.

### Under the hood
- Eliminated flaky tests caused by module-level state for more stable
test outcomes.
- Unified image tag management under CLI and Renovate for consistent
dependency updates.
- Added cross-PR file-overlap analysis to the review dependency pull
request skill.
- Updated multiple dependencies including Python, Web, CLI, and
container libraries.
- Improved CI tooling and lock file maintenance for better build
reliability.

<!-- HIGHLIGHTS_END -->

:robot: I have created a release *beep* *boop*
---


##
[0.7.8](v0.7.7...v0.7.8)
(2026-05-03)


### Features

* **api:** typed-boundary helper + codebase-audit skill prompt tuning
([#1712](#1712))
([40ee65b](40ee65b))
* **boundary:** RFC
[#1711](#1711) Phases 2 + 3
— typed boundaries via parse_typed
([#1720](#1720))
([7b9f409](7b9f409))


### Bug Fixes

* **api:** audit cleanup B -- API hygiene & validation
([#1719](#1719))
([3d790d9](3d790d9))
* audit cleanup C - persistence, concurrency & data integrity
([#1708](#1708))
([#1717](#1717))
([bcce097](bcce097))
* **test:** exterminate xdist-flaky tests with module-level state
([#1713](#1713))
([#1721](#1721))
([8d258dd](8d258dd))
* **web:** audit cleanup E -- frontend & UX polish
([#1710](#1710))
([#1718](#1718))
([3a3591a](3a3591a))


### Refactoring

* **cli:** single source of truth for DHI image tags + Renovate manager
([#1723](#1723))
([57980a2](57980a2))


### Documentation

* audit cleanup D -- public-facing & docs sync
([#1709](#1709))
([#1715](#1715))
([ade03b7](ade03b7))


### Tests

* **engine:** make TestDrainTimeout deterministic + preserve subclass
type in [@Ontology](https://github.com/ontology)_entity
([#1729](#1729))
([b00fb05](b00fb05))


### CI/CD

* Update CI tool dependencies
([#1703](#1703))
([355a9ff](355a9ff))


### Maintenance

* add cross-PR file-overlap analysis to review-dep-pr skill
([#1722](#1722))
([3861d8a](3861d8a))
* **ci:** unify apko-version under workflow env so Renovate manages it
everywhere ([#1724](#1724))
([9c0a7fd](9c0a7fd))
* consolidate DHI image-pin custom regex managers
([#1726](#1726))
([b8b0cba](b8b0cba))
* **deps:** update dependency chainguard-dev/melange to v0.50.4
([#1701](#1701))
([8cbf83a](8cbf83a))
* Lock file maintenance
([#1705](#1705))
([414cfea](414cfea))
* Lock file maintenance
([#1727](#1727))
([5cb1212](5cb1212))
* Update CLI dependencies
([#1702](#1702))
([9fb57b9](9fb57b9))
* Update Container dependencies
([#1698](#1698))
([6d24fd6](6d24fd6))
* Update dependency @eslint-react/eslint-plugin to v5
([#1704](#1704))
([1cb1294](1cb1294))
* Update Python dependencies
([#1699](#1699))
([8e7af3a](8e7af3a))
* Update Python dependencies to v4.15.0
([#1725](#1725))
([69164c8](69164c8))
* Update Web dependencies
([#1700](#1700))
([715300d](715300d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: synthorg-repo-bot[bot] <279117679+synthorg-repo-bot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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