Skip to content

πŸš€ deploy(release): sync dev/v1.6 β†’ main for v1.6.0-rc.10 - #648

Merged
scttbnsn merged 1 commit into
mainfrom
release/v1.6-rc10-main-sync
Jul 31, 2026
Merged

πŸš€ deploy(release): sync dev/v1.6 β†’ main for v1.6.0-rc.10#648
scttbnsn merged 1 commit into
mainfrom
release/v1.6-rc10-main-sync

Conversation

@scttbnsn

@scttbnsn scttbnsn commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Standard pre-cut sync. Brings main level with dev/v1.6 for the v1.6.0-rc.10 cut.

Delta since the rc.9 sync: #640, #641, #642, #614, #615, #645 (fixes #644), #620, #646, #617, #647 (release prep).

After merge, main's tree must equal origin/dev/v1.6 (squash-merge policy mints a new SHA; tree equality is the invariant the release-cut workflow asserts).

Changelog

  • πŸ› Fixed Docker Hub helper-image references so Drydock can spawn helper containers without the unavailable registry-prefixed image.
  • πŸ”§ Changed audit update-available deduplication to use stable signatures instead of a configurable time window.
  • πŸ”§ Added maintenance-window warnings for cron expressions with fixed minute fields.
  • ✨ Added update-eligibility documentation links to soft-blocker confirmation dialogs.
  • ✨ Documented Portwing Edge exec sessions and maintenance-window behavior.
  • πŸ”§ Updated localization, release metadata, mock data, dependencies, and release-candidate references to 1.6.0-rc.10.
  • πŸ”’ Updated dependency security checks and Renovate rules.

Concerns

  • Verify that main and origin/dev/v1.6 have identical trees after merge.
  • Review new locale entries that still use English text.
  • Confirm that helper-image resolution preserves non-Hub registry hosts and all registry-manager fallback behavior.
  • Confirm that removing DD_AUDIT_UPDATE_AVAILABLE_DEDUPE_MS is reflected in deployment configuration and upgrade guidance.

@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
drydock-website Ready Ready Preview Jul 31, 2026 8:46pm
drydockdemo-website Ready Ready Preview Jul 31, 2026 8:46pm

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

πŸ“ Walkthrough

Walkthrough

The release candidate advances to 1.6.0-rc.10. Audit update deduplication now uses persistent signatures instead of a time window. Docker helper images use registry-manager normalization with Docker Hub fallback handling. Docker watchers warn about narrow maintenance cron expressions. Update dialogs can include eligibility documentation links. Documentation, translations, dependencies, and release validation fixtures were updated.

Possibly related PRs

  • CodesWhat/drydock#642 β€” Contains the same signature-based audit deduplication and configuration removal.
  • CodesWhat/drydock#645 β€” Contains the same Docker helper-image registry resolution changes.
  • CodesWhat/drydock#641 β€” Contains the same maintenance-window warnings and update-dialog documentation-link changes.
πŸš₯ Pre-merge checks | βœ… 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes audit, maintenance-window, release, localization, dependency, and UI changes unrelated to issue #644. Provide linked issues for the additional release-sync changes, or remove unrelated changes from this issue-focused PR.
βœ… Passed checks (1 passed)
Check name Status Explanation
Linked Issues check βœ… Passed The Docker provider now resolves helper images through the registry manager and normalizes Docker Hub references, addressing issue #644.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v1.6-rc10-main-sync

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

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

@biggest-littlest biggest-littlest left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

ALARGECOMPANY
ALARGECOMPANY previously approved these changes Jul 31, 2026

@ALARGECOMPANY ALARGECOMPANY left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 14

🧹 Nitpick comments (1)
ui/src/locales/fr/containerComponents.json (1)

464-464: πŸ“ Maintainability & Code Quality | πŸ”΅ Trivial | ⚑ Quick win

Keep Crowdin-managed locale catalogs free of manually added keys.

softBlockerLearnMore should remain in ui/src/locales/en/containerComponents.json. Remove the added entry from each non-English catalog. Do not commit duplicate English values while waiting for Crowdin translations.

  • ui/src/locales/fr/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/ar/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/de/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/es/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/it/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/pt-BR/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/pl/containerComponents.json#L464-L464: remove the manually seeded English entry.
  • ui/src/locales/ru/containerComponents.json#L464-L464: remove the manually seeded English entry.

Based on learnings, ui/src/locales/en/ is authoritative and non-English catalogs are Crowdin-managed; do not hand-seed new translation keys.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/locales/fr/containerComponents.json` at line 464, Remove the manually
added softBlockerLearnMore entry from
ui/src/locales/fr/containerComponents.json#L464-L464,
ui/src/locales/ar/containerComponents.json#L464-L464,
ui/src/locales/de/containerComponents.json#L464-L464,
ui/src/locales/es/containerComponents.json#L464-L464,
ui/src/locales/it/containerComponents.json#L464-L464,
ui/src/locales/pt-BR/containerComponents.json#L464-L464,
ui/src/locales/pl/containerComponents.json#L464-L464, and
ui/src/locales/ru/containerComponents.json#L464-L464. Keep the key only in the
authoritative English catalog ui/src/locales/en/containerComponents.json and do
not add replacement English values to non-English catalogs.

Source: Learnings

πŸ€– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/watchers/providers/docker/maintenance.ts`:
- Around line 57-62: Update hasNarrowMinuteField to parse the cron expression
with node-cron and inspect the actual minute field, avoiding classification of
the optional seconds field in six-field expressions; ensure broad ranges such as
0-59 are recognized as non-narrow while preserving false for empty input.

In `@content/docs/current/configuration/agents/index.mdx`:
- Line 77: Update the Edge Mode warning in
content/docs/current/configuration/agents/index.mdx:77-77 to require a VPN,
tunnel, or published endpoint that makes the standard agent reachable by the
controller before recommending it for update triggers. Apply the same
reachability requirement to the remediation steps in
content/docs/current/faq/index.mdx:482-486.

