From 0966ad1acd52774cf3f22ee08ed2db919dbb8575 Mon Sep 17 00:00:00 2001
From: scttbnsn <80784472+scttbnsn@users.noreply.github.com>
Date: Tue, 4 Aug 2026 19:16:59 -0400
Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20chore(release):=20cut=20v1.6.0-r?=
=?UTF-8?q?c.12?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Renames Unreleased to [1.6.0-rc.12] — 2026-08-04 and rolls the release
identity forward across README, site config/content, quickstart tag
matrix, demo mocks, API docs, updates highlights, and the identity/link
tests. Adds the routine dependency-maintenance rollup entry (#653, #654,
#655, #656, #664) and the Crowdin sync note (#665).
rc.12 contents: security pins #659 (brace-expansion 5.0.9, ip-address
10.3.1, fast-uri 4.1.2), #604 maturity clock, #605 agent-mismatch grace,
#636 WS anonymous auth, #637 explicit 501.
---
CHANGELOG.md | 10 +++++++++-
README.md | 13 ++++++++++++-
apps/demo/src/mocks/data/agents.ts | 2 +-
apps/demo/src/mocks/data/audit.ts | 4 ++--
apps/demo/src/mocks/data/containers.ts | 2 +-
apps/demo/src/mocks/data/server.ts | 2 +-
apps/demo/src/mocks/handlers/app.ts | 4 ++--
apps/web/src/lib/site-config.ts | 2 +-
apps/web/src/lib/site-content.ts | 2 +-
content/docs/current/api/agent.mdx | 4 ++--
content/docs/current/api/app.mdx | 2 +-
content/docs/current/api/portwing.mdx | 4 ++--
content/docs/current/quickstart/index.mdx | 2 +-
content/docs/current/updates/index.mdx | 8 ++++++++
scripts/changelog-links.test.mjs | 3 ++-
scripts/release-docs-identity.test.mjs | 8 ++++----
scripts/release-identity.test.mjs | 2 +-
17 files changed, 51 insertions(+), 23 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8cb2096df..d193d3aac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [1.6.0-rc.12] — 2026-08-04
+
+### Changed
+
+- **Routine dependency maintenance across the root tooling, demo, UI, and website workspaces** ([#653](https://github.com/CodesWhat/drydock/pull/653), [#654](https://github.com/CodesWhat/drydock/pull/654), [#655](https://github.com/CodesWhat/drydock/pull/655), [#656](https://github.com/CodesWhat/drydock/pull/656)). The dependency-version guard's Next.js check became a 16.x floor instead of an exact pin so routine patch bumps stop tripping it ([#664](https://github.com/CodesWhat/drydock/pull/664)).
+- **Crowdin translation sync** ([#665](https://github.com/CodesWhat/drydock/pull/665)): one French container-component string corrected.
+
### Fixed
- **"Agent Mismatch" no longer appears in the container list/SSE display during the brief window an agent's docker/dockercompose trigger is still (re)registering** ([#605](https://github.com/CodesWhat/drydock/issues/605)). Eligibility is recomputed live on every read, and `AgentClient._doHandshake()` deregisters the agent's components before awaiting the `/api/triggers` fetch and re-register. A read in that window found zero triggers for the agent and `computeUpdateEligibility` raised a hard `agent-mismatch` blocker, disabling the Update button, even though nothing was actually misconfigured — the condition self-corrected once registration finished. `agent-mismatch` now downgrades to a soft blocker (button stays enabled) on display surfaces whenever the container's own agent is mid-registration, per the new `AgentClient.isRegisteringComponents` flag (true only for the deregister→re-register span, not the whole reconnect backoff). Update **admission** (`app/updates/request-update.ts`) is unaffected and stays hard/fail-closed throughout, so an update can never be enqueued through a wrong-agent trigger during that window.
@@ -2319,7 +2326,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.11...HEAD
+[Unreleased]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.12...HEAD
+[1.6.0-rc.12]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.11...v1.6.0-rc.12
[1.6.0-rc.11]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.10...v1.6.0-rc.11
[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
diff --git a/README.md b/README.md
index b4ba72192..30153d62e 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
-
+
@@ -178,6 +178,17 @@ See the [Quick Start guide](https://getdrydock.com/docs/quickstart) for Docker C
🆕 Recent Updates
+v1.6.0-rc.12 highlights
+
+- **Security dependency refresh** — `brace-expansion` 5.0.9 (app/UI/e2e, CVE-2026-69152), `ip-address` 10.3.1 (app runtime, CVE-2026-54272/-69192/-69198), and `fast-uri` 4.1.2 (app/UI, CVE-2026-18446). ([#659](https://github.com/CodesWhat/drydock/pull/659))
+- **Maturity clock** — the hot/mature badge resolves per-container `updatePolicy.maturityMinAgeDays` before the global threshold, matching the gate, and registry publish-date failures log at `warn` instead of disappearing at `debug`. ([#604](https://github.com/CodesWhat/drydock/issues/604))
+- **Agent registration grace** — transient `agent-mismatch`/`no-update-trigger-configured` blockers soften on display surfaces while an agent's components re-register; admission stays fail-closed. ([#605](https://github.com/CodesWhat/drydock/issues/605))
+- **WS log streams + anonymous auth** — log-stream WebSocket upgrades accept sessions when anonymous authentication is the registered mode. ([#636](https://github.com/CodesWhat/drydock/issues/636))
+- **Explicit 501s** — lifecycle actions on agent containers without controller Docker transport return 501 naming the cause instead of an ambiguous 404. ([#637](https://github.com/CodesWhat/drydock/issues/637))
+
+
+
+
v1.6.0-rc.11 highlights
- **Portwing transport** — Portwing 0.9.0's exact `transport=docker-api`, `execution=controller`, `events=portwing` marker now routes native registry checks, single/batch updates, start/stop/restart, update previews, and backup rollbacks through authenticated Standard HTTP or Edge request/response/stream transport. Portwing remains the lifecycle-event source, and raw inventory cannot erase controller-enriched update results. ([#632](https://github.com/CodesWhat/drydock/issues/632), [#637](https://github.com/CodesWhat/drydock/issues/637), [Portwing #76](https://github.com/CodesWhat/portwing/issues/76))
diff --git a/apps/demo/src/mocks/data/agents.ts b/apps/demo/src/mocks/data/agents.ts
index 3c70dc8a5..5e30b6425 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.11',
+ version: '1.6.0-rc.12',
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 b4935a92f..dc58412f4 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.11 started',
+ details: 'Drydock v1.6.0-rc.12 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.11',
+ details: 'Started watching ghcr.io/codeswhat/drydock:1.6.0-rc.12',
},
];
diff --git a/apps/demo/src/mocks/data/containers.ts b/apps/demo/src/mocks/data/containers.ts
index 312a64bf2..500f3ff39 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.11',
+ tag: '1.6.0-rc.12',
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 2ef6c05c4..c0154f8ae 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.11',
+ version: '1.6.0-rc.12',
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 dc86a04c1..1d6f781ff 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.11',
+ version: '1.6.0-rc.12',
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.11', mode: 'demo' },
+ server: { version: '1.6.0-rc.12', 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 224da539f..416395f6b 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.11",
+ version: "1.6.0-rc.12",
/** 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 8711146f7..31b54387c 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.11",
+ version: "v1.6.0-rc.12",
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 0d733b186..7faf7d032 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.11",
+ "version": "1.6.0-rc.12",
"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.11",
+ "version": "1.6.0-rc.12",
"os": "linux",
"arch": "amd64",
"cpus": 4,
diff --git a/content/docs/current/api/app.mdx b/content/docs/current/api/app.mdx
index ef618d865..adb8430d1 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.11"
+ "version":"1.6.0-rc.12"
}
```
diff --git a/content/docs/current/api/portwing.mdx b/content/docs/current/api/portwing.mdx
index fb870bd26..36b692e5a 100644
--- a/content/docs/current/api/portwing.mdx
+++ b/content/docs/current/api/portwing.mdx
@@ -197,7 +197,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.11",
+ "version": "1.6.0-rc.12",
"pubKeyId": "3f8a1c2e9b047d56",
"timestamp": 1780329600,
"nonce": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
@@ -220,7 +220,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.11",
+ "drydockVersion": "1.6.0-rc.12",
"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 27b31900c..f0c50bbd4 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.11` | Immutable release candidate; best for reproducible testing |
+| `1.6.0-rc.12` | 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 f6a1c6d62..e32a8c3f3 100644
--- a/content/docs/current/updates/index.mdx
+++ b/content/docs/current/updates/index.mdx
@@ -5,6 +5,14 @@ description: "Release update notes and feature highlights, with direct links to
## Unreleased
+## v1.6.0-rc.12 Highlights — August 4, 2026
+
+- **Security dependency refresh** — `brace-expansion` advanced to 5.0.9 across the app, UI, and e2e workspaces (CVE-2026-69152), `ip-address` to 10.3.1 in the app runtime (CVE-2026-54272, CVE-2026-69192, CVE-2026-69198), and `fast-uri` to 4.1.2 in app and UI (backslash-authority host confusion, CVE-2026-18446) ([#659](https://github.com/CodesWhat/drydock/pull/659)).
+- **Maturity badge and gate agree again** — the hot/mature badge now resolves each container's own `updatePolicy.maturityMinAgeDays` before the global `DD_UI_MATURITY_THRESHOLD_DAYS`, matching the gate, and registry publish-date lookup failures (including GHCR/LSCR auth errors) log at `warn` instead of vanishing at `debug` ([#604](https://github.com/CodesWhat/drydock/issues/604)).
+- **No more transient "Agent Mismatch"** — the container list and SSE stream soften `agent-mismatch`/`no-update-trigger-configured` to soft blockers while an agent's components are mid-(re)registration; update admission stays fail-closed throughout ([#605](https://github.com/CodesWhat/drydock/issues/605)).
+- **WebSocket log streams accept anonymous-auth sessions** — under `DD_ANONYMOUS_AUTH_CONFIRM=true`, both the system and container log-stream upgrades now pass the same auth gate as every REST endpoint ([#636](https://github.com/CodesWhat/drydock/issues/636)).
+- **Explicit 501 for missing agent lifecycle transport** — start/stop/restart/rollback on an agent-owned container without controller Docker transport returns a 501 naming the cause instead of an ambiguous 404 ([#637](https://github.com/CodesWhat/drydock/issues/637)).
+
## v1.6.0-rc.11 Highlights — August 1, 2026
- **Portwing 0.9 Docker watcher, updates, and lifecycle actions now run controller-side** — Drydock 1.6.0-rc.11+ recognizes the exact `transport=docker-api`, `execution=controller`, `events=portwing` watcher marker, starts its native registry checks and Docker action against a loopback-only authenticated bridge, and carries Docker calls over Standard HTTP or Edge correlated request/response/stream transport. Single/batch updates, start/stop/restart, update preview, and backup rollback use this path even though Portwing advertises no remote trigger. Portwing stays authoritative for lifecycle events, and raw false/unknown inventory no longer erases controller enrichment ([#632](https://github.com/CodesWhat/drydock/issues/632), [#637](https://github.com/CodesWhat/drydock/issues/637), [Portwing #76](https://github.com/CodesWhat/portwing/issues/76)).
diff --git a/scripts/changelog-links.test.mjs b/scripts/changelog-links.test.mjs
index 180c02d87..86e816bd9 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.11...HEAD`],
+ ['Unreleased', `${repositoryUrl}/compare/v1.6.0-rc.12...HEAD`],
+ ['1.6.0-rc.12', `${repositoryUrl}/compare/v1.6.0-rc.11...v1.6.0-rc.12`],
['1.6.0-rc.11', `${repositoryUrl}/compare/v1.6.0-rc.10...v1.6.0-rc.11`],
['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`],
diff --git a/scripts/release-docs-identity.test.mjs b/scripts/release-docs-identity.test.mjs
index b1c1cc764..5f71f390b 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.11';
-const PREV_RC_VERSION = '1.6.0-rc.10';
-const RC_DATE = '2026-08-01';
-const RC_DISPLAY_DATE = 'August 1, 2026';
+const RC_VERSION = '1.6.0-rc.12';
+const PREV_RC_VERSION = '1.6.0-rc.11';
+const RC_DATE = '2026-08-04';
+const RC_DISPLAY_DATE = 'August 4, 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 0e77d78c4..7d6dbfdc8 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.11';
+const RC_VERSION = '1.6.0-rc.12';
const DEMO_RELEASE_FIXTURES = [
{
path: 'apps/demo/src/mocks/data/server.ts',