v1.5.0-rc.10 — 2026-04-19
Added
- #300 — Security scan digest mode. Every scan cycle (scheduled cron, on-demand single, or the new bulk
POST /api/v1/containers/scan-allendpoint) now carries a stablecycleId(UUID v7) and emits asecurity-scan-cycle-completeevent withscannedCount/alertCount/startedAt/completedAt/scope. Triggers can configureSECURITYMODE=digest(orbatch+digest) to receive one summary per cycle grouped by severity (critical → high → medium → low → unknown) instead of one notification per container. Templates are customizable viaSECURITYDIGESTTITLE/SECURITYDIGESTBODY. Per-channelonce=truededup is tracked under a new'security-alert-digest'NotificationEventKindso simple / batch / digest channels never stomp on each other (same per-channel pattern introduced for updates in #282). The UI Scan All button now issues one bulk-scan request instead of N per-container HTTP calls, so a 40-container inventory produces one email instead of forty. - Opt-in scheduled-scan notifications — New
DD_SECURITY_SCAN_NOTIFICATIONS=trueflag enablessecurity-alertevent emission from scheduled scans. Default isfalseto preserve pre-rc.10 behavior for existing users; on-demand scans always emit. Scheduled scans always emit thesecurity-scan-cycle-completeevent regardless of the flag (so audit-log and OpenTelemetry consumers see every cycle, even zero-alert ones). - Bulk security scan endpoint —
POST /api/v1/containers/scan-allscans all (or a filtered subset of) watched containers server-side, respects a bulk-scan concurrency pool, streams per-container progress over the existing scan SSE channel, emits a singlesecurity-scan-cycle-completeat the end, and honors client-disconnect aborts. Rate-limited to 1 request / 60s per IP (authenticated-admin bypass). - Container source project shortcut link (Discussion #295) — containers now render a clickable "View project" link next to release notes in detail panels and list cards when an
org.opencontainers.image.sourceOCI label,dd.source.repooverride label, or GHCR-derived source URL is available. The link uses a github/gitlab icon based on host, opens in a new tab, and reuses the existingsourceRepofield surfaced by the release-notes enrichment pipeline. No backend changes required. - Absolute-timestamp tooltip on watcher next-run column (Discussion #288) — the "next update check" column on the Watchers/Agents view (already shipped in a prior RC as a relative countdown like "in 14m") now surfaces the absolute local timestamp on hover (
Apr 18, 14:32:07), mirroring the Last-seen / Created pattern elsewhere in the UI. Primary display remains the live relative countdown; the dual-format improvement lets users correlate the next poll against logs, backups, or other scheduled work without mental arithmetic. - Actionable deprecation banners (Discussion #214) — the 5 deprecation warning banners (legacy
WUD_*env vars andwud.*labels, legacy API paths, curl healthcheck override, legacy password hash, OIDC HTTP discovery) now show the concrete migration action inline (e.g. "RenameWUD_*toDD_*") and include a "View migration guide" link that deep-jumps to the relevant anchored section of the deprecations docs page instead of the page root. New anchors added to/docs/deprecations:#legacy-env-vars,#legacy-labels,#legacy-trigger-prefix,#legacy-password-hashes,#curl-healthcheck-override,#oidc-http-discovery,#unversioned-api-paths. - Notification dropdown rework + themeable zebra stripes (Discussion #267) — the notification-bell dropdown has moved to the GitHub/Linear/Slack consensus layout: header carries the "Notifications" title plus a minimal "Clear" text button in the top-right for bulk dismissal, each row grows a per-entry ✕ dismiss affordance (hover-reveal on desktop, always-visible on touch devices via
@media (pointer: coarse)), and a split footer exposes "Mark all as read" + "Open audit log" as equal-weight actions. Replaces the bulk "Clear all" / "Mark all read" header pair that reporters had flagged as cramped. Dismissed entry IDs persist underdd-bell-dismissed-idsin localStorage (audit log is unaffected — the bell is a client-side read model) and Clear hides itself when there's nothing to dismiss. Introduces--dd-zebra-stripe, a new theme token derived viacolor-mix()from--dd-bg-card+--dd-text, so alternate-row striping stays legible on GitHub Dark, GitHub Light, and Ayu Light where the previous--dd-bg-insetfallback was visually identical to--dd-bg-card. (#9bccd456, #e823d953)
Changed
- Trigger digest flush DRY refactor —
flushDigestBuffer/shouldHandleDigestContainerReportare now parameterized on the event kind so update-digest and security-digest share a single implementation, keeping the rc.9 #282 dedup invariants (no cross-channel stomping, per-cycle partitioning) in one place instead of duplicated per feature.
Fixed
- Bulk security scan persistence —
POST /api/v1/containers/scan-allran Trivy scans, emitted alerts, and broadcastsecurity-scan-cycle-complete, but never wrote the scan result back to the container record — leaving the Security page on "0/N scanned — No vulnerability data yet" after every bulk cycle even when real CVEs were found, and losing all data on page reload. Fix persistsscanResulttocontainer.security.scanviastoreContainer.updateContainerand populates the Trivy digest scan cache, mirroring the single-container scan path. This was a regression introduced by the rc.10 bulk-scan feature itself; no prior build was ever working end-to-end. (#14b527be) - Notification bell icon collapse on scroll — In the notification bell dropdown, rows that had scrolled above the visible fold would lose their icon entirely — the
<iconify-icon>web component defaults todisplay: inline, so the flex item's reserved slot collapsed to zero width and subsequent row text left-aligned where the icon should have been. Fix sets explicitwidth,height,display: inline-block, andflex: nonevia inline style onAppIcon.vue(the shared icon wrapper) so the icon box stays reserved regardless of layout or intersection state. Applies project-wide because AppIcon is the shared wrapper all icons use. (#3acaafcd)