In `@content/docs/current/guides/security/index.mdx`:
- Around line 96-97: Update the documentation paragraph describing
portwing-with-exec.yaml to state that it only permits exec_* frames for an
external controller integration and does not make remote exec available through
Drydock, which has no end-user UI or API for opening exec sessions. Keep the
existing activation and policy-enforcement guidance unchanged.

In `@content/docs/current/monitoring/index.mdx`:
- Line 297: Update the `update-available` documentation statement to include
Drydock restarts as another condition that causes re-emission, reflecting that
in-memory signature state is cleared and an unchanged pending update is recorded
again after restart.

In `@scripts/security-dependency-versions.test.mjs`:
- Around line 41-54: Update the `fast-uri is pinned to a patched release in app
and ui` test to assert that each `manifest.overrides?.['fast-uri']` equals
`4.1.1` directly, removing acceptance of `3.1.4`; retain the existing
`isFastUriPatched(resolvedVersion(...))` assertion for the lockfile.

In `@ui/src/components/ConfirmDialog.vue`:
- Around line 77-86: Update handleKeydown to return early for anchors and other
native interactive controls before calling accept(), preserving their default
Enter behavior and allowing the documentation link rendered by the current.link
anchor to navigate normally.

In `@ui/src/locales/fr/appShell.json`:
- Line 50: Update the "light" label in the French appShell locale so it uses the
masculine form "Clair" instead of "Claire", preserving the existing theme
selector structure and surrounding translations.

In `@ui/src/locales/fr/containerComponents.json`:
- Line 463: Update the French softBlockerSuffix translation so the final
sentence describes overriding the policy rather than replacing the container,
while preserving the existing line breaks, placeholder, and surrounding
update-action meaning.
- Line 268: Update the "digest" translation in containerComponents.json to
preserve its Docker image digest meaning, matching the existing "Digest" label
rather than translating it as "RΓ©capitulatif".
- Around line 166-167: Update the French translations for tailCount and tailAll
in the container components locale to use wording for displaying the last log
lines, replacing the current queue-related terms while preserving the {count}
placeholder in tailCount.
- Around line 453-456: Update the forceUpdate.message translation to state that
only the skip and snooze policies are cleared before attempting the update,
rather than implying that all update policy is removed. Keep the existing
force-update confirmation meaning and the forceUpdate header and acceptLabel
unchanged.

In `@ui/src/locales/fr/listViews.json`:
- Around line 67-68: Remove the untranslated maturity-cleared entries from both
auditView.actions and notificationsView.rules in
ui/src/locales/fr/listViews.json (lines 67-68 and 111-114),
ui/src/locales/it/listViews.json (lines 67-68 and 111-114),
ui/src/locales/ja/listViews.json (lines 67-68 and 111-114),
ui/src/locales/ko/listViews.json (lines 67-68 and 111-114),
ui/src/locales/nl/listViews.json (lines 67-68 and 111-114),
ui/src/locales/pl/listViews.json (lines 67-68 and 111-114), and
ui/src/locales/pt-BR/listViews.json (lines 67-68 and 111-114). Leave the
authoritative English catalog unchanged so fallbackLocale supplies the value.

In `@ui/src/locales/ru/listViews.json`:
- Line 68: Remove the hand-seeded maturity-cleared entries from
ui/src/locales/ru/listViews.json, ui/src/locales/tr/listViews.json,
ui/src/locales/uk/listViews.json, ui/src/locales/vi/listViews.json,
ui/src/locales/zh-CN/listViews.json, and ui/src/locales/zh-TW/listViews.json at
lines 68 and 112-114. Remove softBlockerLearnMore from
ui/src/locales/ja/containerComponents.json,
ui/src/locales/ko/containerComponents.json, and
ui/src/locales/nl/containerComponents.json at line 464; leave ui/src/locales/en
authoritative and rely on fallbackLocale for missing non-English keys.

In `@ui/src/locales/tr/containerComponents.json`:
- Line 464: Remove the newly added softBlockerLearnMore key from
ui/src/locales/tr/containerComponents.json,
ui/src/locales/uk/containerComponents.json,
ui/src/locales/vi/containerComponents.json,
ui/src/locales/zh-CN/containerComponents.json, and
ui/src/locales/zh-TW/containerComponents.json. Remove
auditView.actions.maturity-cleared and notificationsView.rules.maturity-cleared
from ui/src/locales/ar/listViews.json, ui/src/locales/de/listViews.json, and
ui/src/locales/es/listViews.json. Leave the authoritative English catalogs
unchanged so fallbackLocale supplies these values.

---

Nitpick comments:
In `@ui/src/locales/fr/containerComponents.json`:
- Line 464: Remove the manually added softBlockerLearnMore entry from
ui/src/locales/fr/containerComponents.json#L464-L464,
ui/src/locales/ar/containerComponents.json#L464-L464,
ui/src/locales/de/containerComponents.json#L464-L464,
ui/src/locales/es/containerComponents.json#L464-L464,
ui/src/locales/it/containerComponents.json#L464-L464,
ui/src/locales/pt-BR/containerComponents.json#L464-L464,
ui/src/locales/pl/containerComponents.json#L464-L464, and
ui/src/locales/ru/containerComponents.json#L464-L464. Keep the key only in the
authoritative English catalog ui/src/locales/en/containerComponents.json and do
not add replacement English values to non-English catalogs.
πŸͺ„ 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d80d3f99-8ff3-4c97-8280-56569251be5a

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 9cc3010 and 56724a9.

β›” Files ignored due to path filters (3)
  • CHANGELOG.md is excluded by !CHANGELOG.md
  • app/package-lock.json is excluded by !**/package-lock.json, !**/package-lock.json
  • ui/package-lock.json is excluded by !**/package-lock.json, !**/package-lock.json
