{"id":"6d1f4c2d-77e7-4c87-bf38-5b2ed3fa1e50","entityType":"agent","slug":"clawhub-zw008-truenas-aiops","name":"truenas-aiops","canonicalUrl":"https://www.xpersona.co/agent/clawhub-zw008-truenas-aiops","canonicalPath":"/agent/clawhub-zw008-truenas-aiops","generatedAt":"2026-10-10T10:45:13.385Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:08:26.358Z","emptyReason":null},"description":"Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks. Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance. Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only). Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.6K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:truenas-aiops","sourceUrl":"https://clawhub.ai/zw008/truenas-aiops","homepage":"https://clawhub.ai/zw008/skills/truenas-aiops","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/zw008/truenas-aiops","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/zw008/skills/truenas-aiops","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":64,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"truenas-aiops technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:08:26.358Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:08:26.358Z","emptyReason":null},"stars":null,"forks":null,"downloads":1568,"packageName":null,"latestVersion":"0.11.5","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:08:26.357Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T08:08:26.358Z","lastCrawledAt":"2026-10-10T08:08:26.357Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T08:08:26.357Z","lastVerifiedAt":null,"highlights":[{"version":"0.11.5","createdAt":"2026-09-16T23:26:39.051Z","changelog":"Version 0.11.5 - Updated references/agent-guardrails.md with new or revised content. - Removed skill-card.md from the project.","fileCount":7,"zipByteSize":17414},{"version":"0.11.4","createdAt":"2026-09-16T05:17:42.506Z","changelog":"truenas-aiops 0.11.4 - Removed the skill-card.md file from the package. - No functional changes to the skill logic or user experience.","fileCount":7,"zipByteSize":17211},{"version":"0.11.3","createdAt":"2026-09-15T06:21:20.367Z","changelog":"truenas-aiops 0.11.3 - Removed the file: skill-card.md. - No changes to functionality or skill behavior.","fileCount":7,"zipByteSize":17503},{"version":"0.11.2","createdAt":"2026-09-12T14:45:28.541Z","changelog":"truenas-aiops 0.11.2 - Updated documentation in SKILL.md (e.g., OpenClaw plugin install command now uses @zw008/truenas-aiops instead of @aiops-tools/truenas-aiops) - Removed skill-card.md file - No code or functional changes; this release is documentation and metadata only","fileCount":7,"zipByteSize":17501},{"version":"0.11.1","createdAt":"2026-09-12T10:28:25.487Z","changelog":"truenas-aiops 0.11.1 - Dropped the skill-card.md file (de-duplicating/streamlining docs). - Updated SKILL.md with OpenClaw plugin installation instructions and requirements for `uvx` on `PATH`. - No code or functionality changes; this is a documentation-only update.","fileCount":7,"zipByteSize":17440},{"version":"0.11.0","createdAt":"2026-09-12T01:15:59.526Z","changelog":"- Metadata requirements updated: now supports either \"truenas-aiops\" or \"uvx\" as valid binaries. - Metadata environment variables clarified; both TRUENAS_AIOPS_CONFIG and TRUENAS_AIOPS_MASTER_PASSWORD are now listed as optional. - skill-card.md file removed for this release. - No user-facing functional or compatibility changes.","fileCount":7,"zipByteSize":17379},{"version":"0.10.0","createdAt":"2026-08-10T06:54:12.834Z","changelog":"- Removed the file skill-card.md. - No changes to core functionality or documentation content. - Minor cleanup of repository files.","fileCount":7,"zipByteSize":17290},{"version":"0.9.0","createdAt":"2026-08-03T05:55:03.092Z","changelog":"truenas-aiops v0.9.0 - Removed the file: skill-card.md - No functional or behavioral changes in the skill's capabilities.","fileCount":7,"zipByteSize":17352}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:truenas-aiops","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:truenas-aiops` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/zw008/truenas-aiops before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T10:45:13.381Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-truenas-aiops/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T08:08:26.358Z","emptyReason":null},"readme":"Skill: truenas-aiops\n\nOwner: zw008\n\nSummary: Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks. Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance. Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only). Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.\n\nTags: latest:0.11.5\n\nVersion history:\n\nv0.11.5 | 2026-09-16T23:26:39.051Z | auto\n\nVersion 0.11.5\n\n- Updated references/agent-guardrails.md with new or revised content.\n- Removed skill-card.md from the project.\n\nv0.11.4 | 2026-09-16T05:17:42.506Z | auto\n\ntruenas-aiops 0.11.4\n\n- Removed the skill-card.md file from the package.\n- No functional changes to the skill logic or user experience.\n\nv0.11.3 | 2026-09-15T06:21:20.367Z | auto\n\ntruenas-aiops 0.11.3\n\n- Removed the file: skill-card.md.\n- No changes to functionality or skill behavior.\n\nv0.11.2 | 2026-09-12T14:45:28.541Z | auto\n\ntruenas-aiops 0.11.2\n\n- Updated documentation in SKILL.md (e.g., OpenClaw plugin install command now uses @zw008/truenas-aiops instead of @aiops-tools/truenas-aiops)\n- Removed skill-card.md file\n- No code or functional changes; this release is documentation and metadata only\n\nv0.11.1 | 2026-09-12T10:28:25.487Z | auto\n\ntruenas-aiops 0.11.1\n\n- Dropped the skill-card.md file (de-duplicating/streamlining docs).\n- Updated SKILL.md with OpenClaw plugin installation instructions and requirements for `uvx` on `PATH`.\n- No code or functionality changes; this is a documentation-only update.\n\nv0.11.0 | 2026-09-12T01:15:59.526Z | auto\n\n- Metadata requirements updated: now supports either \"truenas-aiops\" or \"uvx\" as valid binaries.\n- Metadata environment variables clarified; both TRUENAS_AIOPS_CONFIG and TRUENAS_AIOPS_MASTER_PASSWORD are now listed as optional.\n- skill-card.md file removed for this release.\n- No user-facing functional or compatibility changes.\n\nv0.10.0 | 2026-08-10T06:54:12.834Z | auto\n\n- Removed the file skill-card.md.\n- No changes to core functionality or documentation content.\n- Minor cleanup of repository files.\n\nv0.9.0 | 2026-08-03T05:55:03.092Z | auto\n\ntruenas-aiops v0.9.0\n\n- Removed the file: skill-card.md\n- No functional or behavioral changes in the skill's capabilities.\n\nv0.8.1 | 2026-08-02T14:54:38.888Z | auto\n\nTrueNAS AIops 0.8.1\n\n- Upgraded from mock-validated to live-verified against real TrueNAS SCALE 25.04 and 26 appliances; coverage, transport support, and known limitations documented in docs/VERIFICATION.md.\n- Updated documentation and compatibility notes to reflect live endpoint verification and clarify S.M.A.R.T. test (disk health) coverage.\n- Revised CLI reference and setup guide for improved onboarding clarity.\n- Enhanced description and compatibility hints to emphasize support boundaries and recent live validation status.\n\nv0.8.0 | 2026-08-02T14:50:08.567Z | auto\n\nTrueNAS AIops 0.8.0\n\n- Updated documentation in `references/capabilities.md` to reflect current capabilities.\n- Removed the `skill-card.md` file for cleanup.\n- No functional code changes in this release; documentation and metadata only.\n\nv0.7.0 | 2026-08-02T09:42:05.754Z | auto\n\ntruenas-aiops 0.7.0\n\n- Removed the skill-card.md file from the project.\n\nv0.6.0 | 2026-07-21T09:43:07.920Z | auto\n\ntruenas-aiops v0.6.0\n\n- Updated documentation for agent guardrails and setup guide.\n- Improved and clarified SKILL.md compatibility guidelines and risk-tier descriptions.\n- Refined governance harness section to emphasize labelling and descriptive risk tiers.\n- Removed redundant file: skill-card.md.\n\nv0.5.0 | 2026-07-20T11:17:32.812Z | auto\n\n- Updated documentation: removed the skill-card.md file.\n- Minor adjustments to referenced capabilities documentation.\n- No changes to skill functionality or code behavior.\n- This release involves only documentation/metadata cleanup.\n\nv0.4.0 | 2026-07-19T03:53:31.955Z | auto\n\n**Expanded diagnostics, new guardrails, and improved documentation.**\n\n- Added diagnostics/RCA tools: root cause analysis for pool health and alert/capacity issues.\n- Introduced an \"Agent Guardrails\" reference and governance documentation.\n- Increased MCP tools coverage from 21 to 25, enhancing TrueNAS operations support.\n- Improved out-of-scope and diagnostic usage guidance throughout documentation.\n- Removed legacy/duplicate files & streamlined file organization.\n\nv0.3.0 | 2026-07-17T05:54:56.185Z | auto\n\n- Removed the sample file skill-card.md.\n- No changes to functionality or documentation aside from sample file cleanup.\n\nv0.2.0 | 2026-07-13T13:08:02.858Z | auto\n\ntruenas-aiops v0.2.0\n\n- Removed redundant skill-card.md file for a leaner codebase.\n- SKILL.md updated and streamlined; no functional or user-facing changes to documented features.\n- Skill now includes only SKILL.md as primary documentation, reducing maintenance overhead.\n\nv0.1.0 | 2026-06-28T05:47:09.270Z | auto\n\ntruenas-aiops 0.1.0 (preview release)\n\n- Initial release providing TrueNAS SCALE management with 21 governed operations (read/write) via CLI/MCP.\n- Includes health/system overview, ZFS pool/dataset/snapshot management, disk checks, alerts, services, and replication tasks.\n- Every write operation is audited, risk-tiered, guarded, and supports undo (where possible); destructive ops require double confirmation.\n- Credentials are stored encrypted; no plaintext on disk; legacy env var fallback with deprecation warning.\n- No external dependencies required beyond httpx and MCP SDK; no outbound webhooks.\n- Preview only — functionality mock-validated, not yet tested on a live TrueNAS appliance.\n\nArchive index:\n\nArchive v0.11.5: 7 files, 17414 bytes\n\nFiles: references/agent-guardrails.md (9088b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2780b), SKILL.md (16595b), _meta.json (133b)\n\nFile v0.11.5:SKILL.md\n\n---\nname: truenas-aiops\nslug: truenas-aiops\ndisplayName: \"TrueNAS AIops\"\nsummary: \"Governed TrueNAS SCALE storage ops — 25 MCP tools with audit, budget, undo guards.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/TrueNAS-AIops\ntags: [aiops, mcp, governance, truenas]\ndescription: >\n  Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks.\n  Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance.\n  Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only).\n  Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.\ninstaller:\n  kind: uv\n  package: truenas-aiops\nargument-hint: \"[pool/dataset/snapshot id or describe your TrueNAS task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"truenas-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"TRUENAS_AIOPS_CONFIG\",\"TRUENAS_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/TrueNAS-AIops\",\"emoji\":\"🗄️\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed TrueNAS SCALE storage operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.\n  All write operations are audited to a local SQLite DB under ~/.truenas-aiops/ (relocatable via TRUENAS_AIOPS_HOME).\n  Credentials: Each TrueNAS target's API key is stored ENCRYPTED in ~/.truenas-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'truenas-aiops init' to onboard, or 'truenas-aiops secret set <target>' to add one (create the key in the TrueNAS UI: Credentials → API Keys). The store is unlocked by a master password from TRUENAS_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var TRUENAS_<TARGET_NAME_UPPER>_APIKEY is still honoured as a fallback with a deprecation warning (migrate with 'truenas-aiops secret migrate'). The API key is sent as an Authorization: Bearer header at request time and held only in memory; keys are never logged or echoed.\n  Destructive operations (snapshot delete, service restart) require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + risk-tier labelling). snapshot_create records an inverse snapshot_delete undo descriptor; snapshot_delete is high-risk and irreversible (captures BEFORE state, records no undo).\n  Webhooks: none — no outbound network calls beyond the configured TrueNAS REST API endpoint.\n  SSL: verify_ssl defaults to true; disable only for self-signed lab certificates.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Routes are resolved against the appliance's own method list and were cross-checked on live 25.04 and 26 appliances; S.M.A.R.T. on failing media remains unverified (see docs/VERIFICATION.md).\n---\n\n# TrueNAS AIops\n\n> **Disclaimer**: This is a community-maintained open-source project and is **not affiliated with, endorsed by, or sponsored by iXsystems or the TrueNAS project.** \"TrueNAS\" is a trademark of its owner. Source code is publicly auditable at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops) under the MIT license.\n\nGoverned TrueNAS SCALE storage operations — **25 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.truenas-aiops/`, policy engine, token/runaway budget guard, undo-token recording, and descriptive risk tiers. The TrueNAS API key is stored **encrypted** (`~/.truenas-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`truenas_aiops.governance`) — truenas-aiops has no external skill-family dependency. **Verification**: coverage focuses on common TrueNAS operations and is not exhaustive, but it is no longer mock-only — reads, governed writes with audit + undo, the WebSocket transport, degraded-pool RCA, replication and cloud-sync have all been exercised against live TrueNAS SCALE 25.04 and 26 appliances. `docs/VERIFICATION.md` records exactly what was checked and what is still open.\n\n## What This Skill Does\n\n| Category | Tools | Count | Read or Write |\n|----------|-------|:-----:|:-------------:|\n| **Overview / System** | health overview, system info | 2 | 2 read |\n| **Diagnostics / RCA** | pool health RCA, alert & capacity RCA | 2 | 2 read |\n| **Pools** | list, get, status, scrub status, capacity | 5 | 5 read |\n| | scrub start | 1 | 1 write (medium) |\n| **Datasets** | list, get | 2 | 2 read |\n| | create | 1 | 1 write (medium) |\n| **Snapshots** | list | 1 | 1 read |\n| | create (medium), delete (high) | 2 | 2 write |\n| **Disks** | list, S.M.A.R.T. results | 2 | 2 read |\n| **Alerts** | list | 1 | 1 read |\n| **Services** | list | 1 | 1 read |\n| | restart | 1 | 1 write (medium) |\n| **Replication** | replication tasks, cloud-sync tasks | 2 | 2 read |\n\n## Quick Install\n\n```bash\nuv tool install truenas-aiops\ntruenas-aiops init       # interactive wizard: connection + encrypted API key\ntruenas-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/truenas-aiops\nopenclaw skills info truenas-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a TrueNAS appliance (`overview`): pool capacity/health, alerts, running services\n- Root-cause a degraded/full pool (`diagnose pool-health`) or a wall of alerts (`diagnose alerts`) — worst-first findings that cite the measured number\n- List/inspect ZFS pools, datasets, and snapshots\n- Create a snapshot before a risky change; start a pool scrub\n- Check disk health and S.M.A.R.T. self-test results\n- List and restart system services (smb/nfs/ssh)\n- Inspect replication and cloud-sync tasks\n\n**Do NOT use when** the target is not a TrueNAS SCALE appliance — other NAS/storage or backup products, hypervisor VM lifecycle, Kubernetes/containers, and network devices are out of scope for this skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| TrueNAS pools / datasets / snapshots / ZFS health | **truenas-aiops** (this skill) |\n| Backup software job/restore operations | a backup-software ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### Root-cause a degraded or full pool (start here)\n\n1. `truenas-aiops diagnose pool-health` → worst-first findings: bad ZFS state (DEGRADED/FAULTED/OFFLINE), non-zero read/write/checksum/scan error counters, and pools over 80%/90% capacity — each citing the measured number\n2. `truenas-aiops pool status <pool_id>` → inspect the topology / scan detail the finding cited\n3. `truenas-aiops pool scrub-start <pool_name>` → kick an integrity scrub (governed, medium risk); poll with `pool scrub-status`\n4. `truenas-aiops diagnose alerts` → cross-check active alerts by level and any datasets nearing their quota/available ceiling\n\n### Snapshot a dataset before a change, then roll back if needed\n\n1. `truenas-aiops dataset list` → confirm the dataset id (e.g. `tank/data`)\n2. `truenas-aiops snapshot create tank/data pre-change` → records an inverse `snapshot_delete` undo descriptor\n3. Make your change; if it went wrong, the snapshot is your recovery point\n4. `truenas-aiops snapshot delete tank/data@pre-change --dry-run` → preview; then without `--dry-run` (double confirm) — IRREVERSIBLE, captures BEFORE state, no undo\n\n### Scrub a pool and follow it\n\n1. `truenas-aiops pool list` → find the pool name and health\n2. `truenas-aiops pool scrub-start tank` → starts the integrity scrub\n3. `truenas-aiops pool scrub-status <pool_id>` → check `state` / `percentage`; do not re-issue (the runaway budget guard backs a tight poll loop)\n\n## Usage Mode\n\n| Scenario | Recommended | Why |\n|----------|:-----------:|-----|\n| Local/small models | **CLI** | fewer tokens than MCP |\n| Cloud models (Claude, GPT) | Either | MCP gives structured JSON I/O |\n| Automated pipelines | **MCP** | type-safe parameters, audited |\n\n## MCP Tools (25 — 19 read, 6 write)\n\n| Category | Tools | R/W |\n|----------|-------|:---:|\n| Overview / System | `overview`, `system_info` | Read |\n| Diagnostics / RCA | `pool_health_rca`, `alert_and_capacity_rca` | Read |\n| Pools | `pool_list`, `pool_get`, `pool_status`, `scrub_status`, `pool_capacity` | Read |\n| | `pool_scrub_start` | Write |\n| Datasets | `dataset_list`, `dataset_get` | Read |\n| | `dataset_create` | Write |\n| Snapshots | `snapshot_list` | Read |\n| | `snapshot_create`, `snapshot_delete` | Write |\n| Disks | `disk_list`, `smart_test_results` | Read |\n| Alerts | `alert_list` | Read |\n| Services | `service_list` | Read |\n| | `service_restart` | Write |\n| Replication | `replication_list`, `cloudsync_list` | Read |\n| Undo (governance) | `undo_list` | Read |\n| | `undo_apply` | Write |\n\n**Harness features that light up**: `snapshot_create` passes an `undo=` lambda so the harness records an inverse `snapshot_delete` descriptor (with `_undo_id`) to the undo store. `snapshot_delete` is tagged `risk_level=high`, captures the snapshot's BEFORE state, and declares no undo (it is irreversible). `pool_scrub_start`, `dataset_create`, and `service_restart` are `medium` risk and capture prior state where relevant. All 25 tools are audit-logged under `~/.truenas-aiops/` and pass through the budget/runaway guard, with a descriptive risk-tier label on each audit row. Start any triage with `overview`.\n\n## CLI Quick Reference\n\n```bash\ntruenas-aiops init                                    # onboarding wizard (encrypted API key)\ntruenas-aiops overview [--target <t>]                 # health summary\ntruenas-aiops system [--target <t>]                   # version / hostname / memory / uptime\ntruenas-aiops diagnose pool-health                    # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts                         # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity                           # size / allocated / free / used%\ntruenas-aiops pool scrub-start <pool_name>\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>                # e.g. tank/data\ntruenas-aiops dataset create <tank/path> [--dry-run]\ntruenas-aiops snapshot list [--dataset tank/data] [--limit 200]\ntruenas-aiops snapshot create <dataset> <name>\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # double confirm, IRREVERSIBLE\ntruenas-aiops disk list\ntruenas-aiops disk smart                              # S.M.A.R.T. self-test results\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops service restart <service> [--dry-run]   # double confirm (smb/nfs/ssh)\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\ntruenas-aiops secret set <target>                     # store API key encrypted\ntruenas-aiops secret list                             # names only\ntruenas-aiops secret migrate                          # import legacy plaintext .env\ntruenas-aiops secret rotate-password\ntruenas-aiops doctor\ntruenas-aiops mcp                                     # start MCP server (stdio)\n```\n\nSee `references/cli-reference.md` for the full command list, and\n`references/agent-guardrails.md` when driving these tools with a smaller /\nlocal model (enforced guardrails, ready-to-paste system prompt).\n\n## Troubleshooting\n\n### \"Config file not found\"\nRun `truenas-aiops init` to set up your first target (writes `~/.truenas-aiops/config.yaml` and stores the API key encrypted).\n\n### \"No API key for target '<name>'\"\nAdd it to the encrypted store: `truenas-aiops secret set <name>` (prompts hidden), or run `truenas-aiops init`. Create the key in the TrueNAS UI under Credentials → API Keys. For non-interactive use (MCP/CI), also export `TRUENAS_AIOPS_MASTER_PASSWORD` so the store can be unlocked without a prompt.\n\n### \"Master password not set\" / \"Wrong master password\"\nThe encrypted store `~/.truenas-aiops/secrets.enc` is unlocked by `TRUENAS_AIOPS_MASTER_PASSWORD` (or an interactive prompt). If you forgot it, delete `secrets.enc` and re-run `truenas-aiops init`. Rotate it with `truenas-aiops secret rotate-password`.\n\n### \"Authentication/authorization failed (401/403)\"\nThe API key is wrong or revoked, or the account lacks permission. Regenerate the key in the TrueNAS UI (Credentials → API Keys) and update it: `truenas-aiops secret set <name>`.\n\n### \"Could not reach TrueNAS … check the host/port\"\nConfirm the TrueNAS web/REST endpoint is reachable on the configured port (default 443) and `api_path` is `/api/v2.0`. For self-signed certificates set `verify_ssl: false` on the target (lab only).\n\n### \"Resource not found (404)\"\nThe pool/dataset/snapshot id is stale. List the parent collection first (`pool list`, `dataset list`, `snapshot list`) to get a current id.\n\n## Audit & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (scope the TrueNAS API key to a\nlimited-privilege account and writes then fail at the appliance). There is no\nread-only switch, policy file, or approval gate.\n\n- API key stored **encrypted** in `~/.truenas-aiops/secrets.enc` (Fernet/AES-128 + scrypt key derivation; chmod 600) — never plaintext on disk; the master password is never stored, only a per-store salt + ciphertext.\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.truenas-aiops/audit.db` (relocatable via `TRUENAS_AIOPS_HOME`): params (secrets redacted), result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `TRUENAS_AUDIT_APPROVED_BY` / `TRUENAS_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: cumulative tool calls and wall-time are capped, and a tight scrub/poll loop trips a circuit breaker.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; CLI writes execute through the same governed tools, so they are audited + undo-recorded.\n- Reversible writes capture the real fetched before-state and record an inverse descriptor (e.g. `snapshot_create` → `snapshot_delete`) that replays against the tool's own signature.\n\nThe harness is bundled in the package — no external dependency, no manual setup. See `references/setup-guide.md` for security details.\n\n## Contributing & feature requests\n\nCoverage is intentionally focused, and what has actually been verified against live appliances is recorded in `docs/VERIFICATION.md`. **Missing a capability you need, or hit an endpoint that needs fixing for your TrueNAS version?** Open an issue or pull request at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues) — feature requests, contributions, and comments are all welcome.\n\n## License\n\nMIT — [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops)\n\nFile v0.11.5:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"truenas-aiops\",\n  \"version\": \"0.11.5\",\n  \"publishedAt\": 1789601199051\n}\n\nFile v0.11.5:references/agent-guardrails.md\n\n# Agent guardrails — running truenas-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Scope the TrueNAS API key to a\n  limited-privilege account (the key inherits its user's permissions). A write\n  then fails at the appliance, which is the only place the permission actually\n  lives — a revoked permission cannot be argued around by a model, but a\n  skill-side flag can.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Don't invent a value when a field is missing\" | A field the TrueNAS middleware did not return comes back as `null`, never as `\"\"`. Absent and empty are distinguishable in the payload — a disk with no `serial`, a dataset with no `mountpoint`, a replication task with no `state` all report `null`. |\n| \"Tell me if the output was cut off\" | `snapshot_list` returns `{\"snapshots\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}` and `undo_list` the same shape under `undos`. Truncation is measured, not guessed from a length coincidence. This matters most for snapshots: a periodic snapshot task retaining hourly/daily/weekly across a few datasets produces thousands of rows. |\n| \"Preserve the ordering / tell me what's most urgent\" | `pool_health_rca` and `alert_and_capacity_rca` findings carry an explicit 1-based `rank`, worst-first. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `snapshot delete` and `service restart` at the CLI require a `--dry-run`-able preview plus double confirmation. `snapshot_delete` captures the BEFORE state for the audit record. |\n| \"Log what you did\" | Every governed call is audited to `~/.truenas-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. `snapshot_create` additionally records a replayable inverse undo token. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n| \"Don't paraphrase the pool status\" | Pool `status` and `healthy` are passed through verbatim from ZFS — the ops layer never normalises `HEALTHY` / `DEGRADED` / `FAULTED` / `OFFLINE`. Only the model can break that; see the prompt below. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a TrueNAS SCALE storage appliance through the truenas-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current TrueNAS appliance, you MUST\n  call a tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit instead of treating\n  the partial result as complete.\n- A null field means the middleware did not return that value. Report it as\n  \"not available\" — never infer it.\n- Report ZFS status strings exactly as returned: HEALTHY, DEGRADED, FAULTED,\n  OFFLINE, UNAVAIL, REMOVED. Do not paraphrase \"DEGRADED\" as \"having issues\",\n  and do not translate or prettify alert levels or IDs.\n- When an RCA result has findings, work in \"rank\" order and cite the measured\n  number in each finding's \"detail\" (used-percent, error counters, alert level).\n\nIDENTIFIERS\n- A pool name (\"tank\") is not a dataset path (\"tank/data/vm\") and neither is a\n  snapshot id (\"tank/data@auto-2026-07-18\"). A snapshot id is always\n  <dataset>@<snapshot-name>. Do not construct one by guessing; take it from\n  snapshot_list.\n- A disk device name (\"sda\") is not a disk serial and is not stable across\n  reboots or controller changes. Quote both when identifying a disk.\n- Service names are the TrueNAS middleware names (\"smb\", \"nfs\", \"ssh\"), not\n  systemd unit names.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert a capacity, redundancy, or performance problem unless a tool\n  result supports it.\n- Do not add generic advice that does not follow from the tool output.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — snapshot deletion is irreversible and\ntakes any dependent clones with it:\n\n```bash\n# e.g. connect with an API key for a limited-privilege TrueNAS account that\n# lacks write access. Then:\ntruenas-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport TRUENAS_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport TRUENAS_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\n\n## TrueNAS-specific notes worth knowing\n\n- **A dataset path is not a pool name.** `tank` is a pool; `tank/data/vm` is a\n  dataset inside it. `pool_get`/`pool_status` take a pool id; `dataset_get`\n  takes the full dataset path. Passing one where the other is expected returns a\n  404 from the middleware, not a helpful error.\n- **Snapshot deletion is irreversible and destroys dependent clones.** ZFS\n  clones are backed by their origin snapshot; deleting\n  `tank/data@auto-2026-07-18` takes any clone promoted from it with it. That is\n  why `snapshot_delete` is `high` risk, declares no undo, and only captures the\n  BEFORE state for the audit record. There is no \"restore from the recycle bin\".\n- **Report pool status verbatim.** `HEALTHY` and `DEGRADED` are ZFS states with\n  precise meanings — `DEGRADED` means redundancy is lost but the pool is still\n  serving I/O, which is a very different operational posture from `FAULTED`.\n  Paraphrasing loses the distinction an operator acts on.\n- **A scrub is not a repair.** `pool_scrub_start` kicks an integrity check; it\n  will surface checksum errors and repair what redundancy allows, but it does\n  not replace a failing disk. It is also long-running — poll `scrub_status`,\n  never re-issue.\n- **`healthy: false` with status `ONLINE` is real.** ZFS reports it after recent\n  errors or an incomplete resilver. `pool_health_rca` flags it as a warning\n  rather than swallowing it.\n- **Capacity thresholds are about ZFS, not disk space etiquette.** ZFS is\n  copy-on-write; above roughly 80% it slows and above 90% it fragments sharply.\n  The RCA thresholds (`CAP_WARN_PCT` 80, `CAP_CRIT_PCT` 90) exist for that\n  reason and are cited in every capacity finding.\n- **Dataset usage is measured against a quota when one is set**, otherwise\n  against `used + available` headroom. The finding text says which.\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer `overview` and the two RCA\n  tools (`pool_health_rca`, `alert_and_capacity_rca`) — they do the multi-step\n  correlation inside one call, so the model does not have to chain reads and\n  keep pool/dataset ids straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions; filter `snapshot_list` to one dataset and use `limit` deliberately\n  rather than pulling every snapshot on the appliance.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.5:references/capabilities.md\n\n# truenas-aiops capabilities\n\n> 25 MCP tools (19 read, 6 write). Routes are resolved against the appliance's\n> own method list and were cross-checked on live TrueNAS SCALE 25.04 and 26\n> appliances; see docs/VERIFICATION.md for what remains unverified.\n\n## Read tools (19)\n\n| Tool | REST (modelled) | Returns |\n|------|----------------|---------|\n| `overview` | fan-out | pools (capacity/health), alerts by level, running services |\n| `system_info` | `GET /system/info` | version, hostname, memory, cores, uptime |\n| `pool_health_rca` | `GET /pool` | worst-first findings: bad ZFS state, read/write/checksum/scan error counts, capacity over 80%/90% |\n| `alert_and_capacity_rca` | `POST /alert/list` + `GET /pool/dataset` | worst-first findings: active alerts by level + datasets near quota/available ceiling |\n| `pool_list` | `GET /pool` | id, name, status, healthy, size/allocated/free |\n| `pool_get` | `GET /pool/id/{id}` | single pool detail |\n| `pool_status` | `GET /pool/id/{id}` | health + scan + topology summary |\n| `scrub_status` | `GET /pool/id/{id}` | scrub function/state/percentage |\n| `pool_capacity` | `GET /pool` | size/allocated/free + used% per pool |\n| `dataset_list` | `GET /pool/dataset` | id, name, type, pool, used/available |\n| `dataset_get` | `GET /pool/dataset/id/{id}` | single dataset detail |\n| `snapshot_list` | `GET /zfs/snapshot` | `{snapshots, returned, limit, truncated}` — id, dataset, name, used (opt. filter by dataset; default limit 200) |\n| `disk_list` | `GET /disk` | name, serial, model, size, pool |\n| `smart_test_results` | `GET /smart/test/results` | latest S.M.A.R.T. self-test per disk |\n| `alert_list` | `POST /alert/list` | level, message, class, dismissed |\n| `service_list` | `GET /service` | name, state (RUNNING/STOPPED), enable |\n| `replication_list` | `GET /replication` | name, direction, transport, state (PENDING/RUNNING/FINISHED/ERROR, never absent), error, lastSnapshot, lastRun |\n| `cloudsync_list` | `GET /cloudsync` | description, direction, path, state (the last run's job state; null until it runs) |\n| `undo_list` | governance store | recorded reversible writes / not-yet-applied undo tokens |\n\n## Write tools (6)\n\n| Tool | Risk | REST (modelled) | Undo / safety |\n|------|------|----------------|---------------|\n| `pool_scrub_start` | medium | `POST /pool/scrub/run` | captures prior scan state; no undo (non-destructive); `dry_run` |\n| `dataset_create` | medium | `POST /pool/dataset` | no undo (deletion out of scope); `dry_run` |\n| `snapshot_create` | medium | `POST /zfs/snapshot` | records inverse `snapshot_delete` undo descriptor; `dry_run` |\n| `snapshot_delete` | **high** | `DELETE /zfs/snapshot/id/{id}` | captures BEFORE state; IRREVERSIBLE, no undo; CLI double-confirm + `dry_run` |\n| `service_restart` | medium | `POST /service/restart` | captures prior state; no undo; refuses a name absent from `service_list`, and refuses `ssh` without `confirm=True` (out-of-band recovery path); guards also fire under `dry_run`; CLI double-confirm |\n| `undo_apply` | medium | governance store | executes a recorded inverse; itself governed; single-use; supports dry-run |\n\n## Out of scope (by design)\n\n- Pool/dataset **deletion** and any bulk-data-destroying operation\n- Running/overwriting replication or cloud-sync jobs\n- Sharing config (SMB/NFS/iSCSI share CRUD), users/groups, apps/VMs\n- Anything outside a single TrueNAS SCALE appliance\n\nWant one of these? Open an issue or PR — feedback and contributions welcome.\n\nFile v0.11.5:references/cli-reference.md\n\n# truenas-aiops CLI reference\n\n> Exercised against live TrueNAS SCALE 25.04 and 26 appliances over both the\n> REST and WebSocket transports; see docs/VERIFICATION.md for the gaps.\n\n## Setup & diagnostics\n\n```bash\ntruenas-aiops init                      # interactive onboarding wizard\ntruenas-aiops doctor [--skip-auth]      # config + secret store + connectivity (/system/info)\ntruenas-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.truenas-aiops/secrets.enc)\n\n```bash\ntruenas-aiops secret set <target> [--value <key>]   # store API key (hidden prompt if no --value)\ntruenas-aiops secret list                            # names only — values never shown\ntruenas-aiops secret rm <target>\ntruenas-aiops secret migrate                         # import legacy plaintext .env (TRUENAS_<T>_APIKEY)\ntruenas-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\ntruenas-aiops overview [--target <t>]    # pools (capacity/health), alerts by level, running services\ntruenas-aiops system [--target <t>]      # version / hostname / memory / cores / uptime\ntruenas-aiops diagnose pool-health       # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts            # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>      # health + scan + topology summary\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity              # size / allocated / free / used% per pool\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>   # e.g. tank/data\ntruenas-aiops snapshot list [--dataset <tank/data>] [--limit 200]\ntruenas-aiops disk list\ntruenas-aiops disk smart                 # S.M.A.R.T. self-test results per disk\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\ntruenas-aiops pool scrub-start <pool_name>            # (medium) start an integrity scrub\ntruenas-aiops dataset create <tank/path> [--dry-run]  # (medium) create a ZFS dataset\ntruenas-aiops snapshot create <dataset> <name>        # (medium) records inverse snapshot_delete undo\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # (high) double confirm — IRREVERSIBLE\ntruenas-aiops service restart <service> [--dry-run]   # (medium) double confirm — smb/nfs/ssh/...\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the API call that would be made, change nothing\n- Destructive commands (`snapshot delete`, `service restart`) require two confirmations\n\nFile v0.11.5:references/setup-guide.md\n\n# truenas-aiops setup & security guide\n\n> Validated against live TrueNAS SCALE 25.04 and 26 appliances; docs/VERIFICATION.md\n> records exactly what was checked.\n\n## 1. Install\n\n```bash\nuv tool install truenas-aiops\n```\n\n## 2. Create a TrueNAS API key\n\nIn the TrueNAS SCALE web UI: **Credentials → API Keys → Add**. Copy the key\n(shown once). truenas-aiops sends it as `Authorization: Bearer <key>` against the\nREST API base `https://<host>:<port>/api/v2.0`.\n\n## 3. Onboard\n\n```bash\ntruenas-aiops init\n```\n\nThe wizard collects (non-secret) connection details into\n`~/.truenas-aiops/config.yaml` and stores the API key **encrypted** into\n`~/.truenas-aiops/secrets.enc`. Example config:\n\n```yaml\ntargets:\n  - name: nas1\n    host: 10.0.0.30\n    port: 443\n    verify_ssl: false          # self-signed lab certs only\n    api_path: /api/v2.0\n```\n\n## 4. Non-interactive use (MCP server / CI / cron)\n\nExport the master password so the encrypted store can be unlocked without a\nprompt:\n\n```bash\nexport TRUENAS_AIOPS_MASTER_PASSWORD='your-master-password'\n```\n\n## Credential security\n\n- The API key is **never** written to disk in plaintext. It lives only in\n  `~/.truenas-aiops/secrets.enc`, encrypted with Fernet (AES-128-CBC + HMAC),\n  the key derived from your master password via scrypt. Only a per-store random\n  salt and the ciphertext are on disk (chmod 600); the master password itself is\n  never stored.\n- A legacy plaintext env var `TRUENAS_<TARGET_NAME_UPPER>_APIKEY` is still\n  honoured as a fallback with a deprecation warning — migrate with\n  `truenas-aiops secret migrate` (it imports then renames the old `.env`).\n- The key is held only in memory during a session and is never logged or echoed;\n  exception text and tracebacks are scrubbed of secret-shaped strings before\n  being written to the audit log.\n\n## Governance harness state\n\nState lives under `~/.truenas-aiops/` (relocate with `TRUENAS_AIOPS_HOME`):\n\n- `audit.db` — every tool call (SQLite), with its descriptive risk tier and any\n  optional approver/rationale annotations\n- `undo.db` — inverse descriptors for reversible writes (e.g. `snapshot_create`)\n- budget / runaway guard — caps cumulative tool calls and wall-time; trips on\n  tight scrub/poll loops\n\n## Verify\n\n```bash\ntruenas-aiops doctor\n```\n\n`doctor` checks the config file, the encrypted store and its permissions,\nthat an API key is present per target, and (unless `--skip-auth`) connectivity\nby hitting `/system/info`.\n\nFile v0.11.5:skill-card.md\n\n## Description:\n\nTrueNAS AIops lets agents inspect and administer TrueNAS SCALE storage through CLI and MCP tools for health checks, diagnostics, pools, datasets, snapshots, disks, alerts, services, replication, and cloud-sync tasks.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nStorage administrators, operators, and agent developers use this skill to triage and perform governed operations on TrueNAS SCALE appliances. It supports read-only diagnostics as well as audited write actions such as dataset creation, snapshot operations, pool scrub starts, service restarts, and undo application.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can perform high-impact TrueNAS storage writes and does not provide its own read-only mode or approval gate.\n\nMitigation: Install only for intended TrueNAS administration, use a least-privilege or read-only TrueNAS API key unless writes are required, and require explicit human oversight for write actions.\n\nRisk: Snapshot deletion and service restart can disrupt storage availability or remove recovery points.\n\nMitigation: Use dry-run previews, confirm current dataset, snapshot, pool, and service identifiers from live tool output, and treat these actions as requiring explicit operator approval.\n\nRisk: Long-lived exported master passwords or legacy plaintext environment keys can weaken credential handling.\n\nMitigation: Prefer the encrypted secret store, avoid shared-system exported master passwords, and migrate away from legacy plaintext environment keys.\n\n## Reference(s):\n\n- [TrueNAS AIops ClawHub page](https://clawhub.ai/zw008/skills/truenas-aiops)\n- [TrueNAS AIops homepage](https://github.com/AIops-tools/TrueNAS-AIops)\n- [Capabilities](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup and security guide](references/setup-guide.md)\n- [Agent guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown and structured tool-call results with inline shell commands and configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Responses may include TrueNAS API-derived status values, diagnostics, audit context, dry-run previews, and operator guidance.]\n\n## Skill Version(s):\n\n0.11.5 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.11.4: 7 files, 17211 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2324b), SKILL.md (16595b), _meta.json (133b)\n\nFile v0.11.4:SKILL.md\n\n---\nname: truenas-aiops\nslug: truenas-aiops\ndisplayName: \"TrueNAS AIops\"\nsummary: \"Governed TrueNAS SCALE storage ops — 25 MCP tools with audit, budget, undo guards.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/TrueNAS-AIops\ntags: [aiops, mcp, governance, truenas]\ndescription: >\n  Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks.\n  Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance.\n  Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only).\n  Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.\ninstaller:\n  kind: uv\n  package: truenas-aiops\nargument-hint: \"[pool/dataset/snapshot id or describe your TrueNAS task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"truenas-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"TRUENAS_AIOPS_CONFIG\",\"TRUENAS_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/TrueNAS-AIops\",\"emoji\":\"🗄️\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed TrueNAS SCALE storage operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.\n  All write operations are audited to a local SQLite DB under ~/.truenas-aiops/ (relocatable via TRUENAS_AIOPS_HOME).\n  Credentials: Each TrueNAS target's API key is stored ENCRYPTED in ~/.truenas-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'truenas-aiops init' to onboard, or 'truenas-aiops secret set <target>' to add one (create the key in the TrueNAS UI: Credentials → API Keys). The store is unlocked by a master password from TRUENAS_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var TRUENAS_<TARGET_NAME_UPPER>_APIKEY is still honoured as a fallback with a deprecation warning (migrate with 'truenas-aiops secret migrate'). The API key is sent as an Authorization: Bearer header at request time and held only in memory; keys are never logged or echoed.\n  Destructive operations (snapshot delete, service restart) require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + risk-tier labelling). snapshot_create records an inverse snapshot_delete undo descriptor; snapshot_delete is high-risk and irreversible (captures BEFORE state, records no undo).\n  Webhooks: none — no outbound network calls beyond the configured TrueNAS REST API endpoint.\n  SSL: verify_ssl defaults to true; disable only for self-signed lab certificates.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Routes are resolved against the appliance's own method list and were cross-checked on live 25.04 and 26 appliances; S.M.A.R.T. on failing media remains unverified (see docs/VERIFICATION.md).\n---\n\n# TrueNAS AIops\n\n> **Disclaimer**: This is a community-maintained open-source project and is **not affiliated with, endorsed by, or sponsored by iXsystems or the TrueNAS project.** \"TrueNAS\" is a trademark of its owner. Source code is publicly auditable at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops) under the MIT license.\n\nGoverned TrueNAS SCALE storage operations — **25 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.truenas-aiops/`, policy engine, token/runaway budget guard, undo-token recording, and descriptive risk tiers. The TrueNAS API key is stored **encrypted** (`~/.truenas-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`truenas_aiops.governance`) — truenas-aiops has no external skill-family dependency. **Verification**: coverage focuses on common TrueNAS operations and is not exhaustive, but it is no longer mock-only — reads, governed writes with audit + undo, the WebSocket transport, degraded-pool RCA, replication and cloud-sync have all been exercised against live TrueNAS SCALE 25.04 and 26 appliances. `docs/VERIFICATION.md` records exactly what was checked and what is still open.\n\n## What This Skill Does\n\n| Category | Tools | Count | Read or Write |\n|----------|-------|:-----:|:-------------:|\n| **Overview / System** | health overview, system info | 2 | 2 read |\n| **Diagnostics / RCA** | pool health RCA, alert & capacity RCA | 2 | 2 read |\n| **Pools** | list, get, status, scrub status, capacity | 5 | 5 read |\n| | scrub start | 1 | 1 write (medium) |\n| **Datasets** | list, get | 2 | 2 read |\n| | create | 1 | 1 write (medium) |\n| **Snapshots** | list | 1 | 1 read |\n| | create (medium), delete (high) | 2 | 2 write |\n| **Disks** | list, S.M.A.R.T. results | 2 | 2 read |\n| **Alerts** | list | 1 | 1 read |\n| **Services** | list | 1 | 1 read |\n| | restart | 1 | 1 write (medium) |\n| **Replication** | replication tasks, cloud-sync tasks | 2 | 2 read |\n\n## Quick Install\n\n```bash\nuv tool install truenas-aiops\ntruenas-aiops init       # interactive wizard: connection + encrypted API key\ntruenas-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/truenas-aiops\nopenclaw skills info truenas-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a TrueNAS appliance (`overview`): pool capacity/health, alerts, running services\n- Root-cause a degraded/full pool (`diagnose pool-health`) or a wall of alerts (`diagnose alerts`) — worst-first findings that cite the measured number\n- List/inspect ZFS pools, datasets, and snapshots\n- Create a snapshot before a risky change; start a pool scrub\n- Check disk health and S.M.A.R.T. self-test results\n- List and restart system services (smb/nfs/ssh)\n- Inspect replication and cloud-sync tasks\n\n**Do NOT use when** the target is not a TrueNAS SCALE appliance — other NAS/storage or backup products, hypervisor VM lifecycle, Kubernetes/containers, and network devices are out of scope for this skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| TrueNAS pools / datasets / snapshots / ZFS health | **truenas-aiops** (this skill) |\n| Backup software job/restore operations | a backup-software ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### Root-cause a degraded or full pool (start here)\n\n1. `truenas-aiops diagnose pool-health` → worst-first findings: bad ZFS state (DEGRADED/FAULTED/OFFLINE), non-zero read/write/checksum/scan error counters, and pools over 80%/90% capacity — each citing the measured number\n2. `truenas-aiops pool status <pool_id>` → inspect the topology / scan detail the finding cited\n3. `truenas-aiops pool scrub-start <pool_name>` → kick an integrity scrub (governed, medium risk); poll with `pool scrub-status`\n4. `truenas-aiops diagnose alerts` → cross-check active alerts by level and any datasets nearing their quota/available ceiling\n\n### Snapshot a dataset before a change, then roll back if needed\n\n1. `truenas-aiops dataset list` → confirm the dataset id (e.g. `tank/data`)\n2. `truenas-aiops snapshot create tank/data pre-change` → records an inverse `snapshot_delete` undo descriptor\n3. Make your change; if it went wrong, the snapshot is your recovery point\n4. `truenas-aiops snapshot delete tank/data@pre-change --dry-run` → preview; then without `--dry-run` (double confirm) — IRREVERSIBLE, captures BEFORE state, no undo\n\n### Scrub a pool and follow it\n\n1. `truenas-aiops pool list` → find the pool name and health\n2. `truenas-aiops pool scrub-start tank` → starts the integrity scrub\n3. `truenas-aiops pool scrub-status <pool_id>` → check `state` / `percentage`; do not re-issue (the runaway budget guard backs a tight poll loop)\n\n## Usage Mode\n\n| Scenario | Recommended | Why |\n|----------|:-----------:|-----|\n| Local/small models | **CLI** | fewer tokens than MCP |\n| Cloud models (Claude, GPT) | Either | MCP gives structured JSON I/O |\n| Automated pipelines | **MCP** | type-safe parameters, audited |\n\n## MCP Tools (25 — 19 read, 6 write)\n\n| Category | Tools | R/W |\n|----------|-------|:---:|\n| Overview / System | `overview`, `system_info` | Read |\n| Diagnostics / RCA | `pool_health_rca`, `alert_and_capacity_rca` | Read |\n| Pools | `pool_list`, `pool_get`, `pool_status`, `scrub_status`, `pool_capacity` | Read |\n| | `pool_scrub_start` | Write |\n| Datasets | `dataset_list`, `dataset_get` | Read |\n| | `dataset_create` | Write |\n| Snapshots | `snapshot_list` | Read |\n| | `snapshot_create`, `snapshot_delete` | Write |\n| Disks | `disk_list`, `smart_test_results` | Read |\n| Alerts | `alert_list` | Read |\n| Services | `service_list` | Read |\n| | `service_restart` | Write |\n| Replication | `replication_list`, `cloudsync_list` | Read |\n| Undo (governance) | `undo_list` | Read |\n| | `undo_apply` | Write |\n\n**Harness features that light up**: `snapshot_create` passes an `undo=` lambda so the harness records an inverse `snapshot_delete` descriptor (with `_undo_id`) to the undo store. `snapshot_delete` is tagged `risk_level=high`, captures the snapshot's BEFORE state, and declares no undo (it is irreversible). `pool_scrub_start`, `dataset_create`, and `service_restart` are `medium` risk and capture prior state where relevant. All 25 tools are audit-logged under `~/.truenas-aiops/` and pass through the budget/runaway guard, with a descriptive risk-tier label on each audit row. Start any triage with `overview`.\n\n## CLI Quick Reference\n\n```bash\ntruenas-aiops init                                    # onboarding wizard (encrypted API key)\ntruenas-aiops overview [--target <t>]                 # health summary\ntruenas-aiops system [--target <t>]                   # version / hostname / memory / uptime\ntruenas-aiops diagnose pool-health                    # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts                         # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity                           # size / allocated / free / used%\ntruenas-aiops pool scrub-start <pool_name>\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>                # e.g. tank/data\ntruenas-aiops dataset create <tank/path> [--dry-run]\ntruenas-aiops snapshot list [--dataset tank/data] [--limit 200]\ntruenas-aiops snapshot create <dataset> <name>\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # double confirm, IRREVERSIBLE\ntruenas-aiops disk list\ntruenas-aiops disk smart                              # S.M.A.R.T. self-test results\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops service restart <service> [--dry-run]   # double confirm (smb/nfs/ssh)\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\ntruenas-aiops secret set <target>                     # store API key encrypted\ntruenas-aiops secret list                             # names only\ntruenas-aiops secret migrate                          # import legacy plaintext .env\ntruenas-aiops secret rotate-password\ntruenas-aiops doctor\ntruenas-aiops mcp                                     # start MCP server (stdio)\n```\n\nSee `references/cli-reference.md` for the full command list, and\n`references/agent-guardrails.md` when driving these tools with a smaller /\nlocal model (enforced guardrails, ready-to-paste system prompt).\n\n## Troubleshooting\n\n### \"Config file not found\"\nRun `truenas-aiops init` to set up your first target (writes `~/.truenas-aiops/config.yaml` and stores the API key encrypted).\n\n### \"No API key for target '<name>'\"\nAdd it to the encrypted store: `truenas-aiops secret set <name>` (prompts hidden), or run `truenas-aiops init`. Create the key in the TrueNAS UI under Credentials → API Keys. For non-interactive use (MCP/CI), also export `TRUENAS_AIOPS_MASTER_PASSWORD` so the store can be unlocked without a prompt.\n\n### \"Master password not set\" / \"Wrong master password\"\nThe encrypted store `~/.truenas-aiops/secrets.enc` is unlocked by `TRUENAS_AIOPS_MASTER_PASSWORD` (or an interactive prompt). If you forgot it, delete `secrets.enc` and re-run `truenas-aiops init`. Rotate it with `truenas-aiops secret rotate-password`.\n\n### \"Authentication/authorization failed (401/403)\"\nThe API key is wrong or revoked, or the account lacks permission. Regenerate the key in the TrueNAS UI (Credentials → API Keys) and update it: `truenas-aiops secret set <name>`.\n\n### \"Could not reach TrueNAS … check the host/port\"\nConfirm the TrueNAS web/REST endpoint is reachable on the configured port (default 443) and `api_path` is `/api/v2.0`. For self-signed certificates set `verify_ssl: false` on the target (lab only).\n\n### \"Resource not found (404)\"\nThe pool/dataset/snapshot id is stale. List the parent collection first (`pool list`, `dataset list`, `snapshot list`) to get a current id.\n\n## Audit & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (scope the TrueNAS API key to a\nlimited-privilege account and writes then fail at the appliance). There is no\nread-only switch, policy file, or approval gate.\n\n- API key stored **encrypted** in `~/.truenas-aiops/secrets.enc` (Fernet/AES-128 + scrypt key derivation; chmod 600) — never plaintext on disk; the master password is never stored, only a per-store salt + ciphertext.\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.truenas-aiops/audit.db` (relocatable via `TRUENAS_AIOPS_HOME`): params (secrets redacted), result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `TRUENAS_AUDIT_APPROVED_BY` / `TRUENAS_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: cumulative tool calls and wall-time are capped, and a tight scrub/poll loop trips a circuit breaker.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; CLI writes execute through the same governed tools, so they are audited + undo-recorded.\n- Reversible writes capture the real fetched before-state and record an inverse descriptor (e.g. `snapshot_create` → `snapshot_delete`) that replays against the tool's own signature.\n\nThe harness is bundled in the package — no external dependency, no manual setup. See `references/setup-guide.md` for security details.\n\n## Contributing & feature requests\n\nCoverage is intentionally focused, and what has actually been verified against live appliances is recorded in `docs/VERIFICATION.md`. **Missing a capability you need, or hit an endpoint that needs fixing for your TrueNAS version?** Open an issue or pull request at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues) — feature requests, contributions, and comments are all welcome.\n\n## License\n\nMIT — [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops)\n\nFile v0.11.4:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"truenas-aiops\",\n  \"version\": \"0.11.4\",\n  \"publishedAt\": 1789535862506\n}\n\nFile v0.11.4:references/agent-guardrails.md\n\n# Agent guardrails — running truenas-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Scope the TrueNAS API key to a\n  limited-privilege account (the key inherits its user's permissions). A write\n  then fails at the appliance, which is the only place the permission actually\n  lives — a revoked permission cannot be argued around by a model, but a\n  skill-side flag can.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Don't invent a value when a field is missing\" | A field the TrueNAS middleware did not return comes back as `null`, never as `\"\"`. Absent and empty are distinguishable in the payload — a disk with no `serial`, a dataset with no `mountpoint`, a replication task with no `state` all report `null`. |\n| \"Tell me if the output was cut off\" | `snapshot_list` and `undo_list` return `{\"snapshots\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured, not guessed from a length coincidence. This matters most for snapshots: a periodic snapshot task retaining hourly/daily/weekly across a few datasets produces thousands of rows. |\n| \"Preserve the ordering / tell me what's most urgent\" | `pool_health_rca` and `alert_and_capacity_rca` findings carry an explicit 1-based `rank`, worst-first. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `snapshot delete` and `service restart` at the CLI require a `--dry-run`-able preview plus double confirmation. `snapshot_delete` captures the BEFORE state for the audit record. |\n| \"Log what you did\" | Every governed call is audited to `~/.truenas-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. `snapshot_create` additionally records a replayable inverse undo token. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n| \"Don't paraphrase the pool status\" | Pool `status` and `healthy` are passed through verbatim from ZFS — the ops layer never normalises `HEALTHY` / `DEGRADED` / `FAULTED` / `OFFLINE`. Only the model can break that; see the prompt below. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a TrueNAS SCALE storage appliance through the truenas-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current TrueNAS appliance, you MUST\n  call a tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit instead of treating\n  the partial result as complete.\n- A null field means the middleware did not return that value. Report it as\n  \"not available\" — never infer it.\n- Report ZFS status strings exactly as returned: HEALTHY, DEGRADED, FAULTED,\n  OFFLINE, UNAVAIL, REMOVED. Do not paraphrase \"DEGRADED\" as \"having issues\",\n  and do not translate or prettify alert levels or IDs.\n- When an RCA result has findings, work in \"rank\" order and cite the measured\n  number in each finding's \"detail\" (used-percent, error counters, alert level).\n\nIDENTIFIERS\n- A pool name (\"tank\") is not a dataset path (\"tank/data/vm\") and neither is a\n  snapshot id (\"tank/data@auto-2026-07-18\"). A snapshot id is always\n  <dataset>@<snapshot-name>. Do not construct one by guessing; take it from\n  snapshot_list.\n- A disk device name (\"sda\") is not a disk serial and is not stable across\n  reboots or controller changes. Quote both when identifying a disk.\n- Service names are the TrueNAS middleware names (\"smb\", \"nfs\", \"ssh\"), not\n  systemd unit names.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert a capacity, redundancy, or performance problem unless a tool\n  result supports it.\n- Do not add generic advice that does not follow from the tool output.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — snapshot deletion is irreversible and\ntakes any dependent clones with it:\n\n```bash\n# e.g. connect with an API key for a limited-privilege TrueNAS account that\n# lacks write access. Then:\ntruenas-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport TRUENAS_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport TRUENAS_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\n\n## TrueNAS-specific notes worth knowing\n\n- **A dataset path is not a pool name.** `tank` is a pool; `tank/data/vm` is a\n  dataset inside it. `pool_get`/`pool_status` take a pool id; `dataset_get`\n  takes the full dataset path. Passing one where the other is expected returns a\n  404 from the middleware, not a helpful error.\n- **Snapshot deletion is irreversible and destroys dependent clones.** ZFS\n  clones are backed by their origin snapshot; deleting\n  `tank/data@auto-2026-07-18` takes any clone promoted from it with it. That is\n  why `snapshot_delete` is `high` risk, declares no undo, and only captures the\n  BEFORE state for the audit record. There is no \"restore from the recycle bin\".\n- **Report pool status verbatim.** `HEALTHY` and `DEGRADED` are ZFS states with\n  precise meanings — `DEGRADED` means redundancy is lost but the pool is still\n  serving I/O, which is a very different operational posture from `FAULTED`.\n  Paraphrasing loses the distinction an operator acts on.\n- **A scrub is not a repair.** `pool_scrub_start` kicks an integrity check; it\n  will surface checksum errors and repair what redundancy allows, but it does\n  not replace a failing disk. It is also long-running — poll `scrub_status`,\n  never re-issue.\n- **`healthy: false` with status `ONLINE` is real.** ZFS reports it after recent\n  errors or an incomplete resilver. `pool_health_rca` flags it as a warning\n  rather than swallowing it.\n- **Capacity thresholds are about ZFS, not disk space etiquette.** ZFS is\n  copy-on-write; above roughly 80% it slows and above 90% it fragments sharply.\n  The RCA thresholds (`CAP_WARN_PCT` 80, `CAP_CRIT_PCT` 90) exist for that\n  reason and are cited in every capacity finding.\n- **Dataset usage is measured against a quota when one is set**, otherwise\n  against `used + available` headroom. The finding text says which.\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer `overview` and the two RCA\n  tools (`pool_health_rca`, `alert_and_capacity_rca`) — they do the multi-step\n  correlation inside one call, so the model does not have to chain reads and\n  keep pool/dataset ids straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions; filter `snapshot_list` to one dataset and use `limit` deliberately\n  rather than pulling every snapshot on the appliance.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.4:references/capabilities.md\n\n# truenas-aiops capabilities\n\n> 25 MCP tools (19 read, 6 write). Routes are resolved against the appliance's\n> own method list and were cross-checked on live TrueNAS SCALE 25.04 and 26\n> appliances; see docs/VERIFICATION.md for what remains unverified.\n\n## Read tools (19)\n\n| Tool | REST (modelled) | Returns |\n|------|----------------|---------|\n| `overview` | fan-out | pools (capacity/health), alerts by level, running services |\n| `system_info` | `GET /system/info` | version, hostname, memory, cores, uptime |\n| `pool_health_rca` | `GET /pool` | worst-first findings: bad ZFS state, read/write/checksum/scan error counts, capacity over 80%/90% |\n| `alert_and_capacity_rca` | `POST /alert/list` + `GET /pool/dataset` | worst-first findings: active alerts by level + datasets near quota/available ceiling |\n| `pool_list` | `GET /pool` | id, name, status, healthy, size/allocated/free |\n| `pool_get` | `GET /pool/id/{id}` | single pool detail |\n| `pool_status` | `GET /pool/id/{id}` | health + scan + topology summary |\n| `scrub_status` | `GET /pool/id/{id}` | scrub function/state/percentage |\n| `pool_capacity` | `GET /pool` | size/allocated/free + used% per pool |\n| `dataset_list` | `GET /pool/dataset` | id, name, type, pool, used/available |\n| `dataset_get` | `GET /pool/dataset/id/{id}` | single dataset detail |\n| `snapshot_list` | `GET /zfs/snapshot` | `{snapshots, returned, limit, truncated}` — id, dataset, name, used (opt. filter by dataset; default limit 200) |\n| `disk_list` | `GET /disk` | name, serial, model, size, pool |\n| `smart_test_results` | `GET /smart/test/results` | latest S.M.A.R.T. self-test per disk |\n| `alert_list` | `POST /alert/list` | level, message, class, dismissed |\n| `service_list` | `GET /service` | name, state (RUNNING/STOPPED), enable |\n| `replication_list` | `GET /replication` | name, direction, transport, state (PENDING/RUNNING/FINISHED/ERROR, never absent), error, lastSnapshot, lastRun |\n| `cloudsync_list` | `GET /cloudsync` | description, direction, path, state (the last run's job state; null until it runs) |\n| `undo_list` | governance store | recorded reversible writes / not-yet-applied undo tokens |\n\n## Write tools (6)\n\n| Tool | Risk | REST (modelled) | Undo / safety |\n|------|------|----------------|---------------|\n| `pool_scrub_start` | medium | `POST /pool/scrub/run` | captures prior scan state; no undo (non-destructive); `dry_run` |\n| `dataset_create` | medium | `POST /pool/dataset` | no undo (deletion out of scope); `dry_run` |\n| `snapshot_create` | medium | `POST /zfs/snapshot` | records inverse `snapshot_delete` undo descriptor; `dry_run` |\n| `snapshot_delete` | **high** | `DELETE /zfs/snapshot/id/{id}` | captures BEFORE state; IRREVERSIBLE, no undo; CLI double-confirm + `dry_run` |\n| `service_restart` | medium | `POST /service/restart` | captures prior state; no undo; refuses a name absent from `service_list`, and refuses `ssh` without `confirm=True` (out-of-band recovery path); guards also fire under `dry_run`; CLI double-confirm |\n| `undo_apply` | medium | governance store | executes a recorded inverse; itself governed; single-use; supports dry-run |\n\n## Out of scope (by design)\n\n- Pool/dataset **deletion** and any bulk-data-destroying operation\n- Running/overwriting replication or cloud-sync jobs\n- Sharing config (SMB/NFS/iSCSI share CRUD), users/groups, apps/VMs\n- Anything outside a single TrueNAS SCALE appliance\n\nWant one of these? Open an issue or PR — feedback and contributions welcome.\n\nFile v0.11.4:references/cli-reference.md\n\n# truenas-aiops CLI reference\n\n> Exercised against live TrueNAS SCALE 25.04 and 26 appliances over both the\n> REST and WebSocket transports; see docs/VERIFICATION.md for the gaps.\n\n## Setup & diagnostics\n\n```bash\ntruenas-aiops init                      # interactive onboarding wizard\ntruenas-aiops doctor [--skip-auth]      # config + secret store + connectivity (/system/info)\ntruenas-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.truenas-aiops/secrets.enc)\n\n```bash\ntruenas-aiops secret set <target> [--value <key>]   # store API key (hidden prompt if no --value)\ntruenas-aiops secret list                            # names only — values never shown\ntruenas-aiops secret rm <target>\ntruenas-aiops secret migrate                         # import legacy plaintext .env (TRUENAS_<T>_APIKEY)\ntruenas-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\ntruenas-aiops overview [--target <t>]    # pools (capacity/health), alerts by level, running services\ntruenas-aiops system [--target <t>]      # version / hostname / memory / cores / uptime\ntruenas-aiops diagnose pool-health       # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts            # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>      # health + scan + topology summary\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity              # size / allocated / free / used% per pool\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>   # e.g. tank/data\ntruenas-aiops snapshot list [--dataset <tank/data>] [--limit 200]\ntruenas-aiops disk list\ntruenas-aiops disk smart                 # S.M.A.R.T. self-test results per disk\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\ntruenas-aiops pool scrub-start <pool_name>            # (medium) start an integrity scrub\ntruenas-aiops dataset create <tank/path> [--dry-run]  # (medium) create a ZFS dataset\ntruenas-aiops snapshot create <dataset> <name>        # (medium) records inverse snapshot_delete undo\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # (high) double confirm — IRREVERSIBLE\ntruenas-aiops service restart <service> [--dry-run]   # (medium) double confirm — smb/nfs/ssh/...\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the API call that would be made, change nothing\n- Destructive commands (`snapshot delete`, `service restart`) require two confirmations\n\nFile v0.11.4:references/setup-guide.md\n\n# truenas-aiops setup & security guide\n\n> Validated against live TrueNAS SCALE 25.04 and 26 appliances; docs/VERIFICATION.md\n> records exactly what was checked.\n\n## 1. Install\n\n```bash\nuv tool install truenas-aiops\n```\n\n## 2. Create a TrueNAS API key\n\nIn the TrueNAS SCALE web UI: **Credentials → API Keys → Add**. Copy the key\n(shown once). truenas-aiops sends it as `Authorization: Bearer <key>` against the\nREST API base `https://<host>:<port>/api/v2.0`.\n\n## 3. Onboard\n\n```bash\ntruenas-aiops init\n```\n\nThe wizard collects (non-secret) connection details into\n`~/.truenas-aiops/config.yaml` and stores the API key **encrypted** into\n`~/.truenas-aiops/secrets.enc`. Example config:\n\n```yaml\ntargets:\n  - name: nas1\n    host: 10.0.0.30\n    port: 443\n    verify_ssl: false          # self-signed lab certs only\n    api_path: /api/v2.0\n```\n\n## 4. Non-interactive use (MCP server / CI / cron)\n\nExport the master password so the encrypted store can be unlocked without a\nprompt:\n\n```bash\nexport TRUENAS_AIOPS_MASTER_PASSWORD='your-master-password'\n```\n\n## Credential security\n\n- The API key is **never** written to disk in plaintext. It lives only in\n  `~/.truenas-aiops/secrets.enc`, encrypted with Fernet (AES-128-CBC + HMAC),\n  the key derived from your master password via scrypt. Only a per-store random\n  salt and the ciphertext are on disk (chmod 600); the master password itself is\n  never stored.\n- A legacy plaintext env var `TRUENAS_<TARGET_NAME_UPPER>_APIKEY` is still\n  honoured as a fallback with a deprecation warning — migrate with\n  `truenas-aiops secret migrate` (it imports then renames the old `.env`).\n- The key is held only in memory during a session and is never logged or echoed;\n  exception text and tracebacks are scrubbed of secret-shaped strings before\n  being written to the audit log.\n\n## Governance harness state\n\nState lives under `~/.truenas-aiops/` (relocate with `TRUENAS_AIOPS_HOME`):\n\n- `audit.db` — every tool call (SQLite), with its descriptive risk tier and any\n  optional approver/rationale annotations\n- `undo.db` — inverse descriptors for reversible writes (e.g. `snapshot_create`)\n- budget / runaway guard — caps cumulative tool calls and wall-time; trips on\n  tight scrub/poll loops\n\n## Verify\n\n```bash\ntruenas-aiops doctor\n```\n\n`doctor` checks the config file, the encrypted store and its permissions,\nthat an API key is present per target, and (unless `--skip-auth`) connectivity\nby hitting `/system/info`.\n\nFile v0.11.4:skill-card.md\n\n## Description:\n\ntruenas-aiops helps agents operate TrueNAS SCALE storage by triaging appliance health, inspecting pools, datasets, snapshots, disks, alerts, services, and replication tasks, and running governed storage operations through CLI or MCP tools.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers, storage operators, and operations agents use this skill to inspect and manage TrueNAS SCALE appliances, including health checks, ZFS pool and dataset diagnostics, snapshots, service restarts, and replication or cloud-sync inspection.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can expose high-impact TrueNAS storage write actions without a built-in read-only or approval gate.\n\nMitigation: Use a narrowly scoped or read-only TrueNAS API account by default and avoid exposing write tools to unsupervised agents.\n\nRisk: The skill requires credentials for a TrueNAS SCALE appliance.\n\nMitigation: Keep the master password and legacy API-key environment variables out of shared shells, logs, and CI output, and review or pin the external package before trusting it with credentials.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/zw008/skills/truenas-aiops)\n- [Project homepage](https://github.com/AIops-tools/TrueNAS-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup and security guide](references/setup-guide.md)\n- [Agent guardrails](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown with inline shell commands and structured tool results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May call CLI or MCP tools that return appliance status, diagnostics, audit information, and governed write results.]\n\n## Skill Version(s):\n\n0.11.4 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.11.3: 7 files, 17503 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2919b), SKILL.md (16595b), _meta.json (133b)\n\nFile v0.11.3:SKILL.md\n\n---\nname: truenas-aiops\nslug: truenas-aiops\ndisplayName: \"TrueNAS AIops\"\nsummary: \"Governed TrueNAS SCALE storage ops — 25 MCP tools with audit, budget, undo guards.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/TrueNAS-AIops\ntags: [aiops, mcp, governance, truenas]\ndescription: >\n  Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks.\n  Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance.\n  Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only).\n  Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.\ninstaller:\n  kind: uv\n  package: truenas-aiops\nargument-hint: \"[pool/dataset/snapshot id or describe your TrueNAS task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"truenas-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"TRUENAS_AIOPS_CONFIG\",\"TRUENAS_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/TrueNAS-AIops\",\"emoji\":\"🗄️\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed TrueNAS SCALE storage operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.\n  All write operations are audited to a local SQLite DB under ~/.truenas-aiops/ (relocatable via TRUENAS_AIOPS_HOME).\n  Credentials: Each TrueNAS target's API key is stored ENCRYPTED in ~/.truenas-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'truenas-aiops init' to onboard, or 'truenas-aiops secret set <target>' to add one (create the key in the TrueNAS UI: Credentials → API Keys). The store is unlocked by a master password from TRUENAS_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var TRUENAS_<TARGET_NAME_UPPER>_APIKEY is still honoured as a fallback with a deprecation warning (migrate with 'truenas-aiops secret migrate'). The API key is sent as an Authorization: Bearer header at request time and held only in memory; keys are never logged or echoed.\n  Destructive operations (snapshot delete, service restart) require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + risk-tier labelling). snapshot_create records an inverse snapshot_delete undo descriptor; snapshot_delete is high-risk and irreversible (captures BEFORE state, records no undo).\n  Webhooks: none — no outbound network calls beyond the configured TrueNAS REST API endpoint.\n  SSL: verify_ssl defaults to true; disable only for self-signed lab certificates.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Routes are resolved against the appliance's own method list and were cross-checked on live 25.04 and 26 appliances; S.M.A.R.T. on failing media remains unverified (see docs/VERIFICATION.md).\n---\n\n# TrueNAS AIops\n\n> **Disclaimer**: This is a community-maintained open-source project and is **not affiliated with, endorsed by, or sponsored by iXsystems or the TrueNAS project.** \"TrueNAS\" is a trademark of its owner. Source code is publicly auditable at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops) under the MIT license.\n\nGoverned TrueNAS SCALE storage operations — **25 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.truenas-aiops/`, policy engine, token/runaway budget guard, undo-token recording, and descriptive risk tiers. The TrueNAS API key is stored **encrypted** (`~/.truenas-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`truenas_aiops.governance`) — truenas-aiops has no external skill-family dependency. **Verification**: coverage focuses on common TrueNAS operations and is not exhaustive, but it is no longer mock-only — reads, governed writes with audit + undo, the WebSocket transport, degraded-pool RCA, replication and cloud-sync have all been exercised against live TrueNAS SCALE 25.04 and 26 appliances. `docs/VERIFICATION.md` records exactly what was checked and what is still open.\n\n## What This Skill Does\n\n| Category | Tools | Count | Read or Write |\n|----------|-------|:-----:|:-------------:|\n| **Overview / System** | health overview, system info | 2 | 2 read |\n| **Diagnostics / RCA** | pool health RCA, alert & capacity RCA | 2 | 2 read |\n| **Pools** | list, get, status, scrub status, capacity | 5 | 5 read |\n| | scrub start | 1 | 1 write (medium) |\n| **Datasets** | list, get | 2 | 2 read |\n| | create | 1 | 1 write (medium) |\n| **Snapshots** | list | 1 | 1 read |\n| | create (medium), delete (high) | 2 | 2 write |\n| **Disks** | list, S.M.A.R.T. results | 2 | 2 read |\n| **Alerts** | list | 1 | 1 read |\n| **Services** | list | 1 | 1 read |\n| | restart | 1 | 1 write (medium) |\n| **Replication** | replication tasks, cloud-sync tasks | 2 | 2 read |\n\n## Quick Install\n\n```bash\nuv tool install truenas-aiops\ntruenas-aiops init       # interactive wizard: connection + encrypted API key\ntruenas-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/truenas-aiops\nopenclaw skills info truenas-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a TrueNAS appliance (`overview`): pool capacity/health, alerts, running services\n- Root-cause a degraded/full pool (`diagnose pool-health`) or a wall of alerts (`diagnose alerts`) — worst-first findings that cite the measured number\n- List/inspect ZFS pools, datasets, and snapshots\n- Create a snapshot before a risky change; start a pool scrub\n- Check disk health and S.M.A.R.T. self-test results\n- List and restart system services (smb/nfs/ssh)\n- Inspect replication and cloud-sync tasks\n\n**Do NOT use when** the target is not a TrueNAS SCALE appliance — other NAS/storage or backup products, hypervisor VM lifecycle, Kubernetes/containers, and network devices are out of scope for this skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| TrueNAS pools / datasets / snapshots / ZFS health | **truenas-aiops** (this skill) |\n| Backup software job/restore operations | a backup-software ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### Root-cause a degraded or full pool (start here)\n\n1. `truenas-aiops diagnose pool-health` → worst-first findings: bad ZFS state (DEGRADED/FAULTED/OFFLINE), non-zero read/write/checksum/scan error counters, and pools over 80%/90% capacity — each citing the measured number\n2. `truenas-aiops pool status <pool_id>` → inspect the topology / scan detail the finding cited\n3. `truenas-aiops pool scrub-start <pool_name>` → kick an integrity scrub (governed, medium risk); poll with `pool scrub-status`\n4. `truenas-aiops diagnose alerts` → cross-check active alerts by level and any datasets nearing their quota/available ceiling\n\n### Snapshot a dataset before a change, then roll back if needed\n\n1. `truenas-aiops dataset list` → confirm the dataset id (e.g. `tank/data`)\n2. `truenas-aiops snapshot create tank/data pre-change` → records an inverse `snapshot_delete` undo descriptor\n3. Make your change; if it went wrong, the snapshot is your recovery point\n4. `truenas-aiops snapshot delete tank/data@pre-change --dry-run` → preview; then without `--dry-run` (double confirm) — IRREVERSIBLE, captures BEFORE state, no undo\n\n### Scrub a pool and follow it\n\n1. `truenas-aiops pool list` → find the pool name and health\n2. `truenas-aiops pool scrub-start tank` → starts the integrity scrub\n3. `truenas-aiops pool scrub-status <pool_id>` → check `state` / `percentage`; do not re-issue (the runaway budget guard backs a tight poll loop)\n\n## Usage Mode\n\n| Scenario | Recommended | Why |\n|----------|:-----------:|-----|\n| Local/small models | **CLI** | fewer tokens than MCP |\n| Cloud models (Claude, GPT) | Either | MCP gives structured JSON I/O |\n| Automated pipelines | **MCP** | type-safe parameters, audited |\n\n## MCP Tools (25 — 19 read, 6 write)\n\n| Category | Tools | R/W |\n|----------|-------|:---:|\n| Overview / System | `overview`, `system_info` | Read |\n| Diagnostics / RCA | `pool_health_rca`, `alert_and_capacity_rca` | Read |\n| Pools | `pool_list`, `pool_get`, `pool_status`, `scrub_status`, `pool_capacity` | Read |\n| | `pool_scrub_start` | Write |\n| Datasets | `dataset_list`, `dataset_get` | Read |\n| | `dataset_create` | Write |\n| Snapshots | `snapshot_list` | Read |\n| | `snapshot_create`, `snapshot_delete` | Write |\n| Disks | `disk_list`, `smart_test_results` | Read |\n| Alerts | `alert_list` | Read |\n| Services | `service_list` | Read |\n| | `service_restart` | Write |\n| Replication | `replication_list`, `cloudsync_list` | Read |\n| Undo (governance) | `undo_list` | Read |\n| | `undo_apply` | Write |\n\n**Harness features that light up**: `snapshot_create` passes an `undo=` lambda so the harness records an inverse `snapshot_delete` descriptor (with `_undo_id`) to the undo store. `snapshot_delete` is tagged `risk_level=high`, captures the snapshot's BEFORE state, and declares no undo (it is irreversible). `pool_scrub_start`, `dataset_create`, and `service_restart` are `medium` risk and capture prior state where relevant. All 25 tools are audit-logged under `~/.truenas-aiops/` and pass through the budget/runaway guard, with a descriptive risk-tier label on each audit row. Start any triage with `overview`.\n\n## CLI Quick Reference\n\n```bash\ntruenas-aiops init                                    # onboarding wizard (encrypted API key)\ntruenas-aiops overview [--target <t>]                 # health summary\ntruenas-aiops system [--target <t>]                   # version / hostname / memory / uptime\ntruenas-aiops diagnose pool-health                    # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts                         # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity                           # size / allocated / free / used%\ntruenas-aiops pool scrub-start <pool_name>\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>                # e.g. tank/data\ntruenas-aiops dataset create <tank/path> [--dry-run]\ntruenas-aiops snapshot list [--dataset tank/data] [--limit 200]\ntruenas-aiops snapshot create <dataset> <name>\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # double confirm, IRREVERSIBLE\ntruenas-aiops disk list\ntruenas-aiops disk smart                              # S.M.A.R.T. self-test results\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops service restart <service> [--dry-run]   # double confirm (smb/nfs/ssh)\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\ntruenas-aiops secret set <target>                     # store API key encrypted\ntruenas-aiops secret list                             # names only\ntruenas-aiops secret migrate                          # import legacy plaintext .env\ntruenas-aiops secret rotate-password\ntruenas-aiops doctor\ntruenas-aiops mcp                                     # start MCP server (stdio)\n```\n\nSee `references/cli-reference.md` for the full command list, and\n`references/agent-guardrails.md` when driving these tools with a smaller /\nlocal model (enforced guardrails, ready-to-paste system prompt).\n\n## Troubleshooting\n\n### \"Config file not found\"\nRun `truenas-aiops init` to set up your first target (writes `~/.truenas-aiops/config.yaml` and stores the API key encrypted).\n\n### \"No API key for target '<name>'\"\nAdd it to the encrypted store: `truenas-aiops secret set <name>` (prompts hidden), or run `truenas-aiops init`. Create the key in the TrueNAS UI under Credentials → API Keys. For non-interactive use (MCP/CI), also export `TRUENAS_AIOPS_MASTER_PASSWORD` so the store can be unlocked without a prompt.\n\n### \"Master password not set\" / \"Wrong master password\"\nThe encrypted store `~/.truenas-aiops/secrets.enc` is unlocked by `TRUENAS_AIOPS_MASTER_PASSWORD` (or an interactive prompt). If you forgot it, delete `secrets.enc` and re-run `truenas-aiops init`. Rotate it with `truenas-aiops secret rotate-password`.\n\n### \"Authentication/authorization failed (401/403)\"\nThe API key is wrong or revoked, or the account lacks permission. Regenerate the key in the TrueNAS UI (Credentials → API Keys) and update it: `truenas-aiops secret set <name>`.\n\n### \"Could not reach TrueNAS … check the host/port\"\nConfirm the TrueNAS web/REST endpoint is reachable on the configured port (default 443) and `api_path` is `/api/v2.0`. For self-signed certificates set `verify_ssl: false` on the target (lab only).\n\n### \"Resource not found (404)\"\nThe pool/dataset/snapshot id is stale. List the parent collection first (`pool list`, `dataset list`, `snapshot list`) to get a current id.\n\n## Audit & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (scope the TrueNAS API key to a\nlimited-privilege account and writes then fail at the appliance). There is no\nread-only switch, policy file, or approval gate.\n\n- API key stored **encrypted** in `~/.truenas-aiops/secrets.enc` (Fernet/AES-128 + scrypt key derivation; chmod 600) — never plaintext on disk; the master password is never stored, only a per-store salt + ciphertext.\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.truenas-aiops/audit.db` (relocatable via `TRUENAS_AIOPS_HOME`): params (secrets redacted), result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `TRUENAS_AUDIT_APPROVED_BY` / `TRUENAS_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: cumulative tool calls and wall-time are capped, and a tight scrub/poll loop trips a circuit breaker.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; CLI writes execute through the same governed tools, so they are audited + undo-recorded.\n- Reversible writes capture the real fetched before-state and record an inverse descriptor (e.g. `snapshot_create` → `snapshot_delete`) that replays against the tool's own signature.\n\nThe harness is bundled in the package — no external dependency, no manual setup. See `references/setup-guide.md` for security details.\n\n## Contributing & feature requests\n\nCoverage is intentionally focused, and what has actually been verified against live appliances is recorded in `docs/VERIFICATION.md`. **Missing a capability you need, or hit an endpoint that needs fixing for your TrueNAS version?** Open an issue or pull request at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues) — feature requests, contributions, and comments are all welcome.\n\n## License\n\nMIT — [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops)\n\nFile v0.11.3:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"truenas-aiops\",\n  \"version\": \"0.11.3\",\n  \"publishedAt\": 1789453280367\n}\n\nFile v0.11.3:references/agent-guardrails.md\n\n# Agent guardrails — running truenas-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Scope the TrueNAS API key to a\n  limited-privilege account (the key inherits its user's permissions). A write\n  then fails at the appliance, which is the only place the permission actually\n  lives — a revoked permission cannot be argued around by a model, but a\n  skill-side flag can.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Don't invent a value when a field is missing\" | A field the TrueNAS middleware did not return comes back as `null`, never as `\"\"`. Absent and empty are distinguishable in the payload — a disk with no `serial`, a dataset with no `mountpoint`, a replication task with no `state` all report `null`. |\n| \"Tell me if the output was cut off\" | `snapshot_list` and `undo_list` return `{\"snapshots\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured, not guessed from a length coincidence. This matters most for snapshots: a periodic snapshot task retaining hourly/daily/weekly across a few datasets produces thousands of rows. |\n| \"Preserve the ordering / tell me what's most urgent\" | `pool_health_rca` and `alert_and_capacity_rca` findings carry an explicit 1-based `rank`, worst-first. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `snapshot delete` and `service restart` at the CLI require a `--dry-run`-able preview plus double confirmation. `snapshot_delete` captures the BEFORE state for the audit record. |\n| \"Log what you did\" | Every governed call is audited to `~/.truenas-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. `snapshot_create` additionally records a replayable inverse undo token. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n| \"Don't paraphrase the pool status\" | Pool `status` and `healthy` are passed through verbatim from ZFS — the ops layer never normalises `HEALTHY` / `DEGRADED` / `FAULTED` / `OFFLINE`. Only the model can break that; see the prompt below. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a TrueNAS SCALE storage appliance through the truenas-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current TrueNAS appliance, you MUST\n  call a tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit instead of treating\n  the partial result as complete.\n- A null field means the middleware did not return that value. Report it as\n  \"not available\" — never infer it.\n- Report ZFS status strings exactly as returned: HEALTHY, DEGRADED, FAULTED,\n  OFFLINE, UNAVAIL, REMOVED. Do not paraphrase \"DEGRADED\" as \"having issues\",\n  and do not translate or prettify alert levels or IDs.\n- When an RCA result has findings, work in \"rank\" order and cite the measured\n  number in each finding's \"detail\" (used-percent, error counters, alert level).\n\nIDENTIFIERS\n- A pool name (\"tank\") is not a dataset path (\"tank/data/vm\") and neither is a\n  snapshot id (\"tank/data@auto-2026-07-18\"). A snapshot id is always\n  <dataset>@<snapshot-name>. Do not construct one by guessing; take it from\n  snapshot_list.\n- A disk device name (\"sda\") is not a disk serial and is not stable across\n  reboots or controller changes. Quote both when identifying a disk.\n- Service names are the TrueNAS middleware names (\"smb\", \"nfs\", \"ssh\"), not\n  systemd unit names.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert a capacity, redundancy, or performance problem unless a tool\n  result supports it.\n- Do not add generic advice that does not follow from the tool output.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — snapshot deletion is irreversible and\ntakes any dependent clones with it:\n\n```bash\n# e.g. connect with an API key for a limited-privilege TrueNAS account that\n# lacks write access. Then:\ntruenas-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport TRUENAS_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport TRUENAS_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\n\n## TrueNAS-specific notes worth knowing\n\n- **A dataset path is not a pool name.** `tank` is a pool; `tank/data/vm` is a\n  dataset inside it. `pool_get`/`pool_status` take a pool id; `dataset_get`\n  takes the full dataset path. Passing one where the other is expected returns a\n  404 from the middleware, not a helpful error.\n- **Snapshot deletion is irreversible and destroys dependent clones.** ZFS\n  clones are backed by their origin snapshot; deleting\n  `tank/data@auto-2026-07-18` takes any clone promoted from it with it. That is\n  why `snapshot_delete` is `high` risk, declares no undo, and only captures the\n  BEFORE state for the audit record. There is no \"restore from the recycle bin\".\n- **Report pool status verbatim.** `HEALTHY` and `DEGRADED` are ZFS states with\n  precise meanings — `DEGRADED` means redundancy is lost but the pool is still\n  serving I/O, which is a very different operational posture from `FAULTED`.\n  Paraphrasing loses the distinction an operator acts on.\n- **A scrub is not a repair.** `pool_scrub_start` kicks an integrity check; it\n  will surface checksum errors and repair what redundancy allows, but it does\n  not replace a failing disk. It is also long-running — poll `scrub_status`,\n  never re-issue.\n- **`healthy: false` with status `ONLINE` is real.** ZFS reports it after recent\n  errors or an incomplete resilver. `pool_health_rca` flags it as a warning\n  rather than swallowing it.\n- **Capacity thresholds are about ZFS, not disk space etiquette.** ZFS is\n  copy-on-write; above roughly 80% it slows and above 90% it fragments sharply.\n  The RCA thresholds (`CAP_WARN_PCT` 80, `CAP_CRIT_PCT` 90) exist for that\n  reason and are cited in every capacity finding.\n- **Dataset usage is measured against a quota when one is set**, otherwise\n  against `used + available` headroom. The finding text says which.\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer `overview` and the two RCA\n  tools (`pool_health_rca`, `alert_and_capacity_rca`) — they do the multi-step\n  correlation inside one call, so the model does not have to chain reads and\n  keep pool/dataset ids straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions; filter `snapshot_list` to one dataset and use `limit` deliberately\n  rather than pulling every snapshot on the appliance.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.3:references/capabilities.md\n\n# truenas-aiops capabilities\n\n> 25 MCP tools (19 read, 6 write). Routes are resolved against the appliance's\n> own method list and were cross-checked on live TrueNAS SCALE 25.04 and 26\n> appliances; see docs/VERIFICATION.md for what remains unverified.\n\n## Read tools (19)\n\n| Tool | REST (modelled) | Returns |\n|------|----------------|---------|\n| `overview` | fan-out | pools (capacity/health), alerts by level, running services |\n| `system_info` | `GET /system/info` | version, hostname, memory, cores, uptime |\n| `pool_health_rca` | `GET /pool` | worst-first findings: bad ZFS state, read/write/checksum/scan error counts, capacity over 80%/90% |\n| `alert_and_capacity_rca` | `POST /alert/list` + `GET /pool/dataset` | worst-first findings: active alerts by level + datasets near quota/available ceiling |\n| `pool_list` | `GET /pool` | id, name, status, healthy, size/allocated/free |\n| `pool_get` | `GET /pool/id/{id}` | single pool detail |\n| `pool_status` | `GET /pool/id/{id}` | health + scan + topology summary |\n| `scrub_status` | `GET /pool/id/{id}` | scrub function/state/percentage |\n| `pool_capacity` | `GET /pool` | size/allocated/free + used% per pool |\n| `dataset_list` | `GET /pool/dataset` | id, name, type, pool, used/available |\n| `dataset_get` | `GET /pool/dataset/id/{id}` | single dataset detail |\n| `snapshot_list` | `GET /zfs/snapshot` | `{snapshots, returned, limit, truncated}` — id, dataset, name, used (opt. filter by dataset; default limit 200) |\n| `disk_list` | `GET /disk` | name, serial, model, size, pool |\n| `smart_test_results` | `GET /smart/test/results` | latest S.M.A.R.T. self-test per disk |\n| `alert_list` | `POST /alert/list` | level, message, class, dismissed |\n| `service_list` | `GET /service` | name, state (RUNNING/STOPPED), enable |\n| `replication_list` | `GET /replication` | name, direction, transport, state (PENDING/RUNNING/FINISHED/ERROR, never absent), error, lastSnapshot, lastRun |\n| `cloudsync_list` | `GET /cloudsync` | description, direction, path, state (the last run's job state; null until it runs) |\n| `undo_list` | governance store | recorded reversible writes / not-yet-applied undo tokens |\n\n## Write tools (6)\n\n| Tool | Risk | REST (modelled) | Undo / safety |\n|------|------|----------------|---------------|\n| `pool_scrub_start` | medium | `POST /pool/scrub/run` | captures prior scan state; no undo (non-destructive); `dry_run` |\n| `dataset_create` | medium | `POST /pool/dataset` | no undo (deletion out of scope); `dry_run` |\n| `snapshot_create` | medium | `POST /zfs/snapshot` | records inverse `snapshot_delete` undo descriptor; `dry_run` |\n| `snapshot_delete` | **high** | `DELETE /zfs/snapshot/id/{id}` | captures BEFORE state; IRREVERSIBLE, no undo; CLI double-confirm + `dry_run` |\n| `service_restart` | medium | `POST /service/restart` | captures prior state; no undo; refuses a name absent from `service_list`, and refuses `ssh` without `confirm=True` (out-of-band recovery path); guards also fire under `dry_run`; CLI double-confirm |\n| `undo_apply` | medium | governance store | executes a recorded inverse; itself governed; single-use; supports dry-run |\n\n## Out of scope (by design)\n\n- Pool/dataset **deletion** and any bulk-data-destroying operation\n- Running/overwriting replication or cloud-sync jobs\n- Sharing config (SMB/NFS/iSCSI share CRUD), users/groups, apps/VMs\n- Anything outside a single TrueNAS SCALE appliance\n\nWant one of these? Open an issue or PR — feedback and contributions welcome.\n\nFile v0.11.3:references/cli-reference.md\n\n# truenas-aiops CLI reference\n\n> Exercised against live TrueNAS SCALE 25.04 and 26 appliances over both the\n> REST and WebSocket transports; see docs/VERIFICATION.md for the gaps.\n\n## Setup & diagnostics\n\n```bash\ntruenas-aiops init                      # interactive onboarding wizard\ntruenas-aiops doctor [--skip-auth]      # config + secret store + connectivity (/system/info)\ntruenas-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.truenas-aiops/secrets.enc)\n\n```bash\ntruenas-aiops secret set <target> [--value <key>]   # store API key (hidden prompt if no --value)\ntruenas-aiops secret list                            # names only — values never shown\ntruenas-aiops secret rm <target>\ntruenas-aiops secret migrate                         # import legacy plaintext .env (TRUENAS_<T>_APIKEY)\ntruenas-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\ntruenas-aiops overview [--target <t>]    # pools (capacity/health), alerts by level, running services\ntruenas-aiops system [--target <t>]      # version / hostname / memory / cores / uptime\ntruenas-aiops diagnose pool-health       # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts            # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>      # health + scan + topology summary\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity              # size / allocated / free / used% per pool\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>   # e.g. tank/data\ntruenas-aiops snapshot list [--dataset <tank/data>] [--limit 200]\ntruenas-aiops disk list\ntruenas-aiops disk smart                 # S.M.A.R.T. self-test results per disk\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\ntruenas-aiops pool scrub-start <pool_name>            # (medium) start an integrity scrub\ntruenas-aiops dataset create <tank/path> [--dry-run]  # (medium) create a ZFS dataset\ntruenas-aiops snapshot create <dataset> <name>        # (medium) records inverse snapshot_delete undo\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # (high) double confirm — IRREVERSIBLE\ntruenas-aiops service restart <service> [--dry-run]   # (medium) double confirm — smb/nfs/ssh/...\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the API call that would be made, change nothing\n- Destructive commands (`snapshot delete`, `service restart`) require two confirmations\n\nFile v0.11.3:references/setup-guide.md\n\n# truenas-aiops setup & security guide\n\n> Validated against live TrueNAS SCALE 25.04 and 26 appliances; docs/VERIFICATION.md\n> records exactly what was checked.\n\n## 1. Install\n\n```bash\nuv tool install truenas-aiops\n```\n\n## 2. Create a TrueNAS API key\n\nIn the TrueNAS SCALE web UI: **Credentials → API Keys → Add**. Copy the key\n(shown once). truenas-aiops sends it as `Authorization: Bearer <key>` against the\nREST API base `https://<host>:<port>/api/v2.0`.\n\n## 3. Onboard\n\n```bash\ntruenas-aiops init\n```\n\nThe wizard collects (non-secret) connection details into\n`~/.truenas-aiops/config.yaml` and stores the API key **encrypted** into\n`~/.truenas-aiops/secrets.enc`. Example config:\n\n```yaml\ntargets:\n  - name: nas1\n    host: 10.0.0.30\n    port: 443\n    verify_ssl: false          # self-signed lab certs only\n    api_path: /api/v2.0\n```\n\n## 4. Non-interactive use (MCP server / CI / cron)\n\nExport the master password so the encrypted store can be unlocked without a\nprompt:\n\n```bash\nexport TRUENAS_AIOPS_MASTER_PASSWORD='your-master-password'\n```\n\n## Credential security\n\n- The API key is **never** written to disk in plaintext. It lives only in\n  `~/.truenas-aiops/secrets.enc`, encrypted with Fernet (AES-128-CBC + HMAC),\n  the key derived from your master password via scrypt. Only a per-store random\n  salt and the ciphertext are on disk (chmod 600); the master password itself is\n  never stored.\n- A legacy plaintext env var `TRUENAS_<TARGET_NAME_UPPER>_APIKEY` is still\n  honoured as a fallback with a deprecation warning — migrate with\n  `truenas-aiops secret migrate` (it imports then renames the old `.env`).\n- The key is held only in memory during a session and is never logged or echoed;\n  exception text and tracebacks are scrubbed of secret-shaped strings before\n  being written to the audit log.\n\n## Governance harness state\n\nState lives under `~/.truenas-aiops/` (relocate with `TRUENAS_AIOPS_HOME`):\n\n- `audit.db` — every tool call (SQLite), with its descriptive risk tier and any\n  optional approver/rationale annotations\n- `undo.db` — inverse descriptors for reversible writes (e.g. `snapshot_create`)\n- budget / runaway guard — caps cumulative tool calls and wall-time; trips on\n  tight scrub/poll loops\n\n## Verify\n\n```bash\ntruenas-aiops doctor\n```\n\n`doctor` checks the config file, the encrypted store and its permissions,\nthat an API key is present per target, and (unless `--skip-auth`) connectivity\nby hitting `/system/info`.\n\nFile v0.11.3:skill-card.md\n\n## Description:\n\ntruenas-aiops helps agents operate TrueNAS SCALE storage appliances through read diagnostics and governed CLI or MCP actions for pools, datasets, snapshots, disks, alerts, services, replication, and cloud sync.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[zw008](https://clawhub.ai/user/zw008)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, storage administrators, and operations engineers use this skill to triage TrueNAS SCALE appliances, inspect ZFS storage state, and run governed maintenance tasks through CLI or MCP workflows.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can make real storage changes, including irreversible snapshot deletion, and does not provide its own approval gate.\n\nMitigation: Review before production use, prefer a least-privilege or read-only TrueNAS API key unless writes are intended, and use dry-run plus CLI confirmation for destructive work.\n\nRisk: API keys or master passwords may be exposed if passed through broad environments or command-line values.\n\nMitigation: Use the encrypted secret store and hidden prompts where possible, avoid passing API keys with --value, and scope TRUENAS_AIOPS_MASTER_PASSWORD to the narrowest execution environment.\n\nRisk: Disabling TLS verification weakens connection assurance when reaching the TrueNAS API endpoint.\n\nMitigation: Keep verify_ssl enabled for production appliances and disable it only for self-signed lab certificates.\n\nRisk: A mis-scoped account can allow agent-driven writes beyond the operator's intended session posture.\n\nMitigation: Enforce read-only or limited privileges at the TrueNAS account/API-key level, and instruct the agent not to call write tools during observe-only sessions.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/zw008/skills/truenas-aiops)\n- [Publisher profile](https://clawhub.ai/user/zw008)\n- [Project homepage](https://github.com/AIops-tools/TrueNAS-AIops)\n- [capabilities.md](references/capabilities.md)\n- [cli-reference.md](references/cli-reference.md)\n- [setup-guide.md](references/setup-guide.md)\n- [agent-guardrails.md](references/agent-guardrails.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown prose with inline CLI commands and configuration guidance]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Outputs may include TrueNAS CLI or MCP workflow guidance; live results depend on the configured appliance and account permissions.]\n\n## Skill Version(s):\n\n0.11.3 (source: evidence.release.version)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v0.11.2: 7 files, 17501 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2934b), SKILL.md (16595b), _meta.json (133b)\n\nFile v0.11.2:SKILL.md\n\n---\nname: truenas-aiops\nslug: truenas-aiops\ndisplayName: \"TrueNAS AIops\"\nsummary: \"Governed TrueNAS SCALE storage ops — 25 MCP tools with audit, budget, undo guards.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/TrueNAS-AIops\ntags: [aiops, mcp, governance, truenas]\ndescription: >\n  Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks.\n  Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance.\n  Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only).\n  Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.\ninstaller:\n  kind: uv\n  package: truenas-aiops\nargument-hint: \"[pool/dataset/snapshot id or describe your TrueNAS task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"truenas-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"TRUENAS_AIOPS_CONFIG\",\"TRUENAS_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/TrueNAS-AIops\",\"emoji\":\"🗄️\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed TrueNAS SCALE storage operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.\n  All write operations are audited to a local SQLite DB under ~/.truenas-aiops/ (relocatable via TRUENAS_AIOPS_HOME).\n  Credentials: Each TrueNAS target's API key is stored ENCRYPTED in ~/.truenas-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'truenas-aiops init' to onboard, or 'truenas-aiops secret set <target>' to add one (create the key in the TrueNAS UI: Credentials → API Keys). The store is unlocked by a master password from TRUENAS_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var TRUENAS_<TARGET_NAME_UPPER>_APIKEY is still honoured as a fallback with a deprecation warning (migrate with 'truenas-aiops secret migrate'). The API key is sent as an Authorization: Bearer header at request time and held only in memory; keys are never logged or echoed.\n  Destructive operations (snapshot delete, service restart) require double confirmation at the CLI layer and support --dry-run. All write tools pass through the @governed_tool decorator (budget guard + audit + risk-tier labelling). snapshot_create records an inverse snapshot_delete undo descriptor; snapshot_delete is high-risk and irreversible (captures BEFORE state, records no undo).\n  Webhooks: none — no outbound network calls beyond the configured TrueNAS REST API endpoint.\n  SSL: verify_ssl defaults to true; disable only for self-signed lab certificates.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Routes are resolved against the appliance's own method list and were cross-checked on live 25.04 and 26 appliances; S.M.A.R.T. on failing media remains unverified (see docs/VERIFICATION.md).\n---\n\n# TrueNAS AIops\n\n> **Disclaimer**: This is a community-maintained open-source project and is **not affiliated with, endorsed by, or sponsored by iXsystems or the TrueNAS project.** \"TrueNAS\" is a trademark of its owner. Source code is publicly auditable at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops) under the MIT license.\n\nGoverned TrueNAS SCALE storage operations — **25 MCP tools**, every one wrapped with the bundled `@governed_tool` harness: a local unified audit log under `~/.truenas-aiops/`, policy engine, token/runaway budget guard, undo-token recording, and descriptive risk tiers. The TrueNAS API key is stored **encrypted** (`~/.truenas-aiops/secrets.enc`, Fernet + scrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package (`truenas_aiops.governance`) — truenas-aiops has no external skill-family dependency. **Verification**: coverage focuses on common TrueNAS operations and is not exhaustive, but it is no longer mock-only — reads, governed writes with audit + undo, the WebSocket transport, degraded-pool RCA, replication and cloud-sync have all been exercised against live TrueNAS SCALE 25.04 and 26 appliances. `docs/VERIFICATION.md` records exactly what was checked and what is still open.\n\n## What This Skill Does\n\n| Category | Tools | Count | Read or Write |\n|----------|-------|:-----:|:-------------:|\n| **Overview / System** | health overview, system info | 2 | 2 read |\n| **Diagnostics / RCA** | pool health RCA, alert & capacity RCA | 2 | 2 read |\n| **Pools** | list, get, status, scrub status, capacity | 5 | 5 read |\n| | scrub start | 1 | 1 write (medium) |\n| **Datasets** | list, get | 2 | 2 read |\n| | create | 1 | 1 write (medium) |\n| **Snapshots** | list | 1 | 1 read |\n| | create (medium), delete (high) | 2 | 2 write |\n| **Disks** | list, S.M.A.R.T. results | 2 | 2 read |\n| **Alerts** | list | 1 | 1 read |\n| **Services** | list | 1 | 1 read |\n| | restart | 1 | 1 write (medium) |\n| **Replication** | replication tasks, cloud-sync tasks | 2 | 2 read |\n\n## Quick Install\n\n```bash\nuv tool install truenas-aiops\ntruenas-aiops init       # interactive wizard: connection + encrypted API key\ntruenas-aiops doctor\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/truenas-aiops\nopenclaw skills info truenas-aiops          # expect: Visible to model: yes\n```\n\nNeeds `uvx` on `PATH`: the MCP server is fetched with uv, pinned to this release.\n\n## When to Use This Skill\n\n- Triage a TrueNAS appliance (`overview`): pool capacity/health, alerts, running services\n- Root-cause a degraded/full pool (`diagnose pool-health`) or a wall of alerts (`diagnose alerts`) — worst-first findings that cite the measured number\n- List/inspect ZFS pools, datasets, and snapshots\n- Create a snapshot before a risky change; start a pool scrub\n- Check disk health and S.M.A.R.T. self-test results\n- List and restart system services (smb/nfs/ssh)\n- Inspect replication and cloud-sync tasks\n\n**Do NOT use when** the target is not a TrueNAS SCALE appliance — other NAS/storage or backup products, hypervisor VM lifecycle, Kubernetes/containers, and network devices are out of scope for this skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| TrueNAS pools / datasets / snapshots / ZFS health | **truenas-aiops** (this skill) |\n| Backup software job/restore operations | a backup-software ops skill |\n| Hypervisor VM lifecycle (power, snapshot, migrate) | a hypervisor ops skill |\n| Container/cluster lifecycle | a cluster ops skill |\n\n## Common Workflows\n\n### Root-cause a degraded or full pool (start here)\n\n1. `truenas-aiops diagnose pool-health` → worst-first findings: bad ZFS state (DEGRADED/FAULTED/OFFLINE), non-zero read/write/checksum/scan error counters, and pools over 80%/90% capacity — each citing the measured number\n2. `truenas-aiops pool status <pool_id>` → inspect the topology / scan detail the finding cited\n3. `truenas-aiops pool scrub-start <pool_name>` → kick an integrity scrub (governed, medium risk); poll with `pool scrub-status`\n4. `truenas-aiops diagnose alerts` → cross-check active alerts by level and any datasets nearing their quota/available ceiling\n\n### Snapshot a dataset before a change, then roll back if needed\n\n1. `truenas-aiops dataset list` → confirm the dataset id (e.g. `tank/data`)\n2. `truenas-aiops snapshot create tank/data pre-change` → records an inverse `snapshot_delete` undo descriptor\n3. Make your change; if it went wrong, the snapshot is your recovery point\n4. `truenas-aiops snapshot delete tank/data@pre-change --dry-run` → preview; then without `--dry-run` (double confirm) — IRREVERSIBLE, captures BEFORE state, no undo\n\n### Scrub a pool and follow it\n\n1. `truenas-aiops pool list` → find the pool name and health\n2. `truenas-aiops pool scrub-start tank` → starts the integrity scrub\n3. `truenas-aiops pool scrub-status <pool_id>` → check `state` / `percentage`; do not re-issue (the runaway budget guard backs a tight poll loop)\n\n## Usage Mode\n\n| Scenario | Recommended | Why |\n|----------|:-----------:|-----|\n| Local/small models | **CLI** | fewer tokens than MCP |\n| Cloud models (Claude, GPT) | Either | MCP gives structured JSON I/O |\n| Automated pipelines | **MCP** | type-safe parameters, audited |\n\n## MCP Tools (25 — 19 read, 6 write)\n\n| Category | Tools | R/W |\n|----------|-------|:---:|\n| Overview / System | `overview`, `system_info` | Read |\n| Diagnostics / RCA | `pool_health_rca`, `alert_and_capacity_rca` | Read |\n| Pools | `pool_list`, `pool_get`, `pool_status`, `scrub_status`, `pool_capacity` | Read |\n| | `pool_scrub_start` | Write |\n| Datasets | `dataset_list`, `dataset_get` | Read |\n| | `dataset_create` | Write |\n| Snapshots | `snapshot_list` | Read |\n| | `snapshot_create`, `snapshot_delete` | Write |\n| Disks | `disk_list`, `smart_test_results` | Read |\n| Alerts | `alert_list` | Read |\n| Services | `service_list` | Read |\n| | `service_restart` | Write |\n| Replication | `replication_list`, `cloudsync_list` | Read |\n| Undo (governance) | `undo_list` | Read |\n| | `undo_apply` | Write |\n\n**Harness features that light up**: `snapshot_create` passes an `undo=` lambda so the harness records an inverse `snapshot_delete` descriptor (with `_undo_id`) to the undo store. `snapshot_delete` is tagged `risk_level=high`, captures the snapshot's BEFORE state, and declares no undo (it is irreversible). `pool_scrub_start`, `dataset_create`, and `service_restart` are `medium` risk and capture prior state where relevant. All 25 tools are audit-logged under `~/.truenas-aiops/` and pass through the budget/runaway guard, with a descriptive risk-tier label on each audit row. Start any triage with `overview`.\n\n## CLI Quick Reference\n\n```bash\ntruenas-aiops init                                    # onboarding wizard (encrypted API key)\ntruenas-aiops overview [--target <t>]                 # health summary\ntruenas-aiops system [--target <t>]                   # version / hostname / memory / uptime\ntruenas-aiops diagnose pool-health                    # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts                         # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity                           # size / allocated / free / used%\ntruenas-aiops pool scrub-start <pool_name>\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>                # e.g. tank/data\ntruenas-aiops dataset create <tank/path> [--dry-run]\ntruenas-aiops snapshot list [--dataset tank/data] [--limit 200]\ntruenas-aiops snapshot create <dataset> <name>\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # double confirm, IRREVERSIBLE\ntruenas-aiops disk list\ntruenas-aiops disk smart                              # S.M.A.R.T. self-test results\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops service restart <service> [--dry-run]   # double confirm (smb/nfs/ssh)\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\ntruenas-aiops secret set <target>                     # store API key encrypted\ntruenas-aiops secret list                             # names only\ntruenas-aiops secret migrate                          # import legacy plaintext .env\ntruenas-aiops secret rotate-password\ntruenas-aiops doctor\ntruenas-aiops mcp                                     # start MCP server (stdio)\n```\n\nSee `references/cli-reference.md` for the full command list, and\n`references/agent-guardrails.md` when driving these tools with a smaller /\nlocal model (enforced guardrails, ready-to-paste system prompt).\n\n## Troubleshooting\n\n### \"Config file not found\"\nRun `truenas-aiops init` to set up your first target (writes `~/.truenas-aiops/config.yaml` and stores the API key encrypted).\n\n### \"No API key for target '<name>'\"\nAdd it to the encrypted store: `truenas-aiops secret set <name>` (prompts hidden), or run `truenas-aiops init`. Create the key in the TrueNAS UI under Credentials → API Keys. For non-interactive use (MCP/CI), also export `TRUENAS_AIOPS_MASTER_PASSWORD` so the store can be unlocked without a prompt.\n\n### \"Master password not set\" / \"Wrong master password\"\nThe encrypted store `~/.truenas-aiops/secrets.enc` is unlocked by `TRUENAS_AIOPS_MASTER_PASSWORD` (or an interactive prompt). If you forgot it, delete `secrets.enc` and re-run `truenas-aiops init`. Rotate it with `truenas-aiops secret rotate-password`.\n\n### \"Authentication/authorization failed (401/403)\"\nThe API key is wrong or revoked, or the account lacks permission. Regenerate the key in the TrueNAS UI (Credentials → API Keys) and update it: `truenas-aiops secret set <name>`.\n\n### \"Could not reach TrueNAS … check the host/port\"\nConfirm the TrueNAS web/REST endpoint is reachable on the configured port (default 443) and `api_path` is `/api/v2.0`. For self-signed certificates set `verify_ssl: false` on the target (lab only).\n\n### \"Resource not found (404)\"\nThe pool/dataset/snapshot id is stale. List the parent collection first (`pool list`, `dataset list`, `snapshot list`) to get a current id.\n\n## Audit & Safety\n\nThe skill delivers reads and writes and records them; it does **not** decide\nwhether a write is permitted. That is your agent's judgement, or the permission\nof the account you connect it with (scope the TrueNAS API key to a\nlimited-privilege account and writes then fail at the appliance). There is no\nread-only switch, policy file, or approval gate.\n\n- API key stored **encrypted** in `~/.truenas-aiops/secrets.enc` (Fernet/AES-128 + scrypt key derivation; chmod 600) — never plaintext on disk; the master password is never stored, only a per-store salt + ciphertext.\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.truenas-aiops/audit.db` (relocatable via `TRUENAS_AIOPS_HOME`): params (secrets redacted), result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `TRUENAS_AUDIT_APPROVED_BY` / `TRUENAS_AUDIT_RATIONALE` are optional annotations recorded on the audit row (who/why); they are never required and never block.\n- **Runaway guard** — a safety backstop, not authorization: cumulative tool calls and wall-time are capped, and a tight scrub/poll loop trips a circuit breaker.\n- Writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI; CLI writes execute through the same governed tools, so they are audited + undo-recorded.\n- Reversible writes capture the real fetched before-state and record an inverse descriptor (e.g. `snapshot_create` → `snapshot_delete`) that replays against the tool's own signature.\n\nThe harness is bundled in the package — no external dependency, no manual setup. See `references/setup-guide.md` for security details.\n\n## Contributing & feature requests\n\nCoverage is intentionally focused, and what has actually been verified against live appliances is recorded in `docs/VERIFICATION.md`. **Missing a capability you need, or hit an endpoint that needs fixing for your TrueNAS version?** Open an issue or pull request at [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues) — feature requests, contributions, and comments are all welcome.\n\n## License\n\nMIT — [github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops)\n\nFile v0.11.2:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"truenas-aiops\",\n  \"version\": \"0.11.2\",\n  \"publishedAt\": 1789224328541\n}\n\nFile v0.11.2:references/agent-guardrails.md\n\n# Agent guardrails — running truenas-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Scope the TrueNAS API key to a\n  limited-privilege account (the key inherits its user's permissions). A write\n  then fails at the appliance, which is the only place the permission actually\n  lives — a revoked permission cannot be argued around by a model, but a\n  skill-side flag can.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Don't invent a value when a field is missing\" | A field the TrueNAS middleware did not return comes back as `null`, never as `\"\"`. Absent and empty are distinguishable in the payload — a disk with no `serial`, a dataset with no `mountpoint`, a replication task with no `state` all report `null`. |\n| \"Tell me if the output was cut off\" | `snapshot_list` and `undo_list` return `{\"snapshots\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is measured, not guessed from a length coincidence. This matters most for snapshots: a periodic snapshot task retaining hourly/daily/weekly across a few datasets produces thousands of rows. |\n| \"Preserve the ordering / tell me what's most urgent\" | `pool_health_rca` and `alert_and_capacity_rca` findings carry an explicit 1-based `rank`, worst-first. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `snapshot delete` and `service restart` at the CLI require a `--dry-run`-able preview plus double confirmation. `snapshot_delete` captures the BEFORE state for the audit record. |\n| \"Log what you did\" | Every governed call is audited to `~/.truenas-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. `snapshot_create` additionally records a replayable inverse undo token. |\n| \"Don't get stuck retrying\" | The runaway guard trips a circuit breaker if the same call is hammered in a tight loop — a stuck agent is stopped rather than left to burn calls and time. |\n| \"Don't paraphrase the pool status\" | Pool `status` and `healthy` are passed through verbatim from ZFS — the ops layer never normalises `HEALTHY` / `DEGRADED` / `FAULTED` / `OFFLINE`. Only the model can break that; see the prompt below. |\n\n## What still needs a prompt\n\nThese are model-behaviour problems the harness cannot fix from the outside.\nCopy this into your agent's system prompt:\n\n```text\nYou operate a TrueNAS SCALE storage appliance through the truenas-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current TrueNAS appliance, you MUST\n  call a tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit instead of treating\n  the partial result as complete.\n- A null field means the middleware did not return that value. Report it as\n  \"not available\" — never infer it.\n- Report ZFS status strings exactly as returned: HEALTHY, DEGRADED, FAULTED,\n  OFFLINE, UNAVAIL, REMOVED. Do not paraphrase \"DEGRADED\" as \"having issues\",\n  and do not translate or prettify alert levels or IDs.\n- When an RCA result has findings, work in \"rank\" order and cite the measured\n  number in each finding's \"detail\" (used-percent, error counters, alert level).\n\nIDENTIFIERS\n- A pool name (\"tank\") is not a dataset path (\"tank/data/vm\") and neither is a\n  snapshot id (\"tank/data@auto-2026-07-18\"). A snapshot id is always\n  <dataset>@<snapshot-name>. Do not construct one by guessing; take it from\n  snapshot_list.\n- A disk device name (\"sda\") is not a disk serial and is not stable across\n  reboots or controller changes. Quote both when identifying a disk.\n- Service names are the TrueNAS middleware names (\"smb\", \"nfs\", \"ssh\"), not\n  systemd unit names.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert a capacity, redundancy, or performance problem unless a tool\n  result supports it.\n- Do not add generic advice that does not follow from the tool output.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the account's\npermission only when you trust the setup — snapshot deletion is irreversible and\ntakes any dependent clones with it:\n\n```bash\n# e.g. connect with an API key for a limited-privilege TrueNAS account that\n# lacks write access. Then:\ntruenas-aiops doctor\n```\n\nOptionally annotate the audit trail with who is operating and why — recorded on\nevery row, never required:\n\n```bash\nexport TRUENAS_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport TRUENAS_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\n\n## TrueNAS-specific notes worth knowing\n\n- **A dataset path is not a pool name.** `tank` is a pool; `tank/data/vm` is a\n  dataset inside it. `pool_get`/`pool_status` take a pool id; `dataset_get`\n  takes the full dataset path. Passing one where the other is expected returns a\n  404 from the middleware, not a helpful error.\n- **Snapshot deletion is irreversible and destroys dependent clones.** ZFS\n  clones are backed by their origin snapshot; deleting\n  `tank/data@auto-2026-07-18` takes any clone promoted from it with it. That is\n  why `snapshot_delete` is `high` risk, declares no undo, and only captures the\n  BEFORE state for the audit record. There is no \"restore from the recycle bin\".\n- **Report pool status verbatim.** `HEALTHY` and `DEGRADED` are ZFS states with\n  precise meanings — `DEGRADED` means redundancy is lost but the pool is still\n  serving I/O, which is a very different operational posture from `FAULTED`.\n  Paraphrasing loses the distinction an operator acts on.\n- **A scrub is not a repair.** `pool_scrub_start` kicks an integrity check; it\n  will surface checksum errors and repair what redundancy allows, but it does\n  not replace a failing disk. It is also long-running — poll `scrub_status`,\n  never re-issue.\n- **`healthy: false` with status `ONLINE` is real.** ZFS reports it after recent\n  errors or an incomplete resilver. `pool_health_rca` flags it as a warning\n  rather than swallowing it.\n- **Capacity thresholds are about ZFS, not disk space etiquette.** ZFS is\n  copy-on-write; above roughly 80% it slows and above 90% it fragments sharply.\n  The RCA thresholds (`CAP_WARN_PCT` 80, `CAP_CRIT_PCT` 90) exist for that\n  reason and are cited in every capacity finding.\n- **Dataset usage is measured against a quota when one is set**, otherwise\n  against `used + available` headroom. The finding text says which.\n\n## If your model still struggles\n\nSome behaviours are model-capacity limits rather than prompt problems:\n\n- **Multi-tool workflows time out or drift.** Prefer `overview` and the two RCA\n  tools (`pool_health_rca`, `alert_and_capacity_rca`) — they do the multi-step\n  correlation inside one call, so the model does not have to chain reads and\n  keep pool/dataset ids straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions; filter `snapshot_list` to one dataset and use `limit` deliberately\n  rather than pulling every snapshot on the appliance.\n- **The model describes calls instead of making them.** This is usually a\n  runtime/tool-calling-format mismatch, not a prompt problem — check that your\n  client advertises the tools in the format your model was trained on.\n\nFeedback on running this with a specific local model is genuinely useful —\nopen an issue at\n[github.com/AIops-tools/TrueNAS-AIops](https://github.com/AIops-tools/TrueNAS-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.11.2:references/capabilities.md\n\n# truenas-aiops capabilities\n\n> 25 MCP tools (19 read, 6 write). Routes are resolved against the appliance's\n> own method list and were cross-checked on live TrueNAS SCALE 25.04 and 26\n> appliances; see docs/VERIFICATION.md for what remains unverified.\n\n## Read tools (19)\n\n| Tool | REST (modelled) | Returns |\n|------|----------------|---------|\n| `overview` | fan-out | pools (capacity/health), alerts by level, running services |\n| `system_info` | `GET /system/info` | version, hostname, memory, cores, uptime |\n| `pool_health_rca` | `GET /pool` | worst-first findings: bad ZFS state, read/write/checksum/scan error counts, capacity over 80%/90% |\n| `alert_and_capacity_rca` | `POST /alert/list` + `GET /pool/dataset` | worst-first findings: active alerts by level + datasets near quota/available ceiling |\n| `pool_list` | `GET /pool` | id, name, status, healthy, size/allocated/free |\n| `pool_get` | `GET /pool/id/{id}` | single pool detail |\n| `pool_status` | `GET /pool/id/{id}` | health + scan + topology summary |\n| `scrub_status` | `GET /pool/id/{id}` | scrub function/state/percentage |\n| `pool_capacity` | `GET /pool` | size/allocated/free + used% per pool |\n| `dataset_list` | `GET /pool/dataset` | id, name, type, pool, used/available |\n| `dataset_get` | `GET /pool/dataset/id/{id}` | single dataset detail |\n| `snapshot_list` | `GET /zfs/snapshot` | `{snapshots, returned, limit, truncated}` — id, dataset, name, used (opt. filter by dataset; default limit 200) |\n| `disk_list` | `GET /disk` | name, serial, model, size, pool |\n| `smart_test_results` | `GET /smart/test/results` | latest S.M.A.R.T. self-test per disk |\n| `alert_list` | `POST /alert/list` | level, message, class, dismissed |\n| `service_list` | `GET /service` | name, state (RUNNING/STOPPED), enable |\n| `replication_list` | `GET /replication` | name, direction, transport, state (PENDING/RUNNING/FINISHED/ERROR, never absent), error, lastSnapshot, lastRun |\n| `cloudsync_list` | `GET /cloudsync` | description, direction, path, state (the last run's job state; null until it runs) |\n| `undo_list` | governance store | recorded reversible writes / not-yet-applied undo tokens |\n\n## Write tools (6)\n\n| Tool | Risk | REST (modelled) | Undo / safety |\n|------|------|----------------|---------------|\n| `pool_scrub_start` | medium | `POST /pool/scrub/run` | captures prior scan state; no undo (non-destructive); `dry_run` |\n| `dataset_create` | medium | `POST /pool/dataset` | no undo (deletion out of scope); `dry_run` |\n| `snapshot_create` | medium | `POST /zfs/snapshot` | records inverse `snapshot_delete` undo descriptor; `dry_run` |\n| `snapshot_delete` | **high** | `DELETE /zfs/snapshot/id/{id}` | captures BEFORE state; IRREVERSIBLE, no undo; CLI double-confirm + `dry_run` |\n| `service_restart` | medium | `POST /service/restart` | captures prior state; no undo; refuses a name absent from `service_list`, and refuses `ssh` without `confirm=True` (out-of-band recovery path); guards also fire under `dry_run`; CLI double-confirm |\n| `undo_apply` | mediu\n\nArchive v0.11.1: 7 files, 17440 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2847b), SKILL.md (16601b), _meta.json (133b)\n\nArchive v0.11.0: 7 files, 17379 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (3010b), SKILL.md (16287b), _meta.json (133b)\n\nArchive v0.10.0: 7 files, 17290 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2782b), SKILL.md (16395b), _meta.json (133b)\n\nArchive v0.9.0: 7 files, 17352 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2932b), SKILL.md (16395b), _meta.json (132b)\n\nArchive v0.8.1: 7 files, 17286 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3492b), references/cli-reference.md (2828b), references/setup-guide.md (2463b), skill-card.md (2896b), SKILL.md (16395b), _meta.json (132b)\n\nArchive v0.8.0: 7 files, 17103 bytes\n\nFiles: references/agent-guardrails.md (9058b), references/capabilities.md (3427b), references/cli-reference.md (2811b), references/setup-guide.md (2426b), skill-card.md (3070b), SKILL.md (15929b), _meta.json (132b)","readmeExcerpt":"Skill: truenas-aiops Owner: zw008 Summary: Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system ","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"uv tool install truenas-aiops\ntruenas-aiops init       # interactive wizard: connection + encrypted API key\ntruenas-aiops doctor"},{"language":"bash","snippet":"openclaw plugins install clawhub:@zw008/truenas-aiops\nopenclaw skills info truenas-aiops          # expect: Visible to model: yes"},{"language":"bash","snippet":"truenas-aiops init                                    # onboarding wizard (encrypted API key)\ntruenas-aiops overview [--target <t>]                 # health summary\ntruenas-aiops system [--target <t>]                   # version / hostname / memory / uptime\ntruenas-aiops diagnose pool-health                    # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts                         # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity                           # size / allocated / free / used%\ntruenas-aiops pool scrub-start <pool_name>\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>                # e.g. tank/data\ntruenas-aiops dataset create <tank/path> [--dry-run]\ntruenas-aiops snapshot list [--dataset tank/data] [--limit 200]\ntruenas-aiops snapshot create <dataset> <name>\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # double confirm, IRREVERSIBLE\ntruenas-aiops disk list\ntruenas-aiops disk smart                              # S.M.A.R.T. self-test results\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops service restart <service> [--dry-run]   # double confirm (smb/nfs/ssh)\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\ntruenas-aiops secret set <target>                     # store API key encrypted\ntruenas-aiops secret list                             # names only\ntruenas-aiops secret migrate                          # import legacy plaintext .env\ntruenas-aiops secret rotate-password\ntruenas-aiops doctor\ntruenas-aiops mcp                                     # start MCP server (stdio)"},{"language":"text","snippet":"You operate a TrueNAS SCALE storage appliance through the truenas-aiops MCP tools.\n\nTOOL USE\n- Before answering any question about the current TrueNAS appliance, you MUST\n  call a tool. Never answer from memory or assumption.\n- Actually invoke the tool. Do not describe the call you would make, and do not\n  emit an example JSON response in place of calling it.\n- If a tool call fails, report the real error verbatim. Never fill the gap with\n  a plausible-sounding answer.\n\nREADING RESULTS\n- Read the whole result before concluding. If a result contains a \"truncated\"\n  field that is true, say so and re-run with a higher limit instead of treating\n  the partial result as complete.\n- A null field means the middleware did not return that value. Report it as\n  \"not available\" — never infer it.\n- Report ZFS status strings exactly as returned: HEALTHY, DEGRADED, FAULTED,\n  OFFLINE, UNAVAIL, REMOVED. Do not paraphrase \"DEGRADED\" as \"having issues\",\n  and do not translate or prettify alert levels or IDs.\n- When an RCA result has findings, work in \"rank\" order and cite the measured\n  number in each finding's \"detail\" (used-percent, error counters, alert level).\n\nIDENTIFIERS\n- A pool name (\"tank\") is not a dataset path (\"tank/data/vm\") and neither is a\n  snapshot id (\"tank/data@auto-2026-07-18\"). A snapshot id is always\n  <dataset>@<snapshot-name>. Do not construct one by guessing; take it from\n  snapshot_list.\n- A disk device name (\"sda\") is not a disk serial and is not stable across\n  reboots or controller changes. Quote both when identifying a disk.\n- Service names are the TrueNAS middleware names (\"smb\", \"nfs\", \"ssh\"), not\n  systemd unit names.\n\nSCOPE\n- Separate observation from interpretation. State what the tools returned, then\n  any interpretation, clearly marked as such.\n- Do not assert a capacity, redundancy, or performance problem unless a tool\n  result supports it.\n- Do not add generic advice that does not follow from the tool output."},{"language":"bash","snippet":"# e.g. connect with an API key for a limited-privilege TrueNAS account that\n# lacks write access. Then:\ntruenas-aiops doctor"},{"language":"bash","snippet":"export TRUENAS_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport TRUENAS_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\""}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: truenas-aiops\nslug: truenas-aiops\ndisplayName: \"TrueNAS AIops\"\nsummary: \"Governed TrueNAS SCALE storage ops — 25 MCP tools with audit, budget, undo guards.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/TrueNAS-AIops\ntags: [aiops, mcp, governance, truenas]\ndescription: >\n  Use this skill whenever the user needs to operate TrueNAS SCALE storage — a one-shot health overview, system info, read-only diagnostics / RCA (pool health, alerts & dataset capacity), inspect ZFS pools (list/get/status, capacity, scrub status, start a scrub), datasets (list/get/create), snapshots (list/create/delete), physical disks and S.M.A.R.T. self-test results, system alerts, services (list/restart), and replication / cloud-sync tasks.\n  Always use this skill for \"list truenas pools\", \"truenas dataset\", \"create zfs snapshot\", \"start a scrub\", \"diagnose truenas pool health\", \"why is my pool degraded\", \"truenas disk health\", \"truenas smart test\", \"truenas alerts\", \"restart truenas service\", or \"truenas replication\" when the context is explicitly TrueNAS / TrueNAS SCALE / a ZFS NAS appliance.\n  Do NOT use when the target is not a TrueNAS SCALE appliance — other NAS/storage products, backup software, hypervisor VM lifecycle, container clusters, and network devices are out of scope (negative routing hints only).\n  Common TrueNAS SCALE operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers). Live-verified against real TrueNAS SCALE 25.04 and 26 appliances over both transports; see docs/VERIFICATION.md for what is and is not covered.\ninstaller:\n  kind: uv\n  package: truenas-aiops\nargument-hint: \"[pool/dataset/snapshot id or describe your TrueNAS task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"truenas-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"TRUENAS_AIOPS_CONFIG\",\"TRUENAS_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/TrueNAS-AIops\",\"emoji\":\"🗄️\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed TrueNAS SCALE storage operations. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.\n  All write operations are audited to a local SQLite DB under ~/.truenas-aiops/ (relocatable via TRUENAS_AIOPS_HOME).\n  Credentials: Each TrueNAS target's API key is stored ENCRYPTED in ~/.truenas-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'truenas-aiops init' to onboard, or 'truenas-aiops secret set <target>' to add one (create the key in the TrueNAS UI: Credentials → API Keys). The store is unlocked by a master password from TRUENAS_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var TRUENAS_<TARGET_NAME_UPPER>_APIKEY is still honoured as a fallback with a deprecation warning (migrate with 'truenas-aiops secret migrate'). The API key is sent as an Authorization: Bearer header at request t"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"truenas-aiops\",\n  \"version\": \"0.11.5\",\n  \"publishedAt\": 1789601199051\n}"},{"path":"references/agent-guardrails.md","content":"# Agent guardrails — running truenas-aiops with a smaller / local model\n\nIf you drive these tools with a local model (Llama, Qwen, Mistral … via Goose,\nOllama, LM Studio, or any OpenAI-compatible runtime), you will get noticeably\nbetter results with a short system prompt. This page gives you one, and — more\nimportantly — tells you which guardrails you **no longer need to write**, because\nthe tool now enforces them itself.\n\nThe distinction matters. A guardrail in a prompt is a request. A guardrail in the\nharness is a guarantee. Anything below that we could move into the harness, we did.\n\n## Authorization is not this tool's job — decide it where it belongs\n\nWhether a write should happen is your decision, or the account's. The tool does\nnot gate it — there is no read-only switch and no approval prompt to configure.\nThe two right places to control read vs write:\n\n- **The account you connect with.** Scope the TrueNAS API key to a\n  limited-privilege account (the key inherits its user's permissions). A write\n  then fails at the appliance, which is the only place the permission actually\n  lives — a revoked permission cannot be argued around by a model, but a\n  skill-side flag can.\n- **Your agent's system prompt.** If you want an observe-only session, tell the\n  model not to call the write tools (they are clearly tagged `[WRITE]`).\n\nWhat the tool *does* guarantee is that you can always see what happened:\n\n## What the tool enforces — do not waste prompt budget on these\n\n| You might be tempted to prompt | Why you don't need to |\n|---|---|\n| \"Don't invent a value when a field is missing\" | A field the TrueNAS middleware did not return comes back as `null`, never as `\"\"`. Absent and empty are distinguishable in the payload — a disk with no `serial`, a dataset with no `mountpoint`, a replication task with no `state` all report `null`. |\n| \"Tell me if the output was cut off\" | `snapshot_list` returns `{\"snapshots\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}` and `undo_list` the same shape under `undos`. Truncation is measured, not guessed from a length coincidence. This matters most for snapshots: a periodic snapshot task retaining hourly/daily/weekly across a few datasets produces thousands of rows. |\n| \"Preserve the ordering / tell me what's most urgent\" | `pool_health_rca` and `alert_and_capacity_rca` findings carry an explicit 1-based `rank`, worst-first. Priority is in the payload, not implied by list position. |\n| \"Confirm before anything destructive\" | `snapshot delete` and `service restart` at the CLI require a `--dry-run`-able preview plus double confirmation. `snapshot_delete` captures the BEFORE state for the audit record. |\n| \"Log what you did\" | Every governed call is audited to `~/.truenas-aiops/audit.db` regardless of what the model says it did — and the CLI writes the same row the MCP path does, so there is no unaudited entry point. `snapshot_create` additionally records a replayable inverse undo token. |\n| \"Don't get stuck retr"},{"path":"references/capabilities.md","content":"# truenas-aiops capabilities\n\n> 25 MCP tools (19 read, 6 write). Routes are resolved against the appliance's\n> own method list and were cross-checked on live TrueNAS SCALE 25.04 and 26\n> appliances; see docs/VERIFICATION.md for what remains unverified.\n\n## Read tools (19)\n\n| Tool | REST (modelled) | Returns |\n|------|----------------|---------|\n| `overview` | fan-out | pools (capacity/health), alerts by level, running services |\n| `system_info` | `GET /system/info` | version, hostname, memory, cores, uptime |\n| `pool_health_rca` | `GET /pool` | worst-first findings: bad ZFS state, read/write/checksum/scan error counts, capacity over 80%/90% |\n| `alert_and_capacity_rca` | `POST /alert/list` + `GET /pool/dataset` | worst-first findings: active alerts by level + datasets near quota/available ceiling |\n| `pool_list` | `GET /pool` | id, name, status, healthy, size/allocated/free |\n| `pool_get` | `GET /pool/id/{id}` | single pool detail |\n| `pool_status` | `GET /pool/id/{id}` | health + scan + topology summary |\n| `scrub_status` | `GET /pool/id/{id}` | scrub function/state/percentage |\n| `pool_capacity` | `GET /pool` | size/allocated/free + used% per pool |\n| `dataset_list` | `GET /pool/dataset` | id, name, type, pool, used/available |\n| `dataset_get` | `GET /pool/dataset/id/{id}` | single dataset detail |\n| `snapshot_list` | `GET /zfs/snapshot` | `{snapshots, returned, limit, truncated}` — id, dataset, name, used (opt. filter by dataset; default limit 200) |\n| `disk_list` | `GET /disk` | name, serial, model, size, pool |\n| `smart_test_results` | `GET /smart/test/results` | latest S.M.A.R.T. self-test per disk |\n| `alert_list` | `POST /alert/list` | level, message, class, dismissed |\n| `service_list` | `GET /service` | name, state (RUNNING/STOPPED), enable |\n| `replication_list` | `GET /replication` | name, direction, transport, state (PENDING/RUNNING/FINISHED/ERROR, never absent), error, lastSnapshot, lastRun |\n| `cloudsync_list` | `GET /cloudsync` | description, direction, path, state (the last run's job state; null until it runs) |\n| `undo_list` | governance store | recorded reversible writes / not-yet-applied undo tokens |\n\n## Write tools (6)\n\n| Tool | Risk | REST (modelled) | Undo / safety |\n|------|------|----------------|---------------|\n| `pool_scrub_start` | medium | `POST /pool/scrub/run` | captures prior scan state; no undo (non-destructive); `dry_run` |\n| `dataset_create` | medium | `POST /pool/dataset` | no undo (deletion out of scope); `dry_run` |\n| `snapshot_create` | medium | `POST /zfs/snapshot` | records inverse `snapshot_delete` undo descriptor; `dry_run` |\n| `snapshot_delete` | **high** | `DELETE /zfs/snapshot/id/{id}` | captures BEFORE state; IRREVERSIBLE, no undo; CLI double-confirm + `dry_run` |\n| `service_restart` | medium | `POST /service/restart` | captures prior state; no undo; refuses a name absent from `service_list`, and refuses `ssh` without `confirm=True` (out-of-band recovery path); guards also fire under `dry_run`; CLI"},{"path":"references/cli-reference.md","content":"# truenas-aiops CLI reference\n\n> Exercised against live TrueNAS SCALE 25.04 and 26 appliances over both the\n> REST and WebSocket transports; see docs/VERIFICATION.md for the gaps.\n\n## Setup & diagnostics\n\n```bash\ntruenas-aiops init                      # interactive onboarding wizard\ntruenas-aiops doctor [--skip-auth]      # config + secret store + connectivity (/system/info)\ntruenas-aiops mcp                       # start the MCP server (stdio transport)\n```\n\n## Secrets (encrypted store ~/.truenas-aiops/secrets.enc)\n\n```bash\ntruenas-aiops secret set <target> [--value <key>]   # store API key (hidden prompt if no --value)\ntruenas-aiops secret list                            # names only — values never shown\ntruenas-aiops secret rm <target>\ntruenas-aiops secret migrate                         # import legacy plaintext .env (TRUENAS_<T>_APIKEY)\ntruenas-aiops secret rotate-password                 # re-encrypt under a new master password\n```\n\n## Read commands\n\n```bash\ntruenas-aiops overview [--target <t>]    # pools (capacity/health), alerts by level, running services\ntruenas-aiops system [--target <t>]      # version / hostname / memory / cores / uptime\ntruenas-aiops diagnose pool-health       # RCA: pool state / error counters / capacity (worst first)\ntruenas-aiops diagnose alerts            # RCA: active alerts by level + datasets near full\ntruenas-aiops pool list\ntruenas-aiops pool get <pool_id>\ntruenas-aiops pool status <pool_id>      # health + scan + topology summary\ntruenas-aiops pool scrub-status <pool_id>\ntruenas-aiops pool capacity              # size / allocated / free / used% per pool\ntruenas-aiops dataset list\ntruenas-aiops dataset get <dataset_id>   # e.g. tank/data\ntruenas-aiops snapshot list [--dataset <tank/data>] [--limit 200]\ntruenas-aiops disk list\ntruenas-aiops disk smart                 # S.M.A.R.T. self-test results per disk\ntruenas-aiops alert list\ntruenas-aiops service list\ntruenas-aiops replication list\ntruenas-aiops replication cloudsync\n```\n\n## Write commands (governed; risk tier in parentheses)\n\n```bash\ntruenas-aiops pool scrub-start <pool_name>            # (medium) start an integrity scrub\ntruenas-aiops dataset create <tank/path> [--dry-run]  # (medium) create a ZFS dataset\ntruenas-aiops snapshot create <dataset> <name>        # (medium) records inverse snapshot_delete undo\ntruenas-aiops snapshot delete <dataset@name> [--dry-run]   # (high) double confirm — IRREVERSIBLE\ntruenas-aiops service restart <service> [--dry-run]   # (medium) double confirm — smb/nfs/ssh/...\n```\n\n## Common options\n\n- `--target, -t <name>` — target name from `config.yaml` (omit to use the default/first target)\n- `--dry-run` — print the API call that would be made, change nothing\n- Destructive commands (`snapshot delete`, `service restart`) require two confirmations"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":2149,"uniquenessScore":38,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T08:08:26.358Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T08:08:26.358Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T10:45:13.385Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}