* fix(deploy-enforcement): surface scan-policy blocks on update and sidebar deploys
A blocked deploy only opened the policy dialog from the editor deploy
button. The update action and the sidebar context-menu deploy/update
fell through to a generic error toast, so an admin could not review the
violations or bypass the block from those entry points. Route the 409
policy response through a shared handler on all three paths and make the
"Deploy anyway" bypass retry the originating action (deploy or update)
so an update bypass still re-pulls images.
Also:
- Correct the "Block on deploy" policy-editor helper text, which
described post-deploy alerting rather than the pre-flight rejection it
actually performs.
- Dispatch the documented scan_finding warning (policy name and the
offending images) when a scheduled auto-update or auto-start is
blocked, instead of recording an opaque failure.
- Add a standard log line when the gate blocks a deploy, plus
developer-mode diagnostics for the matched policy and per-image
severity decision.
- Fix deploy-enforcement docs: complete the enforced entry-point list,
correct the policy-precedence wording, and remove inaccurate tier and
audit-actor claims.
* fix(deploy-enforcement): surface policy block on rollback and name images in remote auto-update alert
Addresses two gaps found in independent review:
- Rollback is a policy-gated deploy path (it restores the saved files then
re-runs the gate before redeploying), but the frontend treated a blocked
rollback as a generic error toast. Route the 409 through the same handler
as deploy and update so the block dialog opens, and let an admin "Deploy
anyway" retry the rollback with the bypass flag (the rollback route already
honors it).
- The remote auto-update path dispatched its policy-block warning without the
offending image refs, unlike the local scheduler. Append the images so the
alert matches the documented contract on every node.
Also list rollback as an enforced entry point in the docs and clarify that
Git Source enforcement covers both the create-time deploy and a manual
apply-with-deploy.
* feat(frontend): add SystemSheet primitive and migrate mesh sheets to §9.11 chrome
DESIGN.md §9.11 codifies one canonical right-side detail-sheet shell (cyan
rail, mono crumb, italic serif name, mono meta, ESC chip + close glyph,
fixed three-slot toolbar, cyan-underline tabs, ScrollArea body, footer
freshness band). Today the 16 sheet consumers each render their own
header chrome with stock shadcn SheetHeader/SheetTitle.
Introduce <SystemSheet> + <SheetSection> in
frontend/src/components/ui/system-sheet.tsx, composing the existing
<Sheet>/<SheetContent> primitive. Add a backward-compatible showClose
prop to SheetContent so SystemSheet can render its own ESC chip + close
glyph instead of the stock cyan square close.
Migrate the four mesh sheets as the first batch:
* MeshActivitySheet: crumb Fleet › Mesh › Activity, footer freshness from
most-recent event timestamp.
* MeshOptInSheet: crumb Fleet › Mesh › {nodeName}, meta of opted-in
count, drops the redundant bottom Close button (ESC chip dismisses).
* MeshDiagnosticsSheet: removes the icon-prefixed title (forbidden by
§9.11), lifts Refresh/Restart buttons from the body into the toolbar
band, three SheetSection blocks for sidecar status, streams, cache.
* MeshRouteDetailSheet: adds Overview/Events/Raw tabs, lifts Test probe
into the toolbar primary slot, footer surfaces last probe latency.
* feat(frontend): migrate security and scheduled sheets to §9.11 chrome
PR 2 of the System Sheet (§9.11) rollout, stacked on the SystemSheet
primitive PR. Migrates six more sheet consumers and merges the Stack
alert + auto-heal sheets into a single tabbed sheet per audit §17.
Sheets migrated:
* NodeUpdatesSheet: crumb Fleet > Updates, Recheck primary, Update-all
secondary when applicable. Stat tiles and node rows lose their
card-in-sheet wrapping (forbidden by §9.11) for flat dividers.
* StackAlertSheet (now the merged stack monitor): tabs Alerts /
Auto-heal, crumb Stack > {name} > Monitor. New initialTab prop lets
callers open directly to either tab. Auto-heal tab is hidden entirely
for Community-tier users (matches the existing tier-gating on the
context menu trigger and keyboard shortcut).
* StackAutoHealSheet.tsx: deleted. Its body became the Auto-heal tab
inside the merged sheet.
* VulnerabilityScanSheet: removed the icon-prefixed title (forbidden by
§9.11). Re-scan, Compare, CSV, SARIF lifted from body cards into the
toolbar band. Tabs Vulnerabilities | Secrets | Misconfigs (counts on
the tab labels). SBOM dropdown stays in the body summary section
pending a primitive enhancement for dropdown-attached toolbar actions.
* ScanComparisonSheet: crumb Security > Scans > Compare, name Diff,
meta with the +added/-removed delta.
* SecurityHistoryView: the inner sheet only. Crumb Security > Scan
history. Compare (paid + 2 selected) and Refresh in toolbar.
* ScheduledOperationsView run-history sheet (lines ~847-935 only):
crumb Schedules > {taskName} > Runs, Download CSV in toolbar, footer
surfaces next-run timestamp.
Hook refactor:
* useOverlayState replaces three separate state vars (alertSheetOpen,
alertSheetStack, autoHealStackName) with one stackMonitor object
carrying { stackName, tab }. New helpers openAlertSheet(stackName),
openAutoHeal(stackName), closeStackMonitor(). Tests rewritten and
pass (11/11).
* useSidebarContextMenu and ShellOverlays updated for the new API. The
three other call sites (useStackMenuItems, useStackKeyboardShortcuts)
already use openAlertSheet/openAutoHeal and need no change.
* refactor(frontend): extract useOverlayState hook from EditorLayout
* refactor(frontend): extract useStackActions hook and wire useOverlayState into EditorLayout
* refactor(frontend): fix quality issues in useStackActions post-review
* fix(frontend): fix interval leak, RunResult contract, yml hardcode, and loadFile length in useStackActions
* refactor(frontend): extract useSidebarContextMenu hook from EditorLayout
* refactor(frontend): extract ShellOverlays component from EditorLayout
* refactor(frontend): relocate Monaco layout effect and log-viewer event listener out of EditorLayout
The Monaco tab-switch layout effect is now self-contained in EditorView,
alongside its monacoEditorRef. The SENCHO_OPEN_LOGS_EVENT listener moves
into useOverlayState, where openLogViewer lives. EditorLayout is left with
the two coordination effects that depend on cross-hook state.