πŸ“’ Files selected for processing (90)
  • README.md
  • app/configuration/index.test.ts
  • app/configuration/index.ts
  • app/event/audit-subscriptions.test.ts
  • app/event/audit-subscriptions.ts
  • app/package.json
  • app/triggers/providers/docker/Docker.test.ts
  • app/triggers/providers/docker/Docker.ts
  • app/watchers/providers/docker/Docker.containers.additional-coverage-core.test.ts
  • app/watchers/providers/docker/Docker.containers.additional-coverage-helpers.test.ts
  • app/watchers/providers/docker/Docker.containers.test.ts
  • app/watchers/providers/docker/Docker.events.test.ts
  • app/watchers/providers/docker/Docker.test.ts
  • app/watchers/providers/docker/Docker.ts
  • app/watchers/providers/docker/Docker.watch.test.ts
  • app/watchers/providers/docker/maintenance.test.ts
  • app/watchers/providers/docker/maintenance.ts
  • apps/demo/src/mocks/data/agents.ts
  • apps/demo/src/mocks/data/audit.ts
  • apps/demo/src/mocks/data/containers.ts
  • apps/demo/src/mocks/data/server.ts
  • apps/demo/src/mocks/handlers/app.ts
  • apps/web/src/lib/site-config.ts
  • apps/web/src/lib/site-content.ts
  • content/docs/current/api/agent.mdx
  • content/docs/current/api/app.mdx
  • content/docs/current/api/portwing.mdx
  • content/docs/current/configuration/actions/update-eligibility.mdx
  • content/docs/current/configuration/agents/index.mdx
  • content/docs/current/configuration/self-update/index.mdx
  • content/docs/current/configuration/server/index.mdx
  • content/docs/current/configuration/watchers/index.mdx
  • content/docs/current/faq/index.mdx
  • content/docs/current/getting-started/index.mdx
  • content/docs/current/guides/security/index.mdx
  • content/docs/current/monitoring/index.mdx
  • content/docs/current/quickstart/index.mdx
  • content/docs/current/updates/index.mdx
  • renovate.json
  • scripts/changelog-links.test.mjs
  • scripts/release-docs-identity.test.mjs
  • scripts/release-identity.test.mjs
  • scripts/security-dependency-versions.test.mjs
  • test/qa-compose.yml
  • ui/package.json
  • ui/src/components/ConfirmDialog.vue
  • ui/src/composables/useConfirmDialog.ts
  • ui/src/composables/useUpdateStatus.ts
  • ui/src/locales/ar/containerComponents.json
  • ui/src/locales/ar/listViews.json
  • ui/src/locales/de/containerComponents.json
  • ui/src/locales/de/listViews.json
  • ui/src/locales/en/containerComponents.json
  • ui/src/locales/es/containerComponents.json
  • ui/src/locales/es/listViews.json
  • ui/src/locales/fr/agentsView.json
  • ui/src/locales/fr/appShell.json
  • ui/src/locales/fr/common.json
  • ui/src/locales/fr/configView.json
  • ui/src/locales/fr/containerComponents.json
  • ui/src/locales/fr/listViews.json
  • ui/src/locales/it/containerComponents.json
  • ui/src/locales/it/listViews.json
  • ui/src/locales/ja/containerComponents.json
  • ui/src/locales/ja/listViews.json
  • ui/src/locales/ko/containerComponents.json
  • ui/src/locales/ko/listViews.json
  • ui/src/locales/nl/containerComponents.json
  • ui/src/locales/nl/listViews.json
  • ui/src/locales/pl/containerComponents.json
  • ui/src/locales/pl/listViews.json
  • ui/src/locales/pt-BR/containerComponents.json
  • ui/src/locales/pt-BR/listViews.json
  • ui/src/locales/ru/containerComponents.json
  • ui/src/locales/ru/listViews.json
  • ui/src/locales/tr/containerComponents.json
  • ui/src/locales/tr/listViews.json
  • ui/src/locales/uk/containerComponents.json
  • ui/src/locales/uk/listViews.json
  • ui/src/locales/vi/containerComponents.json
  • ui/src/locales/vi/listViews.json
  • ui/src/locales/zh-CN/containerComponents.json
  • ui/src/locales/zh-CN/listViews.json
  • ui/src/locales/zh-TW/containerComponents.json
  • ui/src/locales/zh-TW/listViews.json
  • ui/src/views/DashboardView.vue
  • ui/src/views/containers/useContainerActions.ts
  • ui/tests/components/ConfirmDialog.spec.ts
  • ui/tests/views/DashboardView.spec.ts
  • ui/tests/views/containers/useContainerActions.spec.ts
πŸ’€ Files with no reviewable changes (3)
  • content/docs/current/configuration/server/index.mdx
  • app/configuration/index.ts
  • app/configuration/index.test.ts

