diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38a3ae6a3..3ca093940 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [1.6.0-rc.10] — 2026-07-31
+
### Added
- **Startup warning for minute-precise maintenance-window crons.** `DD_WATCHER_{name}_MAINTENANCE_WINDOW` is matched minute-by-minute, so a fixed minute field like `0 2-6 * * *` only opens the window for one minute per matching hour instead of the whole hour range — a common copy-paste trap reported in [Discussion #639](https://github.com/CodesWhat/drydock/discussions/639). The Docker watcher now logs a one-time warning at init when the configured window's minute field doesn't contain `*`, pointing at the fix (`* 2-3 * * *`). Step values like `*/5` are intentional and are not flagged.
@@ -18,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- **Translations resynced from Crowdin** ([#620](https://github.com/CodesWhat/drydock/pull/620)), refreshing the container-component and list-view catalogs across all 15 non-English locales, plus a fuller French pass over the agents, app-shell, common, and config catalogs.
+- **Routine dependency maintenance across the app and UI workspaces** ([#614](https://github.com/CodesWhat/drydock/pull/614), [#615](https://github.com/CodesWhat/drydock/pull/615), [#617](https://github.com/CodesWhat/drydock/pull/617), [#646](https://github.com/CodesWhat/drydock/pull/646)): undici 8.9.0 (app) and the 7.29.0 UI override, express-rate-limit 8.6.1, @aws-sdk/client-ecr 3.1096.0, vue-i18n 11.4.8, knip 6.29.0, postcss 8.5.24, and the `fast-uri` security override advanced from 3.1.4 to 4.1.1 (both retain the CVE-2026-16221 fix; the dependency-version guard now rejects the still-vulnerable 4.0.0–4.1.0 range). Renovate no longer proposes `@babel/core` majors while Stryker's instrumenter requires Babel 7.
### Fixed
@@ -2295,7 +2298,8 @@ Remaining upstream-only changes (not ported — not applicable to drydock):
| Fix codeberg tests | Covered by drydock's own tests |
| Update changelog | Upstream-specific |
-[Unreleased]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.9...HEAD
+[Unreleased]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.10...HEAD
+[1.6.0-rc.10]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.9...v1.6.0-rc.10
[1.6.0-rc.9]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.8...v1.6.0-rc.9
[1.6.0-rc.8]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.7...v1.6.0-rc.8
[1.6.0-rc.7]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.6...v1.6.0-rc.7
diff --git a/README.md b/README.md
index 901f3df9a..48e13e6ea 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
-
+
@@ -178,7 +178,7 @@ See the [Quick Start guide](https://getdrydock.com/docs/quickstart) for Docker C
🆕 Recent Updates
-v1.6.0-rc.9 highlights
+v1.6.0-rc.10 highlights
- **Notifications** — Per-rule/per-provider title and body templates with live preview, plus audit-backed in-app bell categories and update severity thresholds.
- **Dashboard** — Zero-dependency CSS Grid replacement with mouse/touch reorder, bounded resize, responsive layouts, widget visibility, reset, and optional cross-device preference sync.
diff --git a/apps/demo/src/mocks/data/agents.ts b/apps/demo/src/mocks/data/agents.ts
index 663f6ffd4..dd5b19834 100644
--- a/apps/demo/src/mocks/data/agents.ts
+++ b/apps/demo/src/mocks/data/agents.ts
@@ -4,7 +4,7 @@ export const agents = [
host: '192.168.1.50',
port: 3001,
connected: true,
- version: '1.6.0-rc.9',
+ version: '1.6.0-rc.10',
os: 'linux',
arch: 'amd64',
cpus: 4,
diff --git a/apps/demo/src/mocks/data/audit.ts b/apps/demo/src/mocks/data/audit.ts
index c5add9057..f122b4aaf 100644
--- a/apps/demo/src/mocks/data/audit.ts
+++ b/apps/demo/src/mocks/data/audit.ts
@@ -3,7 +3,7 @@ export const auditEntries = [
id: 'aud-001',
timestamp: '2026-03-10T08:00:00.000Z',
action: 'system:start',
- details: 'Drydock v1.6.0-rc.9 started',
+ details: 'Drydock v1.6.0-rc.10 started',
},
{
id: 'aud-002',
@@ -207,6 +207,6 @@ export const auditEntries = [
timestamp: '2026-03-03T18:00:00.000Z',
action: 'container:watch',
container: 'drydock',
- details: 'Started watching ghcr.io/codeswhat/drydock:1.6.0-rc.9',
+ details: 'Started watching ghcr.io/codeswhat/drydock:1.6.0-rc.10',
},
];
diff --git a/apps/demo/src/mocks/data/containers.ts b/apps/demo/src/mocks/data/containers.ts
index f31c76192..38969ab10 100644
--- a/apps/demo/src/mocks/data/containers.ts
+++ b/apps/demo/src/mocks/data/containers.ts
@@ -330,7 +330,7 @@ export const containers = [
displayName: 'Drydock',
displayIcon: 'sh-drydock',
image: 'codeswhat/drydock',
- tag: '1.6.0-rc.9',
+ tag: '1.6.0-rc.10',
registryType: 'ghcr',
registryUrl: 'https://ghcr.io',
scanStatus: 'scanned',
diff --git a/apps/demo/src/mocks/data/server.ts b/apps/demo/src/mocks/data/server.ts
index 0565140a3..4bf860574 100644
--- a/apps/demo/src/mocks/data/server.ts
+++ b/apps/demo/src/mocks/data/server.ts
@@ -1,5 +1,5 @@
export const serverInfo = {
- version: '1.6.0-rc.9',
+ version: '1.6.0-rc.10',
uptime: 864000,
hostname: 'drydock-demo',
platform: 'linux',
diff --git a/apps/demo/src/mocks/handlers/app.ts b/apps/demo/src/mocks/handlers/app.ts
index b0daff4ba..1eeeb4746 100644
--- a/apps/demo/src/mocks/handlers/app.ts
+++ b/apps/demo/src/mocks/handlers/app.ts
@@ -4,7 +4,7 @@ export const appHandlers = [
http.get('/api/v1/app', () =>
HttpResponse.json({
name: 'Drydock',
- version: '1.6.0-rc.9',
+ version: '1.6.0-rc.10',
description: 'Docker container update manager',
repository: 'https://github.com/CodesWhat/drydock',
documentation: 'https://getdrydock.com/docs',
@@ -16,7 +16,7 @@ export const appHandlers = [
return HttpResponse.json(
{
generatedAt: new Date().toISOString(),
- server: { version: '1.6.0-rc.9', mode: 'demo' },
+ server: { version: '1.6.0-rc.10', mode: 'demo' },
summary: {
containers: 25,
watchers: 2,
diff --git a/apps/web/src/lib/site-config.ts b/apps/web/src/lib/site-config.ts
index 1c595af49..d1c000ddc 100644
--- a/apps/web/src/lib/site-config.ts
+++ b/apps/web/src/lib/site-config.ts
@@ -15,7 +15,7 @@ export const SITE_CONFIG = {
/** Brand name shown in the header, footer, and metadata. */
name: "Drydock",
/** Current release version shown in the hero badge. */
- version: "1.6.0-rc.9",
+ version: "1.6.0-rc.10",
/** Short product tagline used in page titles and OG metadata. */
tagline: "Container Update Monitoring",
/** Default meta / OpenGraph / Twitter description. */
diff --git a/apps/web/src/lib/site-content.ts b/apps/web/src/lib/site-content.ts
index 93a622701..c7f21de78 100644
--- a/apps/web/src/lib/site-content.ts
+++ b/apps/web/src/lib/site-content.ts
@@ -281,7 +281,7 @@ export const roadmap: Milestone[] = [
],
},
{
- version: "v1.6.0-rc.9",
+ version: "v1.6.0-rc.10",
title: "Notifications, Policy & Release Intel",
emoji: "\u{1F4E8}",
status: "next",
diff --git a/content/docs/current/api/agent.mdx b/content/docs/current/api/agent.mdx
index 298b8b43a..2970f5ab6 100644
--- a/content/docs/current/api/agent.mdx
+++ b/content/docs/current/api/agent.mdx
@@ -23,7 +23,7 @@ curl http://drydock:3000/api/v1/agents
"host": "192.168.1.50",
"port": 3000,
"connected": true,
- "version": "1.6.0-rc.9",
+ "version": "1.6.0-rc.10",
"os": "linux",
"arch": "amd64",
"cpus": 4,
@@ -153,7 +153,7 @@ Sent immediately upon connection to confirm the handshake.
{
"type": "dd:ack",
"data": {
- "version": "1.6.0-rc.9",
+ "version": "1.6.0-rc.10",
"os": "linux",
"arch": "amd64",
"cpus": 4,
diff --git a/content/docs/current/api/app.mdx b/content/docs/current/api/app.mdx
index 4055597da..ecf0cb0f8 100644
--- a/content/docs/current/api/app.mdx
+++ b/content/docs/current/api/app.mdx
@@ -12,7 +12,7 @@ curl http://drydock:3000/api/v1/app
{
"name":"drydock",
- "version":"1.6.0-rc.9"
+ "version":"1.6.0-rc.10"
}
```
diff --git a/content/docs/current/api/portwing.mdx b/content/docs/current/api/portwing.mdx
index 1318f710e..321c6ba30 100644
--- a/content/docs/current/api/portwing.mdx
+++ b/content/docs/current/api/portwing.mdx
@@ -162,7 +162,7 @@ A versioned alias `/api/v1/portwing/ws` is also accepted and is signature-equiva
"agentId": "edge-host-01",
"agentName": "edge-host-01",
"protocol": "portwing/1.0",
- "version": "1.6.0-rc.9",
+ "version": "1.6.0-rc.10",
"pubKeyId": "3f8a1c2e9b047d56",
"timestamp": 1780329600,
"nonce": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
@@ -185,7 +185,7 @@ A name collision with an already-connected agent under the same key (or the in-f
"data": {
"pollInterval": 300,
"config": {
- "drydockVersion": "1.6.0-rc.9",
+ "drydockVersion": "1.6.0-rc.10",
"supportedProtocols": "portwing/1.0",
"serverCompatLevel": "1.4.0"
}
diff --git a/content/docs/current/quickstart/index.mdx b/content/docs/current/quickstart/index.mdx
index 63fe94571..d718e3633 100644
--- a/content/docs/current/quickstart/index.mdx
+++ b/content/docs/current/quickstart/index.mdx
@@ -108,7 +108,7 @@ Release tags use the same channel names in every registry:
| Tag | Behavior |
| --- | --- |
-| `1.6.0-rc.9` | Immutable release candidate; best for reproducible testing |
+| `1.6.0-rc.10` | Immutable release candidate; best for reproducible testing |
| `1.6-rc` | Rolling release-candidate channel; moves to the newest `1.6.0-rc.N` |
| `1.6` | Rolling stable minor channel; published only for GA releases |
| `1` | Rolling stable major channel; published only for GA releases |
diff --git a/content/docs/current/updates/index.mdx b/content/docs/current/updates/index.mdx
index 60cdb1025..0b76fcd61 100644
--- a/content/docs/current/updates/index.mdx
+++ b/content/docs/current/updates/index.mdx
@@ -3,6 +3,14 @@ title: "Updates"
description: "Release update notes and feature highlights, with direct links to current configuration and API docs."
---
+## v1.6.0-rc.10 Highlights — July 31, 2026
+
+- **Infrastructure-mode self-updates no longer fail to spawn the helper container on Docker Hub installs** — for containers labeled `dd.update.mode=infrastructure`, the helper image reference is now resolved through the registry provider's `getImageFullName` normalization instead of a raw Hub URL, so it matches the daemon-local image name and the helper actually pulls ([#645](https://github.com/CodesWhat/drydock/pull/645), fixes [#644](https://github.com/CodesWhat/drydock/issues/644)).
+- **Startup warning for minute-precise maintenance-window crons** — the Docker watcher now logs a one-time warning at init when `DD_WATCHER_{name}_MAINTENANCE_WINDOW`'s minute field doesn't contain `*`, a common copy-paste trap that opens the window for one minute per hour instead of the whole range; the update confirm dialog also links to the update-eligibility reasons reference ([Discussion #639](https://github.com/CodesWhat/drydock/discussions/639)).
+- **Unchanged `update-available` audit entries are no longer re-recorded on a timer** — audit rows are now written only on first detection or when the update target/kind changes, instead of every time the dedupe window lapses ([#642](https://github.com/CodesWhat/drydock/pull/642)).
+- **Maintenance-window documentation corrected** — examples now use `* 2-6 * * *` instead of a minute-precise cron that was described as an hourly range, and the update confirm dialog's wording is documented verbatim in [Update Eligibility & Blockers](https://getdrydock.com/docs/configuration/actions/update-eligibility) ([#640](https://github.com/CodesWhat/drydock/pull/640)).
+- **Translations resynced from Crowdin** ([#620](https://github.com/CodesWhat/drydock/pull/620)) and routine dependency maintenance across the app and UI workspaces, including the `fast-uri` security override advancing to 4.1.1 ([#614](https://github.com/CodesWhat/drydock/pull/614), [#615](https://github.com/CodesWhat/drydock/pull/615), [#617](https://github.com/CodesWhat/drydock/pull/617), [#646](https://github.com/CodesWhat/drydock/pull/646)).
+
## v1.6.0-rc.9 Highlights — July 28, 2026
- **Portwing edge log streaming is on by default** — the authenticated container-log WebSocket now bridges correlated chunk/end/error frames from the edge gateway, cancels the agent stream when the viewer closes, and caps each downstream viewer at 1 MiB of buffered data; older Portwing agents degrade gracefully to their one-shot response. `DD_EXPERIMENTAL_PORTWING=false` remains available as an emergency disable.
diff --git a/scripts/changelog-links.test.mjs b/scripts/changelog-links.test.mjs
index 5d119b527..21a9ab7b9 100644
--- a/scripts/changelog-links.test.mjs
+++ b/scripts/changelog-links.test.mjs
@@ -56,7 +56,8 @@ test('every linked changelog heading has exactly one link definition', () => {
test('v1.6 RC and v1.5.2 GA have a complete chronological comparison-link chain', () => {
const definitions = new Map(getLinkDefinitions(changelog).map(({ label, url }) => [label, url]));
const expected = new Map([
- ['Unreleased', `${repositoryUrl}/compare/v1.6.0-rc.9...HEAD`],
+ ['Unreleased', `${repositoryUrl}/compare/v1.6.0-rc.10...HEAD`],
+ ['1.6.0-rc.10', `${repositoryUrl}/compare/v1.6.0-rc.9...v1.6.0-rc.10`],
['1.6.0-rc.9', `${repositoryUrl}/compare/v1.6.0-rc.8...v1.6.0-rc.9`],
['1.6.0-rc.8', `${repositoryUrl}/compare/v1.6.0-rc.7...v1.6.0-rc.8`],
['1.6.0-rc.7', `${repositoryUrl}/compare/v1.6.0-rc.6...v1.6.0-rc.7`],
diff --git a/scripts/release-docs-identity.test.mjs b/scripts/release-docs-identity.test.mjs
index 3836b0e93..f69641597 100644
--- a/scripts/release-docs-identity.test.mjs
+++ b/scripts/release-docs-identity.test.mjs
@@ -2,10 +2,10 @@ import assert from 'node:assert/strict';
import { readdirSync, readFileSync } from 'node:fs';
import test from 'node:test';
-const RC_VERSION = '1.6.0-rc.9';
-const PREV_RC_VERSION = '1.6.0-rc.8';
-const RC_DATE = '2026-07-28';
-const RC_DISPLAY_DATE = 'July 28, 2026';
+const RC_VERSION = '1.6.0-rc.10';
+const PREV_RC_VERSION = '1.6.0-rc.9';
+const RC_DATE = '2026-07-31';
+const RC_DISPLAY_DATE = 'July 31, 2026';
const DOC_ROOTS = ['content/docs/current', 'content/docs/v1.5'];
const BROAD_401_CLAIM =
/(?:all|every) API (?:call|request)s?(?: (?:is|are) rejected with| returns?) `401`/iu;
diff --git a/scripts/release-identity.test.mjs b/scripts/release-identity.test.mjs
index b84101838..2f431a3d6 100644
--- a/scripts/release-identity.test.mjs
+++ b/scripts/release-identity.test.mjs
@@ -3,7 +3,7 @@ import { readFileSync } from 'node:fs';
import test from 'node:test';
const BASE_VERSION = '1.6.0';
-const RC_VERSION = '1.6.0-rc.9';
+const RC_VERSION = '1.6.0-rc.10';
const DEMO_RELEASE_FIXTURES = [
{
path: 'apps/demo/src/mocks/data/server.ts',