diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee2fd7963..a849891ee 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.9] — 2026-07-28
+
### Added
- **Continuous Portwing edge log streams.** The authenticated container-log WebSocket now bridges correlated `dd:container_log_chunk`, `dd:container_log_end`, and `dd:container_log_error` frames, cancels the agent stream when the viewer closes, preserves stdout/stderr and timestamp decoding, and caps each downstream viewer at 1 MiB of buffered data. Older Portwing agents degrade to their one-shot response without breaking the viewer.
@@ -19,6 +21,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **The `portwing/1.0` edge endpoint is enabled by default.** `DD_EXPERIMENTAL_PORTWING=false` remains as an emergency disable for new edge connections. OpenAPI, operator docs, and translated feature summaries now describe the stable/default-on behavior.
+### Fixed
+
+- **The row "Updating/Queued/Scanning" overlay chip is no longer clipped at the pinned-column edge.** The table's pinned identity-cluster cells (`sticky z-10`) painted over the full-width row overlay hosted in the first cell and cut the centered chip in half at the cluster boundary. While an overlay is active the host cell now sits above its z-10 row siblings (and still below the sticky header). ([#631](https://github.com/CodesWhat/drydock/pull/631))
+- **Registry errors no longer replace the container's tag in the tag column.** A rate-limit/auth/not-found registry error rendered a danger pill instead of the current tag (table mode) or appended one (card mode), duplicating the warning glyph + tooltip the registry column already shows. The tag cell now always shows the actual tag; the registry column glyph remains the single error flag. ([#631](https://github.com/CodesWhat/drydock/pull/631))
+
## [1.6.0-rc.8] — 2026-07-28
### Fixed
@@ -2273,7 +2280,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.8...HEAD
+[Unreleased]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.9...HEAD
+[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
[1.6.0-rc.6]: https://github.com/CodesWhat/drydock/compare/v1.6.0-rc.5...v1.6.0-rc.6
diff --git a/README.md b/README.md
index 2f8cbc86b..901f3df9a 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.8 highlights
+v1.6.0-rc.9 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 b44736bfa..663f6ffd4 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.8',
+ version: '1.6.0-rc.9',
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 36205c822..c5add9057 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.8 started',
+ details: 'Drydock v1.6.0-rc.9 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.8',
+ details: 'Started watching ghcr.io/codeswhat/drydock:1.6.0-rc.9',
},
];
diff --git a/apps/demo/src/mocks/data/containers.ts b/apps/demo/src/mocks/data/containers.ts
index c0c627bae..f31c76192 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.8',
+ tag: '1.6.0-rc.9',
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 9b9cbbcf5..0565140a3 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.8',
+ version: '1.6.0-rc.9',
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 bf78f8581..b0daff4ba 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.8',
+ version: '1.6.0-rc.9',
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.8', mode: 'demo' },
+ server: { version: '1.6.0-rc.9', 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 d5f22ddf0..1c595af49 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.8",
+ version: "1.6.0-rc.9",
/** 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 cc96c6554..93a622701 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.8",
+ version: "v1.6.0-rc.9",
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 66cb07506..298b8b43a 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.8",
+ "version": "1.6.0-rc.9",
"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.8",
+ "version": "1.6.0-rc.9",
"os": "linux",
"arch": "amd64",
"cpus": 4,
diff --git a/content/docs/current/api/app.mdx b/content/docs/current/api/app.mdx
index 271706869..4055597da 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.8"
+ "version":"1.6.0-rc.9"
}
```
diff --git a/content/docs/current/api/portwing.mdx b/content/docs/current/api/portwing.mdx
index 30005cc1a..278085e47 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.8",
+ "version": "1.6.0-rc.9",
"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.8",
+ "drydockVersion": "1.6.0-rc.9",
"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 9829f01f3..63fe94571 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.8` | Immutable release candidate; best for reproducible testing |
+| `1.6.0-rc.9` | 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 a6cebb71b..60cdb1025 100644
--- a/content/docs/current/updates/index.mdx
+++ b/content/docs/current/updates/index.mdx
@@ -3,6 +3,12 @@ title: "Updates"
description: "Release update notes and feature highlights, with direct links to current configuration and API docs."
---
+## 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.
+- **The row status overlay is no longer clipped at the pinned-column edge** — the "Updating/Queued/Scanning" chip is now layered above the sticky identity-cluster cells instead of being cut in half at the cluster boundary ([#631](https://github.com/CodesWhat/drydock/pull/631)).
+- **Registry errors no longer replace the container's tag** — a rate-limit/auth/not-found registry error used to overwrite or duplicate the tag cell with a danger pill; the tag column now always shows the actual tag, with the registry column glyph remaining the single error flag ([#631](https://github.com/CodesWhat/drydock/pull/631)).
+
## v1.6.0-rc.8 Highlights — July 28, 2026
- **Agent-managed containers keep their update policy** — remote agents never learn controller-side runtime overrides, so every agent report carried an empty override layer that the controller persisted verbatim, wiping maturity mode, min-age days, skip lists, and snoozes on every sync or recheck. The controller now reapplies its stored overrides when ingesting agent reports, and the store only honors an empty override layer when the update-policy API marks the clear as deliberate — so settings finally survive agent syncs while UI clears still stick ([#565](https://github.com/CodesWhat/drydock/issues/565)).
diff --git a/scripts/changelog-links.test.mjs b/scripts/changelog-links.test.mjs
index 769dd2848..5d119b527 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.8...HEAD`],
+ ['Unreleased', `${repositoryUrl}/compare/v1.6.0-rc.9...HEAD`],
+ ['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`],
['1.6.0-rc.6', `${repositoryUrl}/compare/v1.6.0-rc.5...v1.6.0-rc.6`],
diff --git a/scripts/release-docs-identity.test.mjs b/scripts/release-docs-identity.test.mjs
index a634799d7..3836b0e93 100644
--- a/scripts/release-docs-identity.test.mjs
+++ b/scripts/release-docs-identity.test.mjs
@@ -2,8 +2,8 @@ import assert from 'node:assert/strict';
import { readdirSync, readFileSync } from 'node:fs';
import test from 'node:test';
-const RC_VERSION = '1.6.0-rc.8';
-const PREV_RC_VERSION = '1.6.0-rc.7';
+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 DOC_ROOTS = ['content/docs/current', 'content/docs/v1.5'];
diff --git a/scripts/release-identity.test.mjs b/scripts/release-identity.test.mjs
index 60b2d276a..b84101838 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.8';
+const RC_VERSION = '1.6.0-rc.9';
const DEMO_RELEASE_FIXTURES = [
{
path: 'apps/demo/src/mocks/data/server.ts',