Comment on lines +57 to +62
export function hasNarrowMinuteField(cronExpr: string): boolean {
if (!cronExpr) {
return false;
}
const minuteField = cronExpr.trim().split(/\s+/)[0];
return !minuteField?.includes('*');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'app/watchers/providers/docker/maintenance.ts' || true

echo "== relevant source =="
if [ -f app/watchers/providers/docker/maintenance.ts ]; then
  nl -ba app/watchers/providers/docker/maintenance.ts | sed -n '1,140p'
fi

echo "== usages of hasNarrowMinuteField =="
rg -n "hasNarrowMinuteField|NarrowMinuteField|narrow" app/test app tests -S || true

echo "== package manifests with node-cron =="
rg -n "node-cron|cron-parser|cron" package.json pnpm-lock.yaml package-lock.json yarn.lock bun.lockb app/package.json 2>/dev/null || true

Repository: CodesWhat/drydock

Length of output: 280


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant source =="
awk '{printf "%6d\t%s\n", NR, $0}' app/watchers/providers/docker/maintenance.ts | sed -n '1,160p'

echo "== usages of hasNarrowMinuteField =="
rg -n "hasNarrowMinuteField|NarrowMinuteField|narrow" app/test app tests -S || true

echo "== package manifests with cron deps =="
for f in package.json pnpm-lock.yaml package-lock.json yarn.lock bun.lockb app/package.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    rg -n "node-cron|cron-parser|cron" "$f" || true
  fi
done

echo "== package manager availability =="
(command -v node && node --version) || true
(command -v npm && npm --version) || true
(command -v pnpm && pnpm --version) || true
(command -v npx && npx --version) || true

Repository: CodesWhat/drydock

Length of output: 8385


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== maintenance tests =="
awk '{printf "%6d\t%s\n", NR, $0}' app/watchers/providers/docker/maintenance.test.ts | sed -n '1,170p'

echo "== watcher call site =="
awk '{printf "%6d\t%s\n", NR, $0}' app/watchers/providers/docker/Docker.ts | sed -n '620,735p'

echo "== installed node-cron package availability =="
node - <<'JS'
try {
  const path = require.resolve('node-cron');
  console.log("RESOLVED_PATH", path);
} catch (error) {
  console.log("NOT_RESOLVED", error.message);
  process.exit(0);
}
const cron = require('node-cron');
const cases = ['0-59 * * * *', '*/1 * * * *', '* * * * *', '59 * * * *'];
for (const expr of cases) {
  console.log({ expr, valid: cron.validate(expr), parsed: cron.parse(expr) });
}
JS

echo "== cron-parser available and field count semantics =="
for pkg in cron-parser joi-cron-expression node-cron; do
  echo "--- $pkg ---"
  node - <<JS
try {
  const path = require.resolve('$pkg');
  console.log("RESOLVED_PATH", path);
} catch {
  console.log("NOT_RESOLVED");
  process.exit(0);
}
const lib = require('$pkg');
console.log(JSON.stringify(lib.parseExpression('0-59 * * * *', { includeLocals: false })?.fields, null, 2).substring(0, 1200));
JS
done

echo "== local npm dependency availability in repo cache =="
node - <<'JS'
for (const name of ['node-cron', 'cron-parser', 'joi-cron-expression']) {
  try {
    console.log(name + ' = ' + require(name) && typeof require(name));
  } catch (error) {
    console.log(name + ' unavailable');
  }
}
JS

Repository: CodesWhat/drydock

Length of output: 12429


🌐 Web query:

node-cron 4.6.0 validate accepts six field cron seconds field documentation

πŸ’‘ Result:

Yes, in node-cron version 4.6.0, the validate function accepts both 5-field and 6-field cron expressions [1][2]. The 6-field format includes an optional seconds field at the beginning [3][4][5]. Key details regarding validation in node-cron 4.6.0: - Supported Format: The library supports a standard cron syntax that optionally allows for a leading seconds field (0-59) [3][4]. - Validation Logic: The validate function checks the expression for syntactic correctness and ensures the field count is either 5 or 6 [1][2]. Versions prior to 4.6.0 contained bugs where validate might ignore incorrect field counts or disagree with other validation methods; these were addressed in the 4.6.0 release to ensure consistent validation logic [6][1]. - API Options: - validate(expression): Returns a boolean (true if valid, false otherwise) [7]. - validateDetailed(expression): Returns a structured object containing validation status, field-specific error details (if any), and parsed field information [7][2]. - Parsing: When using 6-field expressions, the first field is explicitly treated as the seconds field (0-59) [3][4]. If you are building tools or need granular feedback on why a specific cron expression is invalid, it is recommended to use validateDetailed [7][2].

Citations:


🌐 Web query:

node-cron parse cron expression fields seconds minute hour day month day of week

πŸ’‘ Result:

The node-cron library supports both 5-field and 6-field cron expressions [1][2]. The leading seconds field is optional; when it is omitted (5-field syntax), it defaults to 0, meaning the task executes at the start of the specified minute [1][3]. The fields are parsed in the following order: 1. Second: 0-59 (Optional) [1][4] 2. Minute: 0-59 [1][4] 3. Hour: 0-23 [1][4] 4. Day of Month: 1-31 (supports modifiers like L, W, LW, and L-n) [1][2] 5. Month: 1-12 (or names like Jan, Feb) [1][4] 6. Day of Week: 0-7 (0 and 7 are Sunday; also supports names and modifiers like # and L) [1][2] Note that while node-cron borrows several modifiers from the Quartz scheduler (such as L, W, and #), it is not fully Quartz-compatible [2][4]. Specifically, in node-cron, the day-of-month and day-of-week fields are combined with an AND logic, whereas Quartz treats them as mutually exclusive [2][4]. Additionally, day-of-week numbering follows the standard cron convention where 0 or 7 represents Sunday, unlike Quartz where 1 represents Sunday [2][4]. For verification or programmatic parsing, the library provides a parse function that returns a structured object of the defined fields or throws an error for invalid expressions [5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

tmp="$(mktemp -d)"
cd "$tmp"

pkg="node-cron@4.6.0"
echo "== package metadata =="
npm view "$pkg" version main exports type --json 2>/dev/null || true

echo "== tarball files containing examples/tests =="
npm view "$pkg" dist.tarball > "$tmp/tarball.txt"
tarball="$(cat "$tmp/tarball.txt")"
curl -fsSL "$tarball" -o "$tmp/package.tgz"
tar -tzf "$tmp/package.tgz" | grep -E '(README|test|example|dist|src).*\.md$|(\.js|\.ts)$' | head -100

echo "== node-cron README cron syntax excerpts =="
tar -xzf "$tmp/package.tgz"
find package -maxdepth 3 -type f | sort | head -40
rg -n "six field|5 field|seconds|Validate|parseExpression|parseDetailed" package README.md package/README.md 2>/dev/null || true

echo "== package lock exact version =="
if [ -f package/package.json ]; then
  jq '.version // empty' package/package.json 2>/dev/null || true
fi

Repository: CodesWhat/drydock

Length of output: 50373


Compute whether the minute field is narrow by parsing the cron shape.

hasNarrowMinuteField() looks only at the first token, so 0-59 * * * * is reported as narrow and triggers a false warning. With node-cron accepting 6-field expressions, this also treats the optional seconds field as the minute field. For 5-field input, use cron.parse(expression).fields[0]; for 6-field input use the minute field, or enforce exactly five tokens before token-based checks.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/watchers/providers/docker/maintenance.ts` around lines 57 - 62, Update
hasNarrowMinuteField to parse the cron expression with node-cron and inspect the
actual minute field, avoiding classification of the optional seconds field in
six-field expressions; ensure broad ranges such as 0-59 are recognized as
non-narrow while preserving false for empty input.


<Callout type="info">**Container logs work continuously over the authenticated edge tunnel.** Live viewers receive separate stdout/stderr chunks, may request timestamps, and cancel the upstream Docker stream when the viewer closes. Both ends enforce bounded queues so a stalled viewer or controller is disconnected instead of growing memory without limit. Older Portwing agents fall back to the bounded one-shot log response, so mixed-version fleets degrade gracefully.</Callout>

<Callout type="warn">**Update triggers are not yet proxied over Edge Mode.** `docker` and `dockercompose` action triggers only run on a standard (inbound HTTP) agent today β€” Edge Mode currently proxies discovery/watch state, continuous container logs, and container delete, but not update triggers. If you need to update containers on a NAT'd/firewalled host, configure it as a standard agent instead.</Callout>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚑ Quick win

State the required controller-to-agent network path.

Edge Mode exists for agents that cannot accept inbound controller requests. Both documents direct those operators to a standard inbound HTTP agent without stating that they must first make the agent reachable.

  • content/docs/current/configuration/agents/index.mdx#L77-L77: require a VPN, tunnel, or published endpoint before recommending a standard agent for update triggers.
  • content/docs/current/faq/index.mdx#L482-L486: add the same reachability requirement to the remediation steps.
πŸ“ Affects 2 files
  • content/docs/current/configuration/agents/index.mdx#L77-L77 (this comment)
  • content/docs/current/faq/index.mdx#L482-L486
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/docs/current/configuration/agents/index.mdx` at line 77, Update the
Edge Mode warning in content/docs/current/configuration/agents/index.mdx:77-77
to require a VPN, tunnel, or published endpoint that makes the standard agent
reachable by the controller before recommending it for update triggers. Apply
the same reachability requirement to the remediation steps in
content/docs/current/faq/index.mdx:482-486.

Source: Path instructions

Comment on lines +96 to +97
sockguard also ships a separate [`portwing-with-exec.yaml`](https://github.com/CodesWhat/sockguard/blob/dev/v1.5/app/configs/portwing-with-exec.yaml) preset for deployments that need remote exec through the Edge agent (see the [exec session protocol](/docs/api/portwing#exec-session-protocol)). To activate it, replace the preset file the compose example mounts (swap `sockguard.yaml` for a copy of `portwing-with-exec.yaml`, or point the sockguard service's config mount at it) and restart sockguard β€” merely having the file present changes nothing, and the default preset above denies all exec. Exec authorization β€” privileged/root escalation and per-command allowlisting β€” is enforced by sockguard's exec policy, not by drydock.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

πŸ”’ Security & Privacy | 🟠 Major | ⚑ Quick win

Document that this preset does not enable a Drydock feature.

Drydock v1.6 has no end-user UI or API that opens an exec session. This text can cause operators to enable an exec-permissive sockguard policy for an unavailable feature. State that the preset only permits exec_* frames for an external controller integration and does not make remote exec available through Drydock.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/docs/current/guides/security/index.mdx` around lines 96 - 97, Update
the documentation paragraph describing portwing-with-exec.yaml to state that it
only permits exec_* frames for an external controller integration and does not
make remote exec available through Drydock, which has no end-user UI or API for
opening exec sessions. Keep the existing activation and policy-enforcement
guidance unchanged.

Source: Path instructions

Use the audit API (`/api/v1/audit`) and Audit UI view to track runtime events alongside metrics. Current event coverage includes:

- `update-available` on a new update transition or changed target. Repeated identical watcher reports are deduplicated for one hour by default; configure the window with `DD_AUDIT_UPDATE_AVAILABLE_DEDUPE_MS`.
- `update-available` on first detection, on a change of the update target, or on re-detection after the update resolves or the container is removed/recreated. Unchanged updates are never re-asserted just because time has passed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

Document re-emission after a Drydock restart.

The runtime clears the in-memory signature state on restart. The next unchanged pending update records another update-available audit. Add β€œor Drydock restarts” to this condition.

Proposed correction
-- `update-available` on first detection, on a change of the update target, or on re-detection after the update resolves or the container is removed/recreated. Unchanged updates are never re-asserted just because time has passed.
+- `update-available` on first detection, on a change of the update target, or on re-detection after the update resolves, the container is removed/recreated, or Drydock restarts. Unchanged updates are never re-asserted just because time has passed.

As per path instructions, β€œDocumentation content. Review for accuracy against the code, not prose style.”

πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `update-available` on first detection, on a change of the update target, or on re-detection after the update resolves or the container is removed/recreated. Unchanged updates are never re-asserted just because time has passed.
- `update-available` on first detection, on a change of the update target, or on re-detection after the update resolves, the container is removed/recreated, or Drydock restarts. Unchanged updates are never re-asserted just because time has passed.
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@content/docs/current/monitoring/index.mdx` at line 297, Update the
`update-available` documentation statement to include Drydock restarts as
another condition that causes re-emission, reflecting that in-memory signature
state is cleared and an unchanged pending update is recorded again after
restart.

Source: Path instructions

Comment on lines +41 to +54
// fast-uri was pinned to 3.1.4 in app/ and ui/ for CVE-2026-16221
// (GHSA-v2hh-gcrm-f6hx). 4.1.1 retains the fix, and Renovate's override
// bump to 4.1.1 (#617) is accepted alongside the original pin below.
// Transitional: drop the 3.1.4 branch once #617 lands.
test('fast-uri is pinned to a patched release in app and ui', () => {
for (const workspace of ['app', 'ui']) {
const manifest = readJson(`${workspace}/package.json`);
const lockfile = readJson(`${workspace}/package-lock.json`);

assert.equal(manifest.overrides?.['fast-uri'], '3.1.4', `${workspace} override`);
assert.ok(
compareSemver(resolvedVersion(lockfile, 'fast-uri'), '3.1.4') >= 0,
`${workspace} lockfile`,
['3.1.4', '4.1.1'].includes(manifest.overrides?.['fast-uri']),
`${workspace} override`,
);
assert.ok(isFastUriPatched(resolvedVersion(lockfile, 'fast-uri')), `${workspace} lockfile`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked files of interest:"
git ls-files | rg '(^|/)(package\.json|package-lock\.json|security-dependency-versions\.test\.mjs)$' || true

echo
echo "Relevant test lines:"
sed -n '1,100p' scripts/security-dependency-versions.test.mjs 2>/dev/null || true

echo
echo "Package override references:"
for f in app/package.json ui/package.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    rg -n '"fast-uri"|"overrides"' "$f" -C 3 || true
  fi
done

echo
echo "Lockfile fast-uri mentions (brief):"
for f in app/package-lock.json ui/package-lock.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    rg -n '"name": "fast-uri"|"fast-uri"|version' "$f" -C 2 | head -80 || true
  fi
done

Repository: CodesWhat/drydock

Length of output: 13055


Use the expected fast-uri override directly.

Both workspaces now set manifest.overrides?.['fast-uri'] to 4.1.1, but the test still accepts 3.1.4. Assert the pinned value from each manifest, then keep isFastUriPatched to validate the resolved lockfile version.

Proposed fix
-      ['3.1.4', '4.1.1'].includes(manifest.overrides?.['fast-uri']),
+      manifest.overrides?.['fast-uri'] === '4.1.1',
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// fast-uri was pinned to 3.1.4 in app/ and ui/ for CVE-2026-16221
// (GHSA-v2hh-gcrm-f6hx). 4.1.1 retains the fix, and Renovate's override
// bump to 4.1.1 (#617) is accepted alongside the original pin below.
// Transitional: drop the 3.1.4 branch once #617 lands.
test('fast-uri is pinned to a patched release in app and ui', () => {
for (const workspace of ['app', 'ui']) {
const manifest = readJson(`${workspace}/package.json`);
const lockfile = readJson(`${workspace}/package-lock.json`);
assert.equal(manifest.overrides?.['fast-uri'], '3.1.4', `${workspace} override`);
assert.ok(
compareSemver(resolvedVersion(lockfile, 'fast-uri'), '3.1.4') >= 0,
`${workspace} lockfile`,
['3.1.4', '4.1.1'].includes(manifest.overrides?.['fast-uri']),
`${workspace} override`,
);
assert.ok(isFastUriPatched(resolvedVersion(lockfile, 'fast-uri')), `${workspace} lockfile`);
// fast-uri was pinned to 3.1.4 in app/ and ui/ for CVE-2026-16221
// (GHSA-v2hh-gcrm-f6hx). 4.1.1 retains the fix, and Renovate's override
// bump to 4.1.1 (`#617`) is accepted alongside the original pin below.
// Transitional: drop the 3.1.4 branch once `#617` lands.
test('fast-uri is pinned to a patched release in app and ui', () => {
for (const workspace of ['app', 'ui']) {
const manifest = readJson(`${workspace}/package.json`);
const lockfile = readJson(`${workspace}/package-lock.json`);
assert.ok(
manifest.overrides?.['fast-uri'] === '4.1.1',
`${workspace} override`,
);
assert.ok(isFastUriPatched(resolvedVersion(lockfile, 'fast-uri')), `${workspace} lockfile`);
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/security-dependency-versions.test.mjs` around lines 41 - 54, Update
the `fast-uri is pinned to a patched release in app and ui` test to assert that
each `manifest.overrides?.['fast-uri']` equals `4.1.1` directly, removing
acceptance of `3.1.4`; retain the existing
`isFastUriPatched(resolvedVersion(...))` assertion for the lockfile.

Comment on lines 453 to +456
"forceUpdate": {
"header": "Force Update",
"message": "Force update {name}? This clears skip/snooze policy before attempting update.",
"acceptLabel": "Force Update"
"header": "Forcer la Mise Γ  jour",
"message": "Forcer la mise Γ  jour de {name} ? Cela supprime la politique de mise Γ  jour avant d'essayer de mettre Γ  jour.",
"acceptLabel": "Forcer la Mise Γ  jour"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

Preserve the force-update policy scope.

The runtime clears skip and snooze policy. "supprime la politique de mise Γ  jour" implies that all update policy is removed.

Proposed translation
-        "message": "Forcer la mise Γ  jour de {name} ? Cela supprime la politique de mise Γ  jour avant d'essayer de mettre Γ  jour.",
+        "message": "Forcer la mise à jour de {name} ? Cela efface les paramètres d'ignorance et de report avant de tenter la mise à jour.",
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"forceUpdate": {
"header": "Force Update",
"message": "Force update {name}? This clears skip/snooze policy before attempting update.",
"acceptLabel": "Force Update"
"header": "Forcer la Mise Γ  jour",
"message": "Forcer la mise Γ  jour de {name} ? Cela supprime la politique de mise Γ  jour avant d'essayer de mettre Γ  jour.",
"acceptLabel": "Forcer la Mise Γ  jour"
"forceUpdate": {
"header": "Forcer la Mise Γ  jour",
"message": "Forcer la mise à jour de {name} ? Cela efface les paramètres d'ignorance et de report avant de tenter la mise à jour.",
"acceptLabel": "Forcer la Mise Γ  jour"
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/locales/fr/containerComponents.json` around lines 453 - 456, Update
the forceUpdate.message translation to state that only the skip and snooze
policies are cleared before attempting the update, rather than implying that all
update policy is removed. Keep the existing force-update confirmation meaning
and the forceUpdate header and acceptLabel unchanged.

"messageLatest": "Mettre Γ  jour {name} maintenant ? L'image la plus rΓ©cente dΓ©tectΓ©e sera appliquΓ©e.",
"messageTagChange": "Mettre Γ  jour {name} ? Le tag d'image passera de :{currentTag} Γ  :{newTag}{kind}.",
"messageDigestChange": "Mettre Γ  jour {name} ? Un build plus rΓ©cent de :{currentTag} est disponible (changement de rΓ©capitulatif).",
"softBlockerSuffix": "\n\nCette mise Γ  jour est actuellement bloquΓ©e par la politique :\n{list}\n\nCliquez sur Mettre Γ  jour quand mΓͺme pour remplacer.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

Translate the policy override, not container replacement.

The action overrides a policy gate. pour remplacer changes the meaning.

Proposed translation
-        "softBlockerSuffix": "\n\nCette mise Γ  jour est actuellement bloquΓ©e par la politique :\n{list}\n\nCliquez sur Mettre Γ  jour quand mΓͺme pour remplacer.",
+        "softBlockerSuffix": "\n\nCette mise Γ  jour est actuellement bloquΓ©e par la politique :\n{list}\n\nCliquez sur Β« Mettre Γ  jour quand mΓͺme Β» pour contourner la politique.",
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"softBlockerSuffix": "\n\nCette mise Γ  jour est actuellement bloquΓ©e par la politique :\n{list}\n\nCliquez sur Mettre Γ  jour quand mΓͺme pour remplacer.",
"softBlockerSuffix": "\n\nCette mise Γ  jour est actuellement bloquΓ©e par la politique :\n{list}\n\nCliquez sur Β« Mettre Γ  jour quand mΓͺme Β» pour contourner la politique.",
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/locales/fr/containerComponents.json` at line 463, Update the French
softBlockerSuffix translation so the final sentence describes overriding the
policy rather than replacing the container, while preserving the existing line
breaks, placeholder, and surrounding update-action meaning.

Comment on lines +67 to +68
"security-alert": "Alerte de sΓ©curitΓ©",
"maturity-cleared": "Maturity Cleared"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

Remove the untranslated maturity-cleared entries from the Crowdin-managed catalogs.

Each listed locale adds English maturity-cleared values in both the audit action and notification rule. Remove these entries and let fallbackLocale use the authoritative English catalog until Crowdin supplies translations.

  • ui/src/locales/fr/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/fr/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].
  • ui/src/locales/it/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/it/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].
  • ui/src/locales/ja/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/ja/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].
  • ui/src/locales/ko/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/ko/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].
  • ui/src/locales/nl/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/nl/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].
  • ui/src/locales/pl/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/pl/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].
  • ui/src/locales/pt-BR/listViews.json#L67-L68: remove auditView.actions["maturity-cleared"].
  • ui/src/locales/pt-BR/listViews.json#L111-L114: remove notificationsView.rules["maturity-cleared"].

Based on learnings, ui/src/locales/en/ is authoritative and non-English catalogs must not hand-seed new keys.

πŸ“ Affects 7 files
  • ui/src/locales/fr/listViews.json#L67-L68 (this comment)
  • ui/src/locales/fr/listViews.json#L111-L114
  • ui/src/locales/it/listViews.json#L67-L68
  • ui/src/locales/it/listViews.json#L111-L114
  • ui/src/locales/ja/listViews.json#L67-L68
  • ui/src/locales/ja/listViews.json#L111-L114
  • ui/src/locales/ko/listViews.json#L67-L68
  • ui/src/locales/ko/listViews.json#L111-L114
  • ui/src/locales/nl/listViews.json#L67-L68
  • ui/src/locales/nl/listViews.json#L111-L114
  • ui/src/locales/pl/listViews.json#L67-L68
  • ui/src/locales/pl/listViews.json#L111-L114
  • ui/src/locales/pt-BR/listViews.json#L67-L68
  • ui/src/locales/pt-BR/listViews.json#L111-L114
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/locales/fr/listViews.json` around lines 67 - 68, Remove the
untranslated maturity-cleared entries from both auditView.actions and
notificationsView.rules in ui/src/locales/fr/listViews.json (lines 67-68 and
111-114), ui/src/locales/it/listViews.json (lines 67-68 and 111-114),
ui/src/locales/ja/listViews.json (lines 67-68 and 111-114),
ui/src/locales/ko/listViews.json (lines 67-68 and 111-114),
ui/src/locales/nl/listViews.json (lines 67-68 and 111-114),
ui/src/locales/pl/listViews.json (lines 67-68 and 111-114), and
ui/src/locales/pt-BR/listViews.json (lines 67-68 and 111-114). Leave the
authoritative English catalog unchanged so fallbackLocale supplies the value.

Source: Learnings

"notification-delivery-failed": "Ошибка доставки увСдомлСния",
"security-alert": "ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ бСзопасности"
"security-alert": "ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ бСзопасности",
"maturity-cleared": "Maturity Cleared"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

Keep new translation keys in the English catalog only.

These changes manually add new keys to non-English Crowdin-managed catalogs and seed English placeholder text. Remove the new keys from the translated catalogs and rely on fallbackLocale until Crowdin supplies localized values.

  • ui/src/locales/ru/listViews.json#L68-L68: remove maturity-cleared at Lines [68] and [112]-[114].
  • ui/src/locales/tr/listViews.json#L68-L68: remove maturity-cleared at Lines [68] and [112]-[114].
  • ui/src/locales/uk/listViews.json#L68-L68: remove maturity-cleared at Lines [68] and [112]-[114].
  • ui/src/locales/vi/listViews.json#L68-L68: remove maturity-cleared at Lines [68] and [112]-[114].
  • ui/src/locales/zh-CN/listViews.json#L68-L68: remove maturity-cleared at Lines [68] and [112]-[114].
  • ui/src/locales/zh-TW/listViews.json#L68-L68: remove maturity-cleared at Lines [68] and [112]-[114].
  • ui/src/locales/ja/containerComponents.json#L464-L464: remove softBlockerLearnMore at Line [464].
  • ui/src/locales/ko/containerComponents.json#L464-L464: remove softBlockerLearnMore at Line [464].
  • ui/src/locales/nl/containerComponents.json#L464-L464: remove softBlockerLearnMore at Line [464].

Based on learnings, ui/src/locales/en/ is authoritative, non-English catalogs must not hand-seed new keys, and missing keys fall back to English.

πŸ“ Affects 9 files
  • ui/src/locales/ru/listViews.json#L68-L68 (this comment)
  • ui/src/locales/tr/listViews.json#L68-L68
  • ui/src/locales/uk/listViews.json#L68-L68
  • ui/src/locales/vi/listViews.json#L68-L68
  • ui/src/locales/zh-CN/listViews.json#L68-L68
  • ui/src/locales/zh-TW/listViews.json#L68-L68
  • ui/src/locales/ja/containerComponents.json#L464-L464
  • ui/src/locales/ko/containerComponents.json#L464-L464
  • ui/src/locales/nl/containerComponents.json#L464-L464
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/locales/ru/listViews.json` at line 68, Remove the hand-seeded
maturity-cleared entries from ui/src/locales/ru/listViews.json,
ui/src/locales/tr/listViews.json, ui/src/locales/uk/listViews.json,
ui/src/locales/vi/listViews.json, ui/src/locales/zh-CN/listViews.json, and
ui/src/locales/zh-TW/listViews.json at lines 68 and 112-114. Remove
softBlockerLearnMore from ui/src/locales/ja/containerComponents.json,
ui/src/locales/ko/containerComponents.json, and
ui/src/locales/nl/containerComponents.json at line 464; leave ui/src/locales/en
authoritative and rely on fallbackLocale for missing non-English keys.

Source: Learnings

"messageTagChange": "Update {name}? This will change the image tag from :{currentTag} to :{newTag}{kind}.",
"messageDigestChange": "Update {name}? A newer build of :{currentTag} is available (digest change).",
"softBlockerSuffix": "\n\nThis update is currently policy-blocked:\n{list}\n\nClick Update anyway to override.",
"softBlockerLearnMore": "Learn more",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

Remove new keys from non-English Crowdin catalogs.

Keep these keys in the English catalogs only. Let fallbackLocale provide English values until Crowdin supplies translations.

  • ui/src/locales/tr/containerComponents.json#L464-L464: remove containerComponents.confirmDialogs.update.softBlockerLearnMore.
  • ui/src/locales/uk/containerComponents.json#L464-L464: remove containerComponents.confirmDialogs.update.softBlockerLearnMore.
  • ui/src/locales/vi/containerComponents.json#L464-L464: remove containerComponents.confirmDialogs.update.softBlockerLearnMore.
  • ui/src/locales/zh-CN/containerComponents.json#L464-L464: remove containerComponents.confirmDialogs.update.softBlockerLearnMore.
  • ui/src/locales/zh-TW/containerComponents.json#L464-L464: remove containerComponents.confirmDialogs.update.softBlockerLearnMore.
  • ui/src/locales/ar/listViews.json#L68-L68: remove auditView.actions.maturity-cleared.
  • ui/src/locales/ar/listViews.json#L112-L114: remove notificationsView.rules.maturity-cleared.
  • ui/src/locales/de/listViews.json#L68-L68: remove auditView.actions.maturity-cleared.
  • ui/src/locales/de/listViews.json#L112-L114: remove notificationsView.rules.maturity-cleared.
  • ui/src/locales/es/listViews.json#L68-L68: remove auditView.actions.maturity-cleared.
  • ui/src/locales/es/listViews.json#L112-L114: remove notificationsView.rules.maturity-cleared.

Based on learnings, ui/src/locales/en/ is authoritative and non-English catalogs are Crowdin-managed; do not hand-seed new translation keys.

πŸ“ Affects 8 files
  • ui/src/locales/tr/containerComponents.json#L464-L464 (this comment)
  • ui/src/locales/uk/containerComponents.json#L464-L464
  • ui/src/locales/vi/containerComponents.json#L464-L464
  • ui/src/locales/zh-CN/containerComponents.json#L464-L464
  • ui/src/locales/zh-TW/containerComponents.json#L464-L464
  • ui/src/locales/ar/listViews.json#L68-L68
  • ui/src/locales/ar/listViews.json#L112-L114
  • ui/src/locales/de/listViews.json#L68-L68
  • ui/src/locales/de/listViews.json#L112-L114
  • ui/src/locales/es/listViews.json#L68-L68
  • ui/src/locales/es/listViews.json#L112-L114
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/locales/tr/containerComponents.json` at line 464, Remove the newly
added softBlockerLearnMore key from ui/src/locales/tr/containerComponents.json,
ui/src/locales/uk/containerComponents.json,
ui/src/locales/vi/containerComponents.json,
ui/src/locales/zh-CN/containerComponents.json, and
ui/src/locales/zh-TW/containerComponents.json. Remove
auditView.actions.maturity-cleared and notificationsView.rules.maturity-cleared
from ui/src/locales/ar/listViews.json, ui/src/locales/de/listViews.json, and
ui/src/locales/es/listViews.json. Leave the authoritative English catalogs
unchanged so fallbackLocale supplies these values.

Source: Learnings

@biggest-littlest biggest-littlest left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@ALARGECOMPANY ALARGECOMPANY left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@scttbnsn
scttbnsn merged commit b9d9873 into main Jul 31, 2026
42 of 43 checks passed
@scttbnsn
scttbnsn deleted the release/v1.6-rc10-main-sync branch July 31, 2026 21:10
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.

Update mode infrastructure can't locate helper container

3 participants