What it looks like
The dashboard is Markdown, so here is one: an example from made-up rows, rendered by Sluiceway's own code, with every section at once.
In a real dashboard issue you tick its boxes; here they are disabled. The same body, as a dashboard issue holds it, is assets/example-dashboard.md.
Sluiceway dashboard
🟡 4 pending · 🟠 2 drifted · 🔵 2 deploying · ⚪ 0 preview failed · 🟢 8 in sync · ⚠️ 2 pending stacks delete or replace resources
Scanned 34e410f on 2026-09-21 10:02 UTC · run · last full scan 2026-09-21 06:00 UTC
Deploying
apps/api:prod · deploying · ticked by alice · run
from #512 by alice · compare apps/worker:prod · queued behind apps/api:prod · ticked by alice · run
from #509 by bob · compare
Updates waiting to merge
Tick a box to merge that pull request. Its stack is then previewed again and deployed as that preview shows it.
- platform/ingress-nginx:prod · Update Helm release ingress-nginx to v4.13 · #519 by renovate[bot] · preview after the merge: 1 update
These wait on their own checks. Each gets a box here once its checks are green.
- apps/web:prod · Update dependency next to v15.5 · #521 by renovate[bot] · waits on its checks
Pending
Tick a box to deploy that stack exactly as its row shows it.
-
apps/billing:prod · 1 create, 1 update · preview
from #514 by erin, #511 by renovate[bot] · compare2 changes
updatekubernetes:apps/v1:Deploymentbilling ·spec.replicas2→3
createkubernetes:monitoring.coreos.com/v1:ServiceMonitorbilling
-
apps/legacy-worker:prod · 3 deletes, 1 tracking only · preview
from #498 by dave · compare
⚠️ DELETEaws:sqs/queue:Queuelegacy-jobs
⚠️ DELETEkubernetes:apps/v1:Deploymentlegacy-worker
⚠️ DELETEkubernetes:core/v1:Servicelegacy-worker1 other change
forgetaws:iam/role:Rolelegacy-worker
-
apps/web:staging · 2 creates, 1 update · preview
from #516 by carol, #510 by bob, and 1 change outside this stack · compare3 changes
updatekubernetes:apps/v1:Deploymentweb ·metadata.labels["app.kubernetes.io/version"],spec.template.spec.containers[0].image
createkubernetes:autoscaling/v2:HorizontalPodAutoscalerweb
createkubernetes:core/v1:ConfigMapweb-feature-flags
-
infra/network:prod · 1 update, 1 replace · preview
from 11fa403 by gina · compare
⚠️ REPLACEaws:ec2/subnet:Subnetprivate-b · forced bycidrBlock1 other change
updateaws:ec2/routeTable:RouteTableprivate ·routes[1].natGatewayId
-
Deploy all 4 pending stacks
Drifted
Real infrastructure changed outside the code. Deploying a stack puts it back as its code says.
-
monitoring/grafana:prod · 1 changed outside the code · preview
1 change outside the code
changedkubernetes:apps/v1:Deploymentgrafana ·spec.replicas
-
platform/external-dns:prod · 1 gone outside the code · preview
1 change outside the code
goneaws:route53/record:Recordstatus-cname
-
Confirm: repair all 2 drifted stacks: monitoring/grafana:prod, platform/external-dns:prod · asked by carol
Ticking this deploys each stack as its row shows it, in dependency order. A change to these rows first takes it back.
In sync
8 stacks in sync
- apps/api:staging
- apps/auth:prod
- apps/auth:staging
- apps/billing:staging
- apps/web:prod
- data/postgres:prod
- data/postgres:staging
- platform/ingress-nginx:prod
1 stack left out by ignore
- sandbox/playground:dev · a scratch stack, deployed by hand
Recently deployed
Times are in UTC.
- 🟢 apps/auth:prod · alice · 09-21 09:41 · run
shipped #513 by alice · compare - 🟢 data/postgres:prod · deployed outside the dashboard, from
35bf0b7· 09-21 09:30 - ⚪ apps/auth:staging · no changes · alice · 09-21 09:12 · run
- 🟢 platform/ingress-nginx:prod · drift fixed · carol · 09-20 18:05 · run
- 🟢 apps/web:prod · bob · 09-20 16:52 · run
shipped #510 by bob · compare - 🔴 apps/web:prod · failed · bob · 09-20 16:40 · run
- Rescan all stacks
Read the dashboard from the top
Section titled “Read the dashboard from the top”- The header. Penny with four crates upstream, one per pending stack, water running downstream because two stacks deploy, and both signs: a pending row deletes resources and another replaces one. The header shows every picture.
- The counts line. How many stacks are pending, drifted, deploying, preview failed and in
sync, each behind its count dot, how many pending stacks
delete or replace resources, and, only when there is one, how many stacks are
busy. Under it, the
scan line says which commit the last scan checked out, when, in which run, and when the
last full scan was. While a scan runs, a scan-running line under it says
since when and links the run, which this example does not show. Neither does it show
the lines about runs that failed: a
run that failed before Sluiceway ran, or found a problem in
sluiceway.yaml, says so under the scan line, and the next scan that works counts the runs that failed since the one before. - Deploying. While a stack deploys, its section comes before every other.
apps/api:proddeploys, and its row starts with a spinner.apps/worker:prodis a queued stack: it waits for the stack it depends on. Both rows sayticked by. A stack set to deploy on merge would saydeploying on merge · merged byinstead, which this example does not show. When a deploy is cancelled or rejected, its row turns into a preview failure within seconds, saysno preview since its deploy ended, and carries its failure line until the next scan previews the stack. - Updates waiting to merge. This section is there when merge and deploy is on.
platform/ingress-nginx:prodis an update waiting to merge: one tick merges its pull request, and its stack is previewed again and deployed.apps/web:prodis an update waiting on its checks, a line with no box that ends inwaits on its checks. It gets its box once its checks are green. - The destroy alert. A caution block above the pending rows names every
pending stack that deletes or replaces resources, here
apps/legacy-worker:prodandinfra/network:prod, and in a paragraph of its own every drifted stack with a resource gone outside the code. The deletes themselves stay under that stack’s row. - A pending row.
apps/billing:prodhas one create and one update waiting. Its row links the preview, names the pull requests that brought the change, links the compare view, and folds the changes under their count. Tick its box to deploy that stack exactly as its row shows it. With cost estimates on, an OpenTofu or Terraform row has a cost line under its first line, and a row whose change fails a policy has no box and names the policy instead. This example shows neither. - A row with deletes.
apps/legacy-worker:proddeletes three resources. A destroy is listed first, outside the fold, and always carries a warning. - A row with changes outside the stack.
apps/web:stagingnames the pull requests its stack claims and folds one change that no stack claims, such as a lockfile bump, since it may reach any stack. - A row with a replace.
infra/network:prodreplaces a subnet, and says which property forces it. The change came from a direct push, so the row names a commit instead of a pull request. - The bulk box.
Deploy all 4 pending stacks, under the pending rows. A tick on it deploys nothing. It asks for a confirm box instead. There is no bulk box in a section with one row, with deploys off, or on a read-only dashboard. - Drifted rows. Real infrastructure changed outside the code.
monitoring/grafana:prodhas a property changed, andplatform/external-dns:prodhas a record gone. Deploying a stack puts it back as its code says. A stack whose drift check failed keeps its row as it was and saysdrift not checked. - The confirm box. Someone ticked
Repair all 2 drifted stacks, and the next run put a confirm box where the bulk box was. It names the stacks and who asked. A tick on the confirm box deploys them, as a tick on each row. Each stack is judged by its own tick rule and gets its own fresh preview. If a row changes before anyone ticks the confirm box, the confirm box goes and the bulk box comes back. - Preview failed and Busy. A stack whose preview failed twice in one scan, after its
second try, sits under Preview failed. Its row has no
box, says why, and links the run whose job log holds the tool’s own words. A
busy stack, one whose lock another update held on both
tries, sits under Busy. Its row starts with
busy:, names the reason,another update holds the stack's lock, and says that the next scan previews it. Nothing is wrong with it, and the header does not turn failing. This example shows neither section. - In sync. The stacks with nothing to deploy, folded under their count, and under them the stacks left out by ignore, each with its reason.
- Recently deployed, the trail. Every deploy that ended, newest first, one line each: its
result dot, the stack id, its ticker (or
merged byfor a deploy on merge), the date and time in UTC, and a link to its run. A deploy that went out can have a shipped line under it. A full scan adds the outside deploys it finds in the tool’s own history, such asdata/postgres:prodhere. A failed deploy stays listed when a later deploy of its stack clears the failure line on the row. - The rescan box. Tick it to start a full scan of every stack. It deploys nothing.