Files
bot/ui/public/skills/healthcheck.html
zooqueenandHanzo Dev 2a2d582eac feat: add Skills Hub with 51 SEO-optimized detail pages + Web3 credits
- Build script (scripts/build-skills-catalog.ts) parses all SKILL.md
  files, outputs JSON catalog and individual detail HTML pages
- Skills Hub list page (/skills) with search, category filters, card grid
- Individual skill pages (/skills/github, etc.) with pre-rendered README,
  metadata sidebar, install commands, GitHub API integration
- Full SEO: unique title, meta description, Open Graph, Twitter Card,
  JSON-LD structured data on every page
- Web3 native messaging: DID identities, wallets, on-chain payments,
  prepaid credit balance model
- Fix stale chat widget system prompt pricing (Pro $5 → actual tiers)
- Add skills:catalog script to package.json

Co-authored-by: Hanzo Dev <[email protected]>
2026-02-13 17:26:25 -08:00

1216 lines
45 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>healthcheck — Hanzo Bot Skills</title>
<meta
name="description"
content="Host security hardening and risk-tolerance configuration for Hanzo Bot deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, Hanzo Bot cron scheduling for periodic checks, or version status checks on a machine running Hanzo Bot (laptop, workstation, Pi, VPS)."
/>
<meta name="keywords" content="healthcheck, Hanzo Bot, AI skill, Utilities, autonomous agent" />
<link rel="canonical" href="https://hanzo.bot/skills/healthcheck" />
<!-- Open Graph -->
<meta property="og:title" content="healthcheck — Hanzo Bot Skills" />
<meta
property="og:description"
content="Host security hardening and risk-tolerance configuration for Hanzo Bot deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, Hanzo Bot cron scheduling for periodic checks, or version status checks on a machine running Hanzo Bot (laptop, workstation, Pi, VPS)."
/>
<meta property="og:type" content="article" />
<meta property="og:url" content="https://hanzo.bot/skills/healthcheck" />
<meta property="og:site_name" content="Hanzo Bot" />
<meta property="og:image" content="https://hanzo.bot/og-skills.png" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@hanaborteam" />
<meta name="twitter:title" content="healthcheck — Hanzo Bot Skills" />
<meta
name="twitter:description"
content="Host security hardening and risk-tolerance configuration for Hanzo Bot deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, Hanzo Bot cron scheduling for periodic checks, or version status checks on a machine running Hanzo Bot (laptop, workstation, Pi, VPS)."
/>
<!-- JSON-LD -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "healthcheck — Hanzo Bot Skill",
"description": "Host security hardening and risk-tolerance configuration for Hanzo Bot deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, Hanzo Bot cron scheduling for periodic checks, or version status checks on a machine running Hanzo Bot (laptop, workstation, Pi, VPS).",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Cross-platform",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"author": {
"@type": "Organization",
"name": "Hanzo AI",
"url": "https://hanzo.ai"
}
}
</script>
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🥷</text></svg>"
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<style>
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--brand: #fd4444;
--brand-secondary: #ff6b6b;
--bg: #000;
--bg-card: rgba(255, 255, 255, 0.04);
--bg-hover: #1a1a1a;
--border: rgba(255, 255, 255, 0.08);
--border-hover: rgba(255, 255, 255, 0.16);
--text: #fff;
--muted: #888;
--subtle: #555;
--max-w: 1200px;
--ease: cubic-bezier(0.4, 0, 0.2, 1);
--ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--font:
"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
sans-serif;
--font-mono: "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
}
html {
scroll-behavior: smooth;
}
body {
font-family: var(--font);
background: var(--bg);
color: var(--text);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
position: relative;
}
body::before {
content: "";
position: fixed;
inset: 0;
background-image:
linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
background-size: 64px 64px;
pointer-events: none;
z-index: 0;
}
body::after {
content: "";
position: fixed;
inset: 0;
opacity: 0.035;
pointer-events: none;
z-index: 0;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
body > * {
position: relative;
z-index: 1;
}
a {
color: inherit;
text-decoration: none;
}
button {
font-family: inherit;
cursor: pointer;
border: none;
background: none;
color: inherit;
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
background: rgba(0, 0, 0, 0.85);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
}
.header-inner {
max-width: var(--max-w);
margin: 0 auto;
padding: 0 24px;
height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-left {
display: flex;
align-items: center;
gap: 32px;
}
.logo {
display: flex;
align-items: center;
gap: 8px;
}
.logo-mark {
width: 24px;
height: 24px;
}
.logo-mark svg {
width: 100%;
height: 100%;
display: block;
}
.logo-text {
font-size: 15px;
font-weight: 600;
letter-spacing: -0.03em;
}
.nav-links {
display: flex;
gap: 4px;
}
.nav-link {
position: relative;
padding: 8px 12px;
font-size: 13px;
font-weight: 500;
color: var(--muted);
border-radius: 6px;
transition:
color 0.15s,
background 0.15s;
}
.nav-link:hover {
color: var(--text);
background: var(--bg-hover);
}
.nav-link.active {
color: var(--brand);
}
.header-right {
display: flex;
align-items: center;
gap: 8px;
}
.btn-ghost {
padding: 8px 16px;
font-size: 13px;
font-weight: 500;
color: var(--muted);
border-radius: 8px;
transition:
color 0.15s,
background 0.15s;
}
.btn-ghost:hover {
color: var(--text);
background: var(--bg-hover);
}
.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 20px;
font-size: 13px;
font-weight: 600;
color: #fff;
background: var(--brand);
border-radius: 9999px;
transition:
opacity 0.15s,
box-shadow 0.15s;
}
.btn-primary:hover {
opacity: 0.9;
box-shadow: 0 0 24px rgba(253, 68, 68, 0.3);
}
.btn-outline {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 20px;
font-size: 13px;
font-weight: 500;
color: var(--text);
border: 1px solid var(--border);
border-radius: 9999px;
transition:
border-color 0.15s,
background 0.15s,
box-shadow 0.15s;
}
.btn-outline:hover {
border-color: rgba(253, 68, 68, 0.3);
background: rgba(253, 68, 68, 0.06);
}
.btn-lg {
padding: 14px 32px;
font-size: 15px;
border-radius: 9999px;
}
.footer {
border-top: 1px solid var(--border);
padding: 64px 24px 32px;
}
.footer-inner {
max-width: var(--max-w);
margin: 0 auto;
}
.footer-grid {
display: grid;
grid-template-columns: 240px repeat(4, 1fr);
gap: 40px;
margin-bottom: 48px;
}
.footer-brand .footer-logo {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
.footer-brand .footer-logo svg {
width: 20px;
height: 20px;
}
.footer-brand .footer-logo span {
font-size: 14px;
font-weight: 600;
}
.footer-brand p {
font-size: 13px;
color: var(--muted);
line-height: 1.6;
margin-bottom: 16px;
}
.footer-social {
display: flex;
gap: 12px;
}
.footer-social a {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border);
border-radius: 8px;
color: var(--muted);
transition:
color 0.15s,
border-color 0.15s;
}
.footer-social a:hover {
color: var(--text);
border-color: var(--border-hover);
}
.footer-social svg {
width: 14px;
height: 14px;
}
.footer-col h4 {
font-size: 12px;
font-weight: 500;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--subtle);
margin-bottom: 16px;
}
.footer-col a {
display: block;
font-size: 13px;
color: var(--muted);
padding: 3px 0;
transition: color 0.15s;
}
.footer-col a:hover {
color: var(--text);
}
.footer-bottom {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 24px;
border-top: 1px solid var(--border);
font-size: 12px;
color: var(--subtle);
}
@media (max-width: 1024px) {
.footer-grid {
grid-template-columns: repeat(3, 1fr);
}
.footer-brand {
grid-column: 1/-1;
}
.nav-links {
display: none;
}
}
@media (max-width: 768px) {
.footer-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.footer-grid {
grid-template-columns: 1fr;
}
}
/* ── Detail layout ── */
.detail-wrap {
max-width: var(--max-w);
margin: 0 auto;
padding: 80px 24px 60px;
}
.back-link {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: var(--muted);
margin-bottom: 24px;
transition: color 0.15s;
}
.back-link:hover {
color: var(--text);
}
.skill-hero {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 32px;
}
.skill-emoji {
font-size: 48px;
line-height: 1;
}
.skill-hero h1 {
font-size: clamp(28px, 4vw, 40px);
font-weight: 700;
letter-spacing: -0.03em;
}
.skill-desc {
font-size: 15px;
color: var(--muted);
line-height: 1.7;
margin-bottom: 40px;
max-width: 720px;
}
.detail-layout {
display: grid;
grid-template-columns: 1fr 320px;
gap: 48px;
align-items: start;
}
.detail-main {
min-width: 0;
}
.detail-sidebar {
display: flex;
flex-direction: column;
gap: 16px;
position: sticky;
top: 80px;
}
.sidebar-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 20px;
backdrop-filter: blur(16px);
}
.sidebar-card h3 {
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--subtle);
margin-bottom: 16px;
}
.info-row {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: 6px 0;
font-size: 13px;
border-bottom: 1px solid var(--border);
}
.info-row:last-child {
border-bottom: none;
}
.info-row .label {
color: var(--muted);
}
.info-row .value {
color: var(--text);
text-align: right;
}
.info-row .value code {
font-family: var(--font-mono);
font-size: 11px;
background: rgba(255, 255, 255, 0.06);
padding: 2px 6px;
border-radius: 4px;
}
.info-row .value a {
color: var(--brand);
transition: opacity 0.15s;
}
.info-row .value a:hover {
opacity: 0.8;
}
.install-row {
padding: 8px 0;
border-bottom: 1px solid var(--border);
}
.install-row:last-child {
border-bottom: none;
}
.install-label {
display: block;
font-size: 12px;
color: var(--muted);
margin-bottom: 4px;
}
.install-cmd {
display: block;
font-family: var(--font-mono);
font-size: 12px;
color: var(--brand-secondary);
background: rgba(255, 255, 255, 0.04);
padding: 6px 10px;
border-radius: 6px;
word-break: break-all;
}
.sidebar-actions {
display: flex;
flex-direction: column;
gap: 8px;
}
.sidebar-actions a {
text-align: center;
}
.web3-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
background: rgba(99, 102, 241, 0.1);
border: 1px solid rgba(99, 102, 241, 0.2);
border-radius: 6px;
font-size: 11px;
font-weight: 500;
color: #818cf8;
margin-bottom: 4px;
}
.web3-features {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 12px;
}
.web3-feat {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--muted);
}
.web3-feat::before {
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
background: #818cf8;
flex-shrink: 0;
}
.category-badge {
display: inline-block;
padding: 3px 10px;
border-radius: 100px;
font-size: 11px;
font-weight: 500;
background: rgba(253, 68, 68, 0.08);
color: var(--brand-secondary);
border: 1px solid rgba(253, 68, 68, 0.15);
}
/* ── README styles ── */
.skill-readme {
line-height: 1.7;
color: rgba(255, 255, 255, 0.85);
}
.skill-readme h1 {
font-size: 28px;
font-weight: 700;
margin: 32px 0 16px;
letter-spacing: -0.02em;
}
.skill-readme h2 {
font-size: 22px;
font-weight: 600;
margin: 28px 0 12px;
letter-spacing: -0.01em;
color: var(--text);
}
.skill-readme h3 {
font-size: 17px;
font-weight: 600;
margin: 24px 0 8px;
}
.skill-readme h4 {
font-size: 14px;
font-weight: 600;
margin: 20px 0 8px;
}
.skill-readme p {
margin: 0 0 16px;
}
.skill-readme ul,
.skill-readme ol {
margin: 0 0 16px;
padding-left: 24px;
}
.skill-readme li {
margin-bottom: 6px;
}
.skill-readme code {
font-family: var(--font-mono);
font-size: 0.88em;
background: rgba(255, 255, 255, 0.06);
padding: 2px 6px;
border-radius: 4px;
}
.skill-readme pre {
margin: 0 0 16px;
border-radius: 8px;
overflow-x: auto;
background: rgba(255, 255, 255, 0.04);
border: 1px solid var(--border);
}
.skill-readme pre code {
display: block;
padding: 16px;
background: none;
font-size: 13px;
line-height: 1.5;
}
.skill-readme table {
width: 100%;
border-collapse: collapse;
margin: 0 0 16px;
font-size: 13px;
}
.skill-readme th,
.skill-readme td {
padding: 8px 12px;
border: 1px solid var(--border);
text-align: left;
}
.skill-readme th {
background: rgba(255, 255, 255, 0.04);
font-weight: 600;
}
.skill-readme blockquote {
border-left: 3px solid var(--brand);
padding: 8px 16px;
margin: 0 0 16px;
color: var(--muted);
background: rgba(255, 255, 255, 0.02);
border-radius: 0 8px 8px 0;
}
.skill-readme a {
color: var(--brand-secondary);
text-decoration: underline;
text-underline-offset: 2px;
}
.skill-readme a:hover {
color: var(--brand);
}
.skill-readme hr {
border: none;
border-top: 1px solid var(--border);
margin: 24px 0;
}
.skill-readme strong {
color: var(--text);
}
@media (max-width: 1024px) {
.detail-layout {
grid-template-columns: 1fr;
}
.detail-sidebar {
position: static;
order: 2;
}
}
@media (max-width: 768px) {
.detail-wrap {
padding: 72px 16px 40px;
}
}
</style>
</head>
<body>
<header class="header">
<div class="header-inner">
<div class="header-left">
<a href="/" class="logo">
<div class="logo-mark">
<svg viewBox="0 0 67 67" xmlns="http://www.w3.org/2000/svg">
<path d="M22.21 67V44.6369H0V67H22.21Z" fill="#fff" />
<path d="M0 44.6369L22.21 46.8285V44.6369H0Z" fill="#fff" />
<path
d="M66.7038 22.3184H22.2534L0.0878906 44.6367H44.4634L66.7038 22.3184Z"
fill="#fff"
/>
<path d="M22.21 0H0V22.3184H22.21V0Z" fill="#fff" />
<path d="M66.7198 0H44.5098V22.3184H66.7198V0Z" fill="#fff" />
<path d="M66.6753 22.3185L44.5098 20.0822V22.3185H66.6753Z" fill="#fff" />
<path d="M66.7198 67V44.6369H44.5098V67H66.7198Z" fill="#fff" />
</svg>
</div>
<span class="logo-text">Bot</span>
</a>
<nav class="nav-links">
<a href="https://hanzo.ai" class="nav-link">AI</a>
<a href="/" class="nav-link">Home</a>
<a href="/skills" class="nav-link active">Skills</a>
<a href="/book" class="nav-link">Book</a>
<a href="https://docs.hanzo.bot" class="nav-link">Docs</a>
<a href="https://github.com/hanzoai/bot" class="nav-link">GitHub</a>
</nav>
</div>
<div class="header-right">
<a href="https://hanzo.ai/contact" class="btn-ghost">Contact Sales</a>
<a href="/chat" class="btn-primary">Sign In</a>
</div>
</div>
</header>
<main class="detail-wrap">
<a href="/skills" class="back-link">&larr; Back to all skills</a>
<div class="skill-hero">
<span class="skill-emoji">🔧</span>
<div>
<h1>healthcheck</h1>
</div>
</div>
<p class="skill-desc">
Host security hardening and risk-tolerance configuration for Hanzo Bot deployments. Use when
a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure
review, Hanzo Bot cron scheduling for periodic checks, or version status checks on a machine
running Hanzo Bot (laptop, workstation, Pi, VPS).
</p>
<div class="detail-layout">
<div class="detail-main">
<div class="skill-readme">
<h1>Hanzo Bot Host Hardening</h1>
<h2>Overview</h2>
<p>
Assess and harden the host running Hanzo Bot, then align it to a user-defined risk
tolerance without breaking access. Use Hanzo Bot security tooling as a first-class
signal, but treat OS hardening as a separate, explicit set of steps.
</p>
<h2>Core rules</h2>
<ul>
<li>
Recommend running this skill with a state-of-the-art model (e.g., Opus 4.5, GPT
5.2+). The agent should self-check the current model and suggest switching if below
that level; do not block execution.
</li>
<li>Require explicit approval before any state-changing action.</li>
<li>
Do not modify remote access settings without confirming how the user connects.
</li>
<li>Prefer reversible, staged changes with a rollback plan.</li>
<li>
Never claim Hanzo Bot changes the host firewall, SSH, or OS updates; it does not.
</li>
<li>If role/identity is unknown, provide recommendations only.</li>
<li>
Formatting: every set of user choices must be numbered so the user can reply with a
single digit.
</li>
<li>System-level backups are recommended; try to verify status.</li>
</ul>
<h2>Workflow (follow in order)</h2>
<h3>0) Model self-check (non-blocking)</h3>
<p>
Before starting, check the current model. If it is below state-of-the-art (e.g., Opus
4.5, GPT 5.2+), recommend switching. Do not block execution.
</p>
<h3>1) Establish context (read-only)</h3>
<p>
Try to infer 1–5 from the environment before asking. Prefer simple, non-technical
questions if you need confirmation.
</p>
<p>Determine (in order):</p>
<ol>
<li>OS and version (Linux/macOS/Windows), container vs host.</li>
<li>Privilege level (root/admin vs user).</li>
<li>Access path (local console, SSH, RDP, tailnet).</li>
<li>Network exposure (public IP, reverse proxy, tunnel).</li>
<li>Hanzo Bot gateway status and bind address.</li>
<li>Backup system and status (e.g., Time Machine, system images, snapshots).</li>
<li>
Deployment context (local mac app, headless gateway host, remote gateway,
container/CI).
</li>
<li>Disk encryption status (FileVault/LUKS/BitLocker).</li>
<li>
OS automatic security updates status. Note: these are not blocking items, but are
highly recommended, especially if Hanzo Bot can access sensitive data.
</li>
<li>
Usage mode for a personal assistant with full access (local workstation vs
headless/remote vs other).
</li>
</ol>
<p>
First ask once for permission to run read-only checks. If granted, run them by default
and only ask questions for items you cannot infer or verify. Do not ask for
information already visible in runtime or command output. Keep the permission ask as a
single sentence, and list follow-up info needed as an unordered list (not numbered)
unless you are presenting selectable choices.
</p>
<p>If you must ask, use non-technical prompts:</p>
<ul>
<li>“Are you using a Mac, Windows PC, or Linux?”</li>
<li>
“Are you logged in directly on the machine, or connecting from another computer?”
</li>
<li>
“Is this machine reachable from the public internet, or only on your home/network?”
</li>
<li>“Do you have backups enabled (e.g., Time Machine), and are they current?”</li>
<li>“Is disk encryption turned on (FileVault/BitLocker/LUKS)?”</li>
<li>“Are automatic security updates enabled?”</li>
<li>
“How do you use this machine?” Examples:
<ul>
<li>Personal machine shared with the assistant</li>
<li>Dedicated local machine for the assistant</li>
<li>Dedicated remote machine/server accessed remotely (always on)</li>
<li>Something else?</li>
</ul>
</li>
</ul>
<p>Only ask for the risk profile after system context is known.</p>
<p>
If the user grants read-only permission, run the OS-appropriate checks by default. If
not, offer them (numbered). Examples:
</p>
<ol>
<li>
OS: <code>uname -a</code>, <code>sw_vers</code>, <code>cat /etc/os-release</code>.
</li>
<li>
Listening ports:
<ul>
<li>
Linux: <code>ss -ltnup</code> (or <code>ss -ltnp</code> if
<code>-u</code> unsupported).
</li>
<li>macOS: <code>lsof -nP -iTCP -sTCP:LISTEN</code>.</li>
</ul>
</li>
<li>
Firewall status:
<ul>
<li>
Linux: <code>ufw status</code>, <code>firewall-cmd --state</code>,
<code>nft list ruleset</code> (pick what is installed).
</li>
<li>
macOS:
<code>/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate</code>
and <code>pfctl -s info</code>.
</li>
</ul>
</li>
<li>Backups (macOS): <code>tmutil status</code> (if Time Machine is used).</li>
</ol>
<h3>2) Run Hanzo Bot security audits (read-only)</h3>
<p>
As part of the default read-only checks, run
<code>hanzo-bot security audit --deep</code>. Only offer alternatives if the user
requests them:
</p>
<ol>
<li><code>hanzo-bot security audit</code> (faster, non-probing)</li>
<li><code>hanzo-bot security audit --json</code> (structured output)</li>
</ol>
<p>Offer to apply Hanzo Bot safe defaults (numbered):</p>
<ol>
<li><code>hanzo-bot security audit --fix</code></li>
</ol>
<p>
Be explicit that <code>--fix</code> only tightens Hanzo Bot defaults and file
permissions. It does not change host firewall, SSH, or OS update policies.
</p>
<p>
If browser control is enabled, recommend that 2FA be enabled on all important
accounts, with hardware keys preferred and SMS not sufficient.
</p>
<h3>3) Check Hanzo Bot version/update status (read-only)</h3>
<p>
As part of the default read-only checks, run <code>hanzo-bot update status</code>.
</p>
<p>Report the current channel and whether an update is available.</p>
<h3>4) Determine risk tolerance (after system context)</h3>
<p>
Ask the user to pick or confirm a risk posture and any required open services/ports
(numbered choices below). Do not pigeonhole into fixed profiles; if the user prefers,
capture requirements instead of choosing a profile. Offer suggested profiles as
optional defaults (numbered). Note that most users pick Home/Workstation Balanced:
</p>
<ol>
<li>
Home/Workstation Balanced (most common): firewall on with reasonable defaults,
remote access restricted to LAN or tailnet.
</li>
<li>
VPS Hardened: deny-by-default inbound firewall, minimal open ports, key-only SSH, no
root login, automatic security updates.
</li>
<li>
Developer Convenience: more local services allowed, explicit exposure warnings,
still audited.
</li>
<li>
Custom: user-defined constraints (services, exposure, update cadence, access
methods).
</li>
</ol>
<h3>5) Produce a remediation plan</h3>
<p>Provide a plan that includes:</p>
<ul>
<li>Target profile</li>
<li>Current posture summary</li>
<li>Gaps vs target</li>
<li>Step-by-step remediation with exact commands</li>
<li>Access-preservation strategy and rollback</li>
<li>Risks and potential lockout scenarios</li>
<li>
Least-privilege notes (e.g., avoid admin usage, tighten ownership/permissions where
safe)
</li>
<li>
Credential hygiene notes (location of Hanzo Bot creds, prefer disk encryption)
</li>
</ul>
<p>Always show the plan before any changes.</p>
<h3>6) Offer execution options</h3>
<p>Offer one of these choices (numbered so users can reply with a single digit):</p>
<ol>
<li>Do it for me (guided, step-by-step approvals)</li>
<li>Show plan only</li>
<li>Fix only critical issues</li>
<li>Export commands for later</li>
</ol>
<h3>7) Execute with confirmations</h3>
<p>For each step:</p>
<ul>
<li>Show the exact command</li>
<li>Explain impact and rollback</li>
<li>Confirm access will remain available</li>
<li>Stop on unexpected output and ask for guidance</li>
</ul>
<h3>8) Verify and report</h3>
<p>Re-check:</p>
<ul>
<li>Firewall status</li>
<li>Listening ports</li>
<li>Remote access still works</li>
<li>Hanzo Bot security audit (re-run)</li>
</ul>
<p>Deliver a final posture report and note any deferred items.</p>
<h2>Required confirmations (always)</h2>
<p>Require explicit approval for:</p>
<ul>
<li>Firewall rule changes</li>
<li>Opening/closing ports</li>
<li>SSH/RDP configuration changes</li>
<li>Installing/removing packages</li>
<li>Enabling/disabling services</li>
<li>User/group modifications</li>
<li>Scheduling tasks or startup persistence</li>
<li>Update policy changes</li>
<li>Access to sensitive files or credentials</li>
</ul>
<p>If unsure, ask.</p>
<h2>Periodic checks</h2>
<p>
After Hanzo Bot install or first hardening pass, run at least one baseline audit and
version check:
</p>
<ul>
<li><code>hanzo-bot security audit</code></li>
<li><code>hanzo-bot security audit --deep</code></li>
<li><code>hanzo-bot update status</code></li>
</ul>
<p>
Ongoing monitoring is recommended. Use the Hanzo Bot cron tool/CLI to schedule
periodic audits (Gateway scheduler). Do not create scheduled tasks without explicit
approval. Store outputs in a user-approved location and avoid secrets in logs. When
scheduling headless cron runs, include a note in the output that instructs the user to
call <code>healthcheck</code> so issues can be fixed.
</p>
<h3>Required prompt to schedule (always)</h3>
<p>
After any audit or hardening pass, explicitly offer scheduling and require a direct
response. Use a short prompt like (numbered):
</p>
<ol>
<li>
“Do you want me to schedule periodic audits (e.g., daily/weekly) via
<code>hanzo-bot cron add</code>?”
</li>
</ol>
<p>If the user says yes, ask for:</p>
<ul>
<li>cadence (daily/weekly), preferred time window, and output location</li>
<li>whether to also schedule <code>hanzo-bot update status</code></li>
</ul>
<p>Use a stable cron job name so updates are deterministic. Prefer exact names:</p>
<ul>
<li><code>healthcheck:security-audit</code></li>
<li><code>healthcheck:update-status</code></li>
</ul>
<p>
Before creating, <code>hanzo-bot cron list</code> and match on exact
<code>name</code>. If found, <code>hanzo-bot cron edit &lt;id&gt; ...</code>. If not
found, <code>hanzo-bot cron add --name &lt;name&gt; ...</code>.
</p>
<p>
Also offer a periodic version check so the user can decide when to update (numbered):
</p>
<ol>
<li>
<code>hanzo-bot update status</code> (preferred for source checkouts and channels)
</li>
<li><code>npm view hanzo-bot version</code> (published npm version)</li>
</ol>
<h2>Hanzo Bot command accuracy</h2>
<p>Use only supported commands and flags:</p>
<ul>
<li><code>hanzo-bot security audit [--deep] [--fix] [--json]</code></li>
<li><code>hanzo-bot status</code> / <code>hanzo-bot status --deep</code></li>
<li><code>hanzo-bot health --json</code></li>
<li><code>hanzo-bot update status</code></li>
<li><code>hanzo-bot cron add|list|runs|run</code></li>
</ul>
<p>Do not invent CLI flags or imply Hanzo Bot enforces host firewall/SSH policies.</p>
<h2>Logging and audit trail</h2>
<p>Record:</p>
<ul>
<li>Gateway identity and role</li>
<li>Plan ID and timestamp</li>
<li>Approved steps and exact commands</li>
<li>Exit codes and files modified (best effort)</li>
</ul>
<p>Redact secrets. Never log tokens or full credential contents.</p>
<h2>Memory writes (conditional)</h2>
<p>
Only write to memory files when the user explicitly opts in and the session is a
private/local workspace (per <code>docs/reference/templates/AGENTS.md</code>).
Otherwise provide a redacted, paste-ready summary the user can decide to save
elsewhere.
</p>
<p>Follow the durable-memory prompt format used by Hanzo Bot compaction:</p>
<ul>
<li>Write lasting notes to <code>memory/YYYY-MM-DD.md</code>.</li>
</ul>
<p>
After each audit/hardening run, if opted-in, append a short, dated summary to
<code>memory/YYYY-MM-DD.md</code> (what was checked, key findings, actions taken, any
scheduled cron jobs, key decisions, and all commands executed). Append-only: never
overwrite existing entries. Redact sensitive host details (usernames, hostnames, IPs,
serials, service names, tokens). If there are durable preferences or decisions (risk
posture, allowed ports, update policy), also update <code>MEMORY.md</code> (long-term
memory is optional and only used in private sessions).
</p>
<p>
If the session cannot write to the workspace, ask for permission or provide exact
entries the user can paste into the memory files.
</p>
</div>
</div>
<aside class="detail-sidebar">
<div class="sidebar-card">
<h3>Info</h3>
<div class="info-row">
<span class="label">Category</span
><span class="value"><span class="category-badge">Utilities</span></span>
</div>
<div class="info-row">
<span class="label">Requires</span><span class="value">None</span>
</div>
<div class="info-row">
<span class="label">Size</span><span class="value">10.3 KB</span>
</div>
<div class="info-row">
<span class="label">Source</span
><span class="value"
><a
href="https://github.com/hanzoai/bot/blob/main/skills/healthcheck/SKILL.md"
target="_blank"
rel="noopener"
>GitHub</a
></span
>
</div>
<div class="info-row" id="lastUpdated">
<span class="label">Updated</span><span class="value">—</span>
</div>
</div>
<div class="sidebar-card sidebar-actions">
<a
href="https://github.com/hanzoai/bot/blob/main/skills/healthcheck/SKILL.md"
class="btn-outline"
target="_blank"
rel="noopener"
>View on GitHub</a
>
<a href="/chat" class="btn-primary">Open in Hanzo Bot</a>
</div>
<div class="sidebar-card">
<h3>Web3 Native</h3>
<div class="web3-badge">&#9670; On-Chain Ready</div>
<div class="web3-features">
<div class="web3-feat">DID identity for every bot</div>
<div class="web3-feat">Integrated wallet &amp; payments</div>
<div class="web3-feat">Prefund balance, draw on credits</div>
<div class="web3-feat">On-chain &amp; fiat payment rails</div>
<div class="web3-feat">Send funds to bots directly</div>
</div>
</div>
</aside>
</div>
</main>
<footer class="footer">
<div class="footer-inner">
<div class="footer-grid">
<div class="footer-brand">
<div class="footer-logo">
<svg viewBox="0 0 67 67" xmlns="http://www.w3.org/2000/svg">
<path d="M22.21 67V44.6369H0V67H22.21Z" fill="#fff" />
<path d="M0 44.6369L22.21 46.8285V44.6369H0Z" fill="#fff" />
<path
d="M66.7038 22.3184H22.2534L0.0878906 44.6367H44.4634L66.7038 22.3184Z"
fill="#fff"
/>
<path d="M22.21 0H0V22.3184H22.21V0Z" fill="#fff" />
<path d="M66.7198 0H44.5098V22.3184H66.7198V0Z" fill="#fff" />
<path d="M66.6753 22.3185L44.5098 20.0822V22.3185H66.6753Z" fill="#fff" />
<path d="M66.7198 67V44.6369H44.5098V67H66.7198Z" fill="#fff" /></svg
><span>Hanzo</span>
</div>
<p>Build, deploy, and manage autonomous AI agents across every platform.</p>
<div class="footer-social">
<a href="https://x.com/hanaborteam" aria-label="X"
><svg viewBox="0 0 24 24" fill="currentColor">
<path
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"
/></svg
></a>
<a href="https://linkedin.com/company/hanzo-ai" aria-label="LinkedIn"
><svg viewBox="0 0 24 24" fill="currentColor">
<path
d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"
/></svg
></a>
<a href="https://discord.gg/XthHQQj" aria-label="Discord"
><svg viewBox="0 0 24 24" fill="currentColor">
<path
d="M20.317 4.37a19.791 19.791 0 00-4.885-1.515.074.074 0 00-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 00-5.487 0 12.64 12.64 0 00-.617-1.25.077.077 0 00-.079-.037A19.736 19.736 0 003.677 4.37a.07.07 0 00-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 00.031.057 19.9 19.9 0 005.993 3.03.078.078 0 00.084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 00-.041-.106 13.107 13.107 0 01-1.872-.892.077.077 0 01-.008-.128 10.2 10.2 0 00.372-.292.074.074 0 01.077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 01.078.01c.12.098.246.198.373.292a.077.077 0 01-.006.127 12.299 12.299 0 01-1.873.892.077.077 0 00-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 00.084.028 19.839 19.839 0 006.002-3.03.077.077 0 00.032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 00-.031-.03z"
/></svg
></a>
</div>
</div>
<div class="footer-col">
<h4>Products</h4>
<a href="https://hanzo.ai">Hanzo AI</a><a href="https://hanzo.app">Hanzo App</a
><a href="https://hanzo.bot">Hanzo Bot</a><a href="https://hanzo.ai/dev">Hanzo Dev</a
><a href="https://hanzo.ai/cloud">Hanzo Cloud</a
><a href="https://hanzo.app/download">Desktop App</a><a href="/book">The Hanzo Book</a>
</div>
<div class="footer-col">
<h4>Developers</h4>
<a href="https://docs.hanzo.bot">Documentation</a
><a href="https://github.com/hanzoai/bot">GitHub</a
><a href="https://docs.hanzo.bot/api">API Reference</a><a href="/skills">Skills Hub</a
><a href="https://docs.hanzo.bot/cli">CLI Reference</a>
</div>
<div class="footer-col">
<h4>Solutions</h4>
<a href="#">Customer Support</a><a href="#">Developer Operations</a
><a href="#">Marketing</a><a href="#">Finance</a><a href="#">Security</a
><a href="#">Enterprise</a>
</div>
<div class="footer-col">
<h4>Company</h4>
<a href="https://hanzo.ai/about">About</a><a href="https://hanzo.ai/blog">Blog</a
><a href="https://hanzo.ai/careers">Careers</a
><a href="https://hanzo.ai/contact">Contact</a
><a href="https://hanzo.ai/privacy">Privacy</a><a href="https://hanzo.ai/terms">Terms</a
><a href="https://status.hanzo.ai">Status</a>
</div>
</div>
<div class="footer-bottom">
<span>&copy; 2016–2026 Hanzo Industries. All rights reserved.</span>
<span>hanzo.ai</span>
</div>
</div>
</footer>
<script>
(function () {
var slug = "healthcheck";
var el = document.getElementById("lastUpdated");
if (!el) return;
var key = "gh-commits-" + slug;
var cached = sessionStorage.getItem(key);
function show(data) {
if (!Array.isArray(data) || !data[0] || !data[0].commit) return;
var d = new Date(data[0].commit.author.date);
var days = Math.floor((Date.now() - d.getTime()) / 86400000);
var txt = days === 0 ? "today" : days === 1 ? "yesterday" : days + " days ago";
el.querySelector(".value").textContent = txt;
}
if (cached) {
try {
show(JSON.parse(cached));
} catch (e) {}
} else {
fetch(
"https://api.github.com/repos/hanzoai/bot/commits?path=skills/" +
slug +
"/SKILL.md&per_page=1",
)
.then(function (r) {
return r.json();
})
.then(function (d) {
try {
sessionStorage.setItem(key, JSON.stringify(d));
} catch (e) {}
show(d);
})
.catch(function () {});
}
})();
</script>
</body>
</html>