MightyMoud/sidekick
Bare metal to production ready in mins; your own fly server on your VPS.
Slowing — last commit 3mo ago
weakest axiscopyleft license (GPL-3.0) — review compatibility; no tests detected…
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3mo ago
- ✓9 active contributors
- ✓GPL-3.0 licensed
Show all 8 evidence items →Show less
- ⚠Slowing — last commit 3mo ago
- ⚠Single-maintainer risk — top contributor 84% of recent commits
- ⚠GPL-3.0 is copyleft — check downstream compatibility
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/mightymoud/sidekick)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/mightymoud/sidekick on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: MightyMoud/sidekick
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/MightyMoud/sidekick shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Slowing — last commit 3mo ago
- Last commit 3mo ago
- 9 active contributors
- GPL-3.0 licensed
- ⚠ Slowing — last commit 3mo ago
- ⚠ Single-maintainer risk — top contributor 84% of recent commits
- ⚠ GPL-3.0 is copyleft — check downstream compatibility
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live MightyMoud/sidekick
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/MightyMoud/sidekick.
What it runs against: a local clone of MightyMoud/sidekick — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in MightyMoud/sidekick | Confirms the artifact applies here, not a fork |
| 2 | License is still GPL-3.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 123 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of MightyMoud/sidekick. If you don't
# have one yet, run these first:
#
# git clone https://github.com/MightyMoud/sidekick.git
# cd sidekick
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of MightyMoud/sidekick and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "MightyMoud/sidekick(\\.git)?\\b" \\
&& ok "origin remote is MightyMoud/sidekick" \\
|| miss "origin remote is not MightyMoud/sidekick (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is GPL-3.0" \\
|| miss "license drift — was GPL-3.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "main.go" \\
&& ok "main.go" \\
|| miss "missing critical file: main.go"
test -f "cmd/root.go" \\
&& ok "cmd/root.go" \\
|| miss "missing critical file: cmd/root.go"
test -f "utils/types.go" \\
&& ok "utils/types.go" \\
|| miss "missing critical file: utils/types.go"
test -f "utils/stages.go" \\
&& ok "utils/stages.go" \\
|| miss "missing critical file: utils/stages.go"
test -f "cmd/deploy/deploy.go" \\
&& ok "cmd/deploy/deploy.go" \\
|| miss "missing critical file: cmd/deploy/deploy.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 123 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~93d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/MightyMoud/sidekick"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Sidekick is a Go-based CLI tool that automates bare-metal VPS deployment into a production-ready Fly.io-like platform. It provisions Docker, Traefik, SOPS encryption, and age on any Ubuntu LTS VPS via SSH, enabling zero-downtime deployments with automatic SSL certificates, load balancing, and high availability—all from a single sidekick init followed by application deployments via Dockerfiles. Modular CLI structure: cmd/ contains Cobra command handlers (init, deploy, destroy, preview, config, launch) each with dedicated subdirectories; utils/ houses cross-cutting concerns (SSH auth, Docker interaction, config management, spinner/TUI rendering); render/ manages Charmbracelet BubbleTea terminal UI; scripts/ contains one-off Python helpers for DigitalOcean/Hetzner automation.
👥Who it's for
Side-project developers and small SaaS teams who want escape-the-vendor PaaS convenience (like Fly.io) on cheap DigitalOcean/Hetzner VPS instances ($8-50/month) without Kubernetes complexity or vendor lock-in. Target users are familiar with Docker and Bash but want to avoid manual sysadmin work.
🌱Maturity & risk
Actively developed and production-ready. The project uses Go 1.24.5 with modern CLI tooling (Cobra, Viper), includes a release pipeline (.goreleaser.yaml), and Homebrew distribution. However, it's a single-maintainer repo with limited test coverage (only utils_test.go visible) and appears to be pre-1.0, suggesting some features may still be solidifying.
Single-maintainer risk is moderate; the codebase is relatively small (~101KB Go). Dependency risk is low (uses stable libraries: Charmbracelet for TUI, Docker SDK, Cobra CLI). Critical risk: SSH-based remote provisioning means credential theft or misconfigured firewall rules could expose VPS; the repo lacks documented security hardening steps. No visible CI/CD workflow (no .github/workflows) may hide breaking changes.
Active areas of work
Based on the file structure, active development includes: preview environment management (cmd/preview with list/remove subcommands), multi-stage deployment orchestration (utils/stages.go), and TUI improvements (render/tui.go with Charmbracelet integration). The .goreleaser.yaml suggests regular releases. Exact recent commit activity not visible from provided data, but the presence of preview infrastructure suggests current focus on advanced deployment features.
🚀Get running
Clone and build: git clone https://github.com/MightyMoud/sidekick && cd sidekick && go build -o sidekick ./. Install via Homebrew (production): brew install sidekick. Requires: Go 1.24.0+, SSH key access to Ubuntu LTS VPS, and brew for downstream sops installation.
Daily commands:
No traditional dev server; this is a CLI tool. Run go run ./main.go init to interactively set up a VPS. For local testing: go test ./.... For release builds: goreleaser build --snapshot --clean.
🗺️Map of the codebase
main.go— Entry point for the CLI application; initializes the root command and dependency injection for the entire tool.cmd/root.go— Root Cobra command that defines the CLI structure and argument parsing; all subcommands branch from here.utils/types.go— Core data structures (Config, Stage, Server) shared across all deployment and orchestration logic.utils/stages.go— Stage execution engine that orchestrates the entire deployment pipeline from bare metal to production.cmd/deploy/deploy.go— Main deployment command that reads Docker images and coordinates multi-stage provisioning on VPS.utils/config.go— Configuration loader and persistence layer; handles VPS credentials, deployment settings, and state.render/tui.go— TUI renderer using Bubble Tea; displays deployment progress, logs, and interactive prompts to users.
🛠️How to make changes
Add a new deployment stage
- Define the new stage logic in utils/stages.go by adding a case in the stage execution switch or creating a new stage handler function. (
utils/stages.go) - Add the stage type constant to utils/types.go (StageType). (
utils/types.go) - Generate SSH scripts for the stage in utils/scripts.go (e.g., GenerateDeployScript). (
utils/scripts.go) - Wire the stage into the deploy command by updating cmd/deploy/deploy.go to include it in the pipeline. (
cmd/deploy/deploy.go) - Update the TUI to display progress for the new stage in render/tui.go. (
render/tui.go)
Add a new CLI command
- Create a new subdirectory under cmd/ (e.g., cmd/newcommand/) with a Go file. (
cmd/newcommand/newcommand.go) - Define a Cobra Command struct with Run function that implements your command logic. (
cmd/newcommand/newcommand.go) - Import and register the command in cmd/root.go by adding it to the root command's AddCommand() call. (
cmd/root.go) - Add any configuration fields needed to utils/types.go if the command uses the Config struct. (
utils/types.go)
Add support for a new cloud provider
- Add provider constants and struct fields to utils/types.go (e.g., ProviderType, provider-specific credentials). (
utils/types.go) - Create provider-specific droplet/instance creation in a new Python script under scripts/ or extend scripts/make-droplet.py. (
scripts/make-droplet.py) - Extend utils/auth.go to handle provider-specific SSH key retrieval and credential management. (
utils/auth.go) - Update cmd/initialize/initialize.go to prompt for provider-specific configuration and call the appropriate provisioning logic. (
cmd/initialize/initialize.go)
Extend the TUI with a new interactive prompt or view
- Define new message types in render/types.go for your interaction (e.g., UserInputMsg, MenuSelectionMsg). (
render/types.go) - Implement view logic and message handling in render/tui.go (Update and View functions). (
render/tui.go) - Add styling constants or helper functions in render/utils.go. (
render/utils.go) - Integrate the new prompt into the appropriate command (e.g., cmd/deploy/deploy.go) by calling the TUI program. (
cmd/deploy/deploy.go)
🔧Why these technologies
- Go 1.24 — Statically compiled, single binary distribution; ideal for CLI tooling and cross-platform deployment scripts.
- Cobra CLI framework — Battle-tested, nested subcommand structure matches the hierarchical nature of sidekick's operations (init, deploy, preview, destroy).
- Bubble Tea + Charmbracelet — Modern, responsive TUI with built-in progress rendering and interactive prompts; better UX than simple stderr logging.
- Docker SDK — Programmatic container image building and registry push without shelling to the Docker CLI.
- golang.org/x/crypto (SSH) — Pure Go SSH client for agent-less remote script execution and secure authentication to bare-metal VPS.
- YAML + Viper — Human-readable config files with environment variable override support; minimal dependency footprint for configuration.
- Python helper scripts — DigitalOcean API integration for droplet provisioning; easier to maintain separately than embedded Go API calls.
⚖️Trade-offs already made
-
SSH-based remote execution over container orchestration (Kubernetes, Docker Swarm)
- Why: Sidekick targets minimal VPS environments; full orchestration adds complexity and overhead inappropriate for hobby/small projects.
- Consequence: Limited auto-scaling and resilience patterns; operators must manually configure load balancing and HA; single point of failure if VPS goes down.
-
Synchronous stage pipeline vs. async job queue (Bull, RQ)
- Why: Simplifies state tracking and user feedback; deployments are typically short-lived (~1–5 min) and initiated by human action.
- Consequence: CLI blocks during deployment; cannot queue multiple concurrent deployments; long-running stages may timeout.
-
File-based configuration over centralized database
- Why: No external dependency; config lives in the repo and can be version-controlled.
- Consequence: No real-time sync across multiple developers or CI agents; requires manual merge conflict resolution.
-
Single binary CLI vs. daemon server + REST API
- Why: Simpler mental model for users; no background process to manage; every invocation is atomic.
- Consequence: No persistent logging or audit trail; each CLI invocation is independent; preview/monitoring requires separate tools.
🚫Non-goals (don't propose these)
- Does not provide managed container orchestration (no Kubernetes, Docker Swarm, or equivalent control plane).
- Does not offer horizontal auto-scaling based on load metrics.
- Does not provide a SaaS-hosted control plane; all coordination happens locally on the operator's machine.
- Does not manage certificate renewal or ACME challenge automation (relies on Traefik for that).
- Does not handle multi-region or multi-cloud failover; scope is single VPS per deployment.
🪤Traps & gotchas
SSH key path must be explicitly set; no auto-discovery of ~/.ssh/id_rsa. Email for SSL cert setup (Let's Encrypt) is required during init and stored in config. The sidekick init command demands root SSH access and modifies /etc/sudoers; test in a disposable VPS first. Traefik reverse proxy port defaults (80/443) must be open on VPS firewall. SOPS key storage (age) happens on the VPS, not locally—losing the VPS means losing secrets unless backed up. Python scripts (make-droplet.py, destroy-droplets.py) are for DigitalOcean API automation but require DO_TOKEN env var; not integrated into main CLI yet.
🏗️Architecture
💡Concepts to learn
- Zero-downtime deployment (blue-green / rolling restart) — Sidekick's core feature promise; you need to understand how it swaps traffic between old and new containers without dropping connections
- Reverse proxy / load balancing (Traefik middleware) — Traefik is the backbone of request routing, SSL termination, and service discovery in Sidekick; understanding Traefik config is essential to troubleshooting deployments
- SSH remote execution and bastion patterns — Sidekick provisions VPS by executing shell scripts over SSH; understanding key-based auth, known_hosts, and command escaping is critical for debugging provisioning failures
- SOPS (Secrets Operations) and age encryption — Sidekick integrates SOPS for managing encrypted secrets; you need to understand how secrets are encrypted, stored, and injected into containers during deployment
- Cobra CLI framework — Sidekick's entire command structure (init, deploy, destroy, etc.) is built on Cobra; contributing new commands or fixing CLI behavior requires Cobra knowledge
- BubbleTea TUI (Terminal User Interface) — Sidekick renders interactive menus, spinners, and progress indicators using Charmbracelet's BubbleTea; modifying UX requires understanding the Elm-like architecture
- Docker image build and registry push — The deploy command builds Dockerfiles locally and pushes to registries; understanding Docker SDK clients and image manifest handling is needed for custom registry support
🔗Related repos
superfly/flyctl— Official Fly.io CLI; the spiritual predecessor and direct inspiration for Sidekick's deployment model and command structuredokku/dokku— Self-hosted PaaS on single VPS using Docker; alternative approach to the same problem (cheap self-hosting) with Git-push deployment instead of CLI commandscaprover/caprover— Another single-VPS PaaS platform with web UI and Docker Swarm; competes in the same self-hosted convenience space but uses UI-first instead of CLImozilla/sops— Secrets Operations tool for encryption; Sidekick integrates SOPS for encrypted config management in deploymentstraefik/traefik— Reverse proxy and load balancer; Sidekick provisions Traefik on VPS for SSL termination, routing, and zero-downtime deploys
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for utils/auth.go and utils/docker.go
The repo has only one test file (utils/utils_test.go) covering general utilities. Critical authentication and Docker integration logic in auth.go and docker.go lack test coverage. Given that sidekick handles VPS deployment with SSH/auth and Docker operations, these need robust tests to prevent security regressions and deployment failures.
- [ ] Create utils/auth_test.go with tests for SSH key handling, credential validation, and host verification logic
- [ ] Create utils/docker_test.go with tests for Docker daemon connections, image operations, and container lifecycle management
- [ ] Use testify/mock or similar to mock external SSH/Docker calls
- [ ] Aim for >80% code coverage on both files
- [ ] Run 'go test ./utils -v' to verify all tests pass
Add GitHub Actions CI workflow for Go builds, tests, and linting
The repo uses .goreleaser.yaml for releases but has no automated CI pipeline. With Go 1.24 as the minimum version and multiple subcommands (deploy, launch, preview, etc.), a CI workflow would catch breaking changes, ensure cross-platform compatibility (Linux/macOS needed for VPS tools), and validate the build before releases.
- [ ] Create .github/workflows/ci.yml with jobs for: go test ./..., go build ./cmd/..., and golangci-lint
- [ ] Include matrix testing across Go versions (1.24.x and latest stable) and OS (ubuntu-latest, macos-latest)
- [ ] Add a step to verify Docker dependency availability on the test runner
- [ ] Ensure the workflow triggers on push to main and all PRs
- [ ] Validate that cmd/root.go, cmd/deploy/deploy.go, and other CLI entrypoints build successfully
Document CLI command examples and flags in README with a Commands section
The README shows hero images and features but lacks concrete CLI usage documentation. Users cannot see what 'sidekick launch', 'sidekick deploy', or 'sidekick preview list' actually do. The cmd/ directory structure shows 5+ commands but none are documented with examples, flags, or expected inputs.
- [ ] Add a 'Commands' section in README.md after Features with subsections for each command in cmd/
- [ ] For each command (deploy, launch, initialize, preview, destroy, config), document: purpose, basic usage, key flags, and a practical example
- [ ] Reference cmd/root.go and cmd/deploy/deploy.go to extract actual flag definitions from Cobra setup
- [ ] Include prerequisite steps (e.g., 'sidekick initialize' before 'sidekick deploy')
- [ ] Add a 'Configuration' subsection explaining cmd/config/config.go and where .env or YAML config files should be placed
🌿Good first issues
- Add unit tests for utils/docker.go: Docker image build and push logic currently untested; create mocks of Docker SDK and verify retry behavior and error handling
- Document the SOPS/age secret workflow: README lacks step-by-step guide on how secrets are encrypted, stored on VPS, and injected into containers; add a guides/secrets.md with examples
- Add health-check retry logic to utils/stages.go: Current implementation lacks exponential backoff when waiting for deployed services to become healthy; implement and test with realistic timeouts
⭐Top contributors
Click to expand
Top contributors
- @MightyMoud — 84 commits
- @dejanstrancar — 4 commits
- @lborgav — 3 commits
- @supavitd — 2 commits
- @gedw99 — 2 commits
📝Recent commits
Click to expand
Recent commits
ffd3fb0— Merge pull request #77 from supavitd/support-multiple-vps (MightyMoud)b84ff01— Merge pull request #80 from Backline-oss-forks/backline/go-931112cca806add425ae70df70f07a7b (MightyMoud)456fd3c— Updatedgolang.org/x/crypto(Backline AI)cce80c7— Add VPS selection on sidekick launch and display server info in deploy (supavitd)1b00c94— POC - Support Multiple VPSes (supavitd)2ed2021— Remove orphan cleanup (MightyMoud)5ed8954— Simple cleanup (MightyMoud)bf2ebcd— New script for zero downtime deploys (MightyMoud)343c157— Refactor deploy and add a new script (MightyMoud)170e124— Capture arch and distro from VPS (MightyMoud)
🔒Security observations
- High · Outdated Go Toolchain with Known Vulnerabilities —
go.mod. The project uses Go 1.24.0 with toolchain 1.24.5. While relatively recent, Go versions can have security vulnerabilities. The go.mod shows golang.org/x/crypto v0.45.0 which may have unpatched vulnerabilities depending on the exact version of Go used. Fix: Regularly update Go to the latest stable patch version. Run 'go get -u golang.org/x/crypto' and verify all dependencies are at their latest secure versions using 'go list -u -m all'. - High · Docker Client Dependency with Known Vulnerability —
go.mod - github.com/docker/docker v28.5.1+incompatible. The dependency 'github.com/docker/docker v28.5.1+incompatible' is marked as incompatible. Docker client libraries have had privilege escalation and container escape vulnerabilities in the past. The +incompatible tag indicates version handling issues. Fix: Resolve the version incompatibility. Use a compatible version of the Docker Go SDK (e.g., github.com/moby/moby). Run 'go get -u github.com/docker/docker' and ensure it resolves properly. - High · Insecure SSH/Crypto Operations —
utils/auth.go, go.mod (golang.org/x/crypto, github.com/skeema/knownhosts). The presence of 'github.com/skeema/knownhosts' and 'golang.org/x/crypto' suggests SSH key handling. Files like 'utils/auth.go' likely handle authentication, but without code review, insecure SSH key storage, weak key exchange, or improper credential handling is a risk, especially for a VPS deployment tool. Fix: Ensure SSH keys are stored in secure locations (e.g., ~/.ssh with 0600 permissions). Validate that host key verification is enabled. Use strong key exchange algorithms. Avoid storing SSH keys in environment variables or configuration files. - High · Environment Variable Configuration Management —
.env files (not visible but likely present), utils/config.go, github.com/joho/godotenv. Dependency on 'github.com/joho/godotenv' suggests .env file usage for configuration. If this tool handles VPS credentials, SSH keys, or API tokens through .env files, these could be accidentally committed to version control or exposed. Fix: Never commit .env files to version control. Add '.env' and '.env.*.local' to .gitignore (verify current .gitignore). Use secure credential managers. For production, use environment variables set by the VPS provider, not local .env files. - Medium · Unvalidated Script Execution —
utils/scripts.go, scripts/ directory. The presence of 'scripts/destroy-droplets.py' and 'scripts/make-droplet.py' suggests execution of external scripts. The file 'utils/scripts.go' likely executes these. If user input influences script execution without proper validation, this could lead to command injection. Fix: Validate all inputs before passing to script execution. Use shell escaping/quoting mechanisms. Avoid shell=True execution patterns. Consider using native Go libraries instead of shell scripts. Implement input sanitization. - Medium · Credential Exposure via Command-Line Arguments —
cmd/ directory, main.go, spf13/cobra usage. A Cobra CLI application handling VPS deployment may expose credentials in command history, process listings, or logs. Users might pass sensitive tokens or keys as arguments. Fix: Avoid accepting credentials as command-line arguments. Use interactive prompts instead (Cobra supports this). Never log credentials. Consider using SOPS integration (already mentioned in README) for secrets management. Implement careful output filtering. - Medium · Missing Certificate Validation for TLS —
cmd/deploy/deploy.go, utils/ - TLS communication code. The README mentions 'Zero config SSL Certs' and the tool manages Traefik. There's a risk of improper TLS validation, self-signed certificate acceptance, or missing certificate pinning when communicating with VPS infrastructure. Fix: Ensure all TLS connections validate certificates properly. Use Go's standard crypto/tls with proper VerifyPeerCertificate callbacks.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.