{"id":"28c4db12-8ae2-4a62-bb49-98eeea3b78eb","entityType":"agent","slug":"clawhub-zw008-cicd-aiops","name":"cicd-aiops","canonicalUrl":"https://www.xpersona.co/agent/clawhub-zw008-cicd-aiops","canonicalPath":"/agent/clawhub-zw008-cicd-aiops","generatedAt":"2026-10-10T10:44:35.865Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:30:40.929Z","emptyReason":null},"description":"Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection). Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance. Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances. Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).","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:cicd-aiops","sourceUrl":"https://clawhub.ai/zw008/cicd-aiops","homepage":"https://clawhub.ai/zw008/skills/cicd-aiops","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/zw008/cicd-aiops","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/zw008/skills/cicd-aiops","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":64,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"cicd-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-10T07:30:40.929Z","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-10T07:30:40.929Z","emptyReason":null},"stars":null,"forks":null,"downloads":1590,"packageName":null,"latestVersion":"0.10.3","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:30:40.864Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T07:30:40.929Z","lastCrawledAt":"2026-10-10T07:30:40.864Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T07:30:40.864Z","lastVerifiedAt":null,"highlights":[{"version":"0.10.3","createdAt":"2026-09-15T05:48:31.953Z","changelog":"- Removed the file skill-card.md. - No functional or user-facing changes in this release.","fileCount":7,"zipByteSize":19274},{"version":"0.10.2","createdAt":"2026-09-12T13:59:51.874Z","changelog":"- Documentation updated in SKILL.md: clarified OpenClaw installation instructions and other minor improvements. - skill-card.md file removed. - No functional or code changes; this is a documentation and packaging update only.","fileCount":7,"zipByteSize":19392},{"version":"0.10.1","createdAt":"2026-09-12T09:56:02.594Z","changelog":"- Removed the redundant skill-card.md file for simpler packaging. - SKILL.md updated with quickstart for OpenClaw plugin usage. - No functional changes to tools or core capabilities. - Documentation now covers OpenClaw install instructions.","fileCount":7,"zipByteSize":19219},{"version":"0.10.0","createdAt":"2026-09-12T00:44:40.656Z","changelog":"- metadata requirements updated: now requires either \"cicd-aiops\" or \"uvx\" binary (anyBins), and \"CICD_AIOPS_CONFIG\" and \"CICD_AIOPS_MASTER_PASSWORD\" are marked as optional environment variables. - Previous file \"skill-card.md\" has been removed. - SKILL.md compatibility, description, and metadata have been revised accordingly; see the new metadata field and requirements. - No new user-facing commands or tool changes. No functional pipeline/tools change in this version.","fileCount":7,"zipByteSize":19202},{"version":"0.9.0","createdAt":"2026-08-10T06:49:42.982Z","changelog":"- Removed the file: skill-card.md - No changes to functionality or feature set; documentation and metadata remain unchanged. - Housekeeping update to project files only.","fileCount":7,"zipByteSize":19217},{"version":"0.8.0","createdAt":"2026-08-10T03:57:53.740Z","changelog":"cicd-aiops version 0.8.0 - Updated documentation: revised references/capabilities.md. - Removed outdated or redundant file: skill-card.md.","fileCount":7,"zipByteSize":19173},{"version":"0.7.0","createdAt":"2026-08-03T05:51:54.489Z","changelog":"- Removed the file skill-card.md from the project. - No changes to functionality or user-facing features. - Documentation and available tools remain unchanged.","fileCount":7,"zipByteSize":19143},{"version":"0.6.0","createdAt":"2026-08-02T09:38:03.082Z","changelog":"- Removed the skill-card.md file. - No changes to user-facing features or functionality.","fileCount":7,"zipByteSize":19050}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:cicd-aiops","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s171xgnmqse0nqvgqvqnaq5f9183kyre:cicd-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/cicd-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-cicd-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-aiops/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-aiops/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-aiops/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-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:44:35.857Z"}},"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-cicd-aiops/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-aiops/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-aiops/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-zw008-cicd-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-10T07:30:40.929Z","emptyReason":null},"readme":"Skill: cicd-aiops\n\nOwner: zw008\n\nSummary: Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection). Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance. Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances. Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).\n\nTags: latest:0.10.3\n\nVersion history:\n\nv0.10.3 | 2026-09-15T05:48:31.953Z | auto\n\n- Removed the file skill-card.md.\n- No functional or user-facing changes in this release.\n\nv0.10.2 | 2026-09-12T13:59:51.874Z | auto\n\n- Documentation updated in SKILL.md: clarified OpenClaw installation instructions and other minor improvements.\n- skill-card.md file removed.\n- No functional or code changes; this is a documentation and packaging update only.\n\nv0.10.1 | 2026-09-12T09:56:02.594Z | auto\n\n- Removed the redundant skill-card.md file for simpler packaging.\n- SKILL.md updated with quickstart for OpenClaw plugin usage.\n- No functional changes to tools or core capabilities.\n- Documentation now covers OpenClaw install instructions.\n\nv0.10.0 | 2026-09-12T00:44:40.656Z | auto\n\n- metadata requirements updated: now requires either \"cicd-aiops\" or \"uvx\" binary (anyBins), and \"CICD_AIOPS_CONFIG\" and \"CICD_AIOPS_MASTER_PASSWORD\" are marked as optional environment variables.\n- Previous file \"skill-card.md\" has been removed.\n- SKILL.md compatibility, description, and metadata have been revised accordingly; see the new metadata field and requirements.\n- No new user-facing commands or tool changes. No functional pipeline/tools change in this version.\n\nv0.9.0 | 2026-08-10T06:49:42.982Z | auto\n\n- Removed the file: skill-card.md\n- No changes to functionality or feature set; documentation and metadata remain unchanged.\n- Housekeeping update to project files only.\n\nv0.8.0 | 2026-08-10T03:57:53.740Z | auto\n\ncicd-aiops version 0.8.0\n\n- Updated documentation: revised references/capabilities.md.\n- Removed outdated or redundant file: skill-card.md.\n\nv0.7.0 | 2026-08-03T05:51:54.489Z | auto\n\n- Removed the file skill-card.md from the project.\n- No changes to functionality or user-facing features.\n- Documentation and available tools remain unchanged.\n\nv0.6.0 | 2026-08-02T09:38:03.082Z | auto\n\n- Removed the skill-card.md file.\n- No changes to user-facing features or functionality.\n\nv0.5.0 | 2026-07-21T15:31:37.555Z | auto\n\n- Removed the skill-card.md file.\n- No user-facing feature, interface, or behavior changes.\n- Documentation remains unchanged; functionality is unaffected.\n\nv0.4.0 | 2026-07-21T09:40:13.113Z | auto\n\ncicd-aiops 0.4.0\n\n- Refined governance and risk gating in documentation, clarifying confirmation and risk-labels for destructive actions.\n- Updated references and setup instructions for improved clarity and accuracy.\n- Removed redundant or outdated documentation files (e.g., skill-card.md).\n- Enhanced flagging of risk-tier and confirmation requirements for high-risk operations (notably delete_artifacts).\n- Minor descriptive and terminology adjustments across docs to better reflect current tool behaviors and restore accuracy.\n\nv0.3.0 | 2026-07-20T11:14:20.713Z | auto\n\n- Removed the skill-card.md file from the package.\n- No changes to user-facing functionality or features.\n- Documentation and skill configuration remain unchanged.\n\nv0.2.1 | 2026-07-20T03:09:01.497Z | auto\n\n- Removed the file: skill-card.md.\n- No changes to functionality; this is a documentation cleanup only.\n- All features, tools, and commands remain unchanged.\n\nv0.2.0 | 2026-07-19T03:50:26.500Z | auto\n\n**cicd-aiops 0.2.0**\n\n- Added agent governance documentation (references/agent-guardrails.md)\n- Introduced undo capabilities: new tools for undo listing and replay\n- Updated documentation for improved clarity and structure (SKILL.md, capabilities.md)\n- Increased total tools from 26 to 28, with enhanced detail on functionality and verification\n- Removed deprecated skill-card.md file\n\nv0.1.2 | 2026-07-17T08:00:04.370Z | auto\n\n- The sample file skill-card.md was removed.\n- No other user-facing changes or features were introduced in this version.\n\nv0.1.1 | 2026-07-17T06:05:45.244Z | auto\n\ncicd-aiops 0.1.1\n\n- No changes detected in this release.\n- Version bump only; documentation, features, and compatibility remain the same.\n\nv0.1.0 | 2026-07-17T05:58:16.537Z | auto\n\ncicd-aiops 0.1.0 (Initial Release)\n\n- Launches a preview skill for governed CI/CD operations on self-managed GitLab and Gitea servers.\n- Supports unified read and write actions: server, project, pipeline, runner, repository, artifact, RCA, and governance/audit operations.\n- Includes four flagship RCA tools (pipeline failure, runner health, storage bloat, stale work) delivering transparent heuristics.\n- All state-changing operations are audited, policy-checked, and risk-tiered using a bundled governance harness.\n- Credentials are encrypted at rest; never stored as plaintext.\n- Preview mode: mock-validated only; not run against live servers.\n\nArchive index:\n\nArchive v0.10.3: 7 files, 19274 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4930b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2691b), SKILL.md (16907b), _meta.json (130b)\n\nFile v0.10.3:SKILL.md\n\n---\nname: cicd-aiops\nslug: cicd-aiops\ndisplayName: \"CICD AIops\"\nsummary: \"Governed self-managed GitLab + Gitea CI/CD ops: pipelines, runners, artifacts, RCA. 28 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/CICD-AIops\ntags: [aiops, mcp, governance, cicd]\ndescription: >\n  Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection).\n  Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance.\n  Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances.\n  Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).\ninstaller:\n  kind: uv\n  package: cicd-aiops\nargument-hint: \"[a project path, pipeline/runner id, or describe your CI/CD task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"cicd-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CICD_AIOPS_CONFIG\",\"CICD_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/CICD-AIops\",\"emoji\":\"🔁\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via \"Authorization: token\"). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).\n  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double confirmation and is irreversible (priorState records the destroyed count/bytes). Reversible writes (pause_runner/resume_runner as an undo pair; update_branch_protection replaying prior settings) capture the real fetched before-state and record an inverse undo descriptor; retry_pipeline/cancel_pipeline record priorState (the pipeline's prior status) only.\n  Webhooks: none — no outbound network calls beyond the configured GitLab / Gitea REST API.\n  SSL: verify_ssl defaults to ON; the init wizard asks before disabling it for self-signed lab certs.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Verification status: mock-validated; no recorded end-to-end run against a live server yet, and the modelled REST paths are the largest verification debt. Both GitLab CE and Gitea are free/self-hostable (each runs from a container), so a home lab is the cheapest live check. See docs/VERIFICATION.md.\n---\n\n# CICD AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by GitLab Inc. or the Gitea project.** GitLab and Gitea are trademarks of their respective owners. Source at [github.com/AIops-tools/CICD-AIops](https://github.com/AIops-tools/CICD-AIops) under the MIT license.\n\nGoverned CI/CD operations — **28 MCP tools** across **self-managed GitLab** (REST\n`/api/v4/...`) and **self-hosted Gitea** (API `/api/v1/...`), every one wrapped with\nthe bundled `@governed_tool` harness: a local unified audit log under\n`~/.cicd-aiops/`, token/runaway budget guard, undo-token recording, and\ndescriptive risk tiers. A per-target `platform` field selects the API shape, so\nthe same tools work on both servers and one config can span a mixed estate. The\naccess token is stored **encrypted** (`~/.cicd-aiops/secrets.enc`, Fernet +\nscrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package\n> (`cicd_aiops.governance`) — no external skill-family dependency. Both\n> platforms are free/self-hostable, so a home lab is the cheapest live check;\n> verification status and the checklist are in `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Group | Tools | Count | R/W |\n|-------|-------|:-----:|:---:|\n| **Server** | server_version, current_user, cicd_overview | 3 | read |\n| **Projects** | list_projects, project_detail | 2 | read |\n| **Pipelines** | list_pipelines, pipeline_detail, pipeline_jobs, job_trace_tail | 4 | read |\n| **Runners** | list_runners, runner_detail | 2 | read |\n| **Repo surface** | list_merge_requests, list_branches, list_protected_branches, list_releases | 4 | read |\n| **Artifacts** | list_artifacts | 1 | read |\n| **Flagship analyses** | pipeline_failure_rca, runner_health_rca, artifact_storage_bloat_analysis, stale_work_audit | 4 | read |\n| **Writes** | retry_pipeline, cancel_pipeline, pause_runner, resume_runner, update_branch_protection | 5 | write (med) |\n| **Writes** | delete_artifacts | 1 | write (**high**) |\n| **Undo** | undo_list, undo_apply | 2 | read + replay |\n\nThe four flagship analyses are transparent heuristics that report their numbers,\nnever a black-box verdict: `pipeline_failure_rca` classifies each failed job from\nits failure_reason + trace-tail markers (test-failure / dependency-network /\nrunner-timeout / oom / script-error) with matched evidence; `runner_health_rca`\nflags offline/stale/paused runners, long-queued jobs, and per-tag saturation;\n`artifact_storage_bloat_analysis` ranks projects by repo + artifact bytes and\nestimates reclaimable bytes; `stale_work_audit` flags idle MRs/branches and\nprotection gaps.\n\n## Quick Install\n\n```bash\nuv tool install cicd-aiops\ncicd-aiops init       # wizard: pick platform (gitlab/gitea) + base URL + encrypted token\ncicd-aiops doctor     # version endpoint + token-scope probe per target\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/cicd-aiops\nopenclaw skills info cicd-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- Get a one-shot snapshot (`overview` / `server_version` / `current_user`)\n- Answer \"why is CI red?\" (`rca pipelines` / `pipeline_failure_rca`) → cause +\n  action per failed pipeline, with the trace evidence that drove the call\n- Find wedged capacity (`rca runners` / `runner_health_rca`) → offline/stale\n  runners, long-queued jobs, saturated tags\n- Reclaim disk (`rca storage` / `artifact_storage_bloat_analysis`) → ranked\n  projects + reclaimable bytes, feeding `delete_artifacts --dry-run`\n- Repo hygiene (`rca stale` / `stale_work_audit`) → idle MRs/branches,\n  unprotected default branch, force-push gaps\n- Safely act: `retry_pipeline` / `cancel_pipeline`, `pause_runner` /\n  `resume_runner` (undo pair), `update_branch_protection` (undo replays prior\n  settings), `delete_artifacts` (risk=high, dry-run + double confirm)\n\n**Do NOT use when** the target is not a GitLab/Gitea CI/CD server — route\nhypervisor, storage, backup, database, network, or OT/industrial work to the\nappropriate other AIops-tools skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Self-managed GitLab / Gitea CI/CD ops | **cicd-aiops** (this skill) |\n| Kubernetes deploy state (what the cluster is actually running) | **k8s-aiops** |\n| A non-CI/CD platform (hypervisor, storage, backup, database, network, OT edge) | the appropriate **other AIops-tools** skill |\n| GitLab.com / Gitea Cloud SaaS accounts | out of scope for this tool |\n\n## Common Workflows\n\nEach recipe starts from one of the four RCAs and ends in a governed write.\nEvery CLI write accepts `--dry-run` and otherwise double-confirms. Note that\nrunner administration and pipeline retry/cancel are **GitLab-only** — on a\nGitea target those tools raise a teaching error listing what is available.\n\n### 1. \"The nightly pipeline has been red for three days\"\n\n1. `cicd-aiops pipelines list dev/api --status failed -n 20` → the recent\n   failed pipelines, newest first.\n2. `cicd-aiops rca pipelines dev/api` → each failed job classified from its\n   `failure_reason` plus trace-tail markers: test-failure, dependency-network,\n   runner-timeout, OOM, or script-error, with the evidence and a suggested\n   action.\n3. `cicd-aiops pipelines jobs dev/api <pipeline-id>` → which stage and job the\n   classification came from.\n4. `cicd-aiops pipelines trace dev/api <job-id> -n 120` → the actual log tail,\n   so you confirm the classification instead of trusting it.\n5. Fix the cause. If the RCA said the failure was transient (dependency-network\n   or runner-timeout): `cicd-aiops pipelines retry dev/api <pipeline-id>\n   --dry-run`, then re-run for real (double confirm).\n6. `cicd-aiops rca pipelines dev/api` again to confirm the class of failure is\n   gone rather than merely quieter.\n\n**Failure branch**: if the RCA classifies the failures as **test-failure** or\n**script-error**, do not retry — the code is broken and a retry burns runner\nminutes to reach the same red. Retry is only honest for transient classes. If\nthe retry itself fails to submit on a Gitea target, that is the teaching error:\nretry/cancel have no Gitea API v1 equivalent, so re-run the job from the Gitea\nUI instead.\n\n### 2. \"Jobs are sitting in the queue and nothing is picking them up\"\n\n1. `cicd-aiops runners list --status offline` and `--status paused` → the\n   obvious suspects first.\n2. `cicd-aiops rca runners` → stale contact ages, long-queued jobs, and **which\n   tag is saturated** (queued jobs versus online runners carrying that tag).\n3. `cicd-aiops runners show <runner-id>` → the specific runner's tags, last\n   contact and status.\n4. If a needed runner was paused: `cicd-aiops runners resume <runner-id>\n   --dry-run`, then for real (reversible — an inverse `pause_runner` is\n   recorded).\n5. If a wedged runner is grabbing jobs and failing them: `cicd-aiops runners\n   pause <runner-id>` to take it out of rotation (reversible — inverse\n   `resume_runner` recorded).\n6. `cicd-aiops rca runners` again to confirm the queue is draining.\n\n**Failure branch**: if the RCA shows a **saturated tag** rather than a\ndown runner, resuming runners will not help — no online runner carries the tag\nthose jobs require, so you need to add or retag capacity. And if you paused a\nrunner and the queue got worse, `cicd-aiops undo apply <id>` resumes exactly\nthe runner you paused. Runner administration is GitLab-only; a Gitea target\nraises a teaching error here.\n\n### 3. \"The CI server is out of disk\"\n\n1. `cicd-aiops rca storage --old-days 30` → projects ranked by repo + artifact\n   bytes with a reclaimable estimate at that age threshold.\n2. `cicd-aiops artifacts list dev/api` → the actual artifact files, their sizes\n   and their expiry, so you see what \"reclaimable\" really refers to.\n3. `cicd-aiops projects --limit 50` → cross-check that the top consumer is the\n   project you expect.\n4. `cicd-aiops artifacts delete dev/api --older-than-days 30 --dry-run` →\n   shows the scope, deletes nothing.\n5. Re-run without `--dry-run`: double confirm, **high** risk. Optionally set\n   `CICD_AUDIT_APPROVED_BY` + `CICD_AUDIT_RATIONALE` to annotate who/why on the\n   audit row. This is **irreversible** — priorState records the destroyed count\n   and bytes for the audit trail, but there is no undo.\n6. `cicd-aiops rca storage` again to confirm the reclaimed bytes landed.\n\n**Failure branch**: never run `artifacts delete` with `--older-than-days 0` as\na first move — 0 means **ALL** artifacts, including the ones a release or a\nrunning deploy depends on. If the dry-run scope reads \"ALL\" and you did not\nintend that, stop and set an age. Since there is no undo for this operation,\nthe dry-run is the only safety net you get; if the bloat is mostly **repo**\nbytes rather than artifact bytes, deleting artifacts will not help at all.\n\n### 4. \"Tighten repo hygiene before the release freeze\"\n\n1. `cicd-aiops rca stale dev/api --mr-days 14 --branch-days 60` → stale open\n   merge requests, idle branches, and **protection gaps** such as an\n   unprotected default branch or force-push left allowed.\n2. Confirm the current state via MCP `list_protected_branches` and\n   `list_branches` for the project.\n3. MCP `list_merge_requests` → the stale MRs the audit named, so you can close\n   or revive them with their owners rather than in bulk.\n4. Close the protection gap with MCP `update_branch_protection` (e.g.\n   `allow_force_push=False` on the default branch) — it fetches and captures\n   the prior settings and records an undo that replays them exactly.\n5. `cicd-aiops undo list` → confirm the protection change is reversible.\n6. `cicd-aiops rca stale dev/api` again to confirm the gap closed.\n\n**Failure branch**: if tightening protection blocks a legitimate workflow — a\nrelease automation that force-pushes tags, say — `cicd-aiops undo apply <id>`\nrestores the exact prior protection settings rather than a guessed default.\nFix the automation before re-applying, and do not disable protection\nfleet-wide to unblock one job.\n\n## Governance & 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 token you connect it with (a GitLab/Gitea access token without write\nscope — writes then fail at the server). There is no read-only switch, policy\nfile, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.cicd-aiops/audit.db` (relocatable via `CICD_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CICD_AUDIT_APPROVED_BY` / `CICD_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: the same call looped in a tight window trips a circuit breaker. Disable with `CICD_RUNAWAY_MAX=0`.\n- Destructive writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI. `delete_artifacts` is irreversible (priorState records the destroyed count/bytes; audit only).\n- Reversible writes fetch the real before-state and record an inverse descriptor (pause_runner↔resume_runner, update_branch_protection→prior settings); irreversible ops (retry_pipeline, cancel_pipeline, delete_artifacts) record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + platform + API-path reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n- `references/agent-guardrails.md` — which guardrails the harness enforces, the\n  GitLab-only vs Gitea platform asymmetry, and a ready-made system prompt for\n  smaller / local models\n\nFile v0.10.3:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"cicd-aiops\",\n  \"version\": \"0.10.3\",\n  \"publishedAt\": 1789451311953\n}\n\nFile v0.10.3:references/agent-guardrails.md\n\n# Agent guardrails — running cicd-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 token you connect with.** Give it a GitLab/Gitea access token without\n  write scope. A write then fails at the server, which is the only place the\n  permission actually lives — no skill-side flag can be argued around by a\n  model, but a token without the scope cannot be.\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| \"Log everything you do, over both MCP and the CLI\" | Every call is audited to `~/.cicd-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. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | A field the server did not return comes back as `null`, never as `\"\"`. A pipeline with no `ref`, a job with no `startedAt` or `failureReason`, a runner that has never reported `contactedAt` — all stay `null`, and the key is always present. |\n| \"Tell me if the output was cut off\" | Every listing returns `{\"<items>\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is **measured** (one extra row is fetched), never guessed from a full page. `job_trace_tail` adds `charsTruncated` for the byte ceiling. |\n| \"Tell me if a number is unknown rather than zero\" | Storage numbers a platform does not report come back as `null` with `artifactsBytesKnown: false`, and `artifact_storage_bloat_analysis` counts them in `artifactBytesUnavailable`. `cicd_overview` reports `runnersSupported`. |\n| \"Confirm before anything destructive\" | Destructive operations require a `--dry-run`-able preview + double confirmation at the CLI. |\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\n## Platform asymmetry — a teaching error is an ANSWER, not a failure\n\nThis is the one thing worth spending prompt budget on, because it is specific\nto this tool. `cicd-aiops` speaks to **two different servers** — self-managed\nGitLab (REST v4) and self-hosted Gitea (API v1) — and they do not expose the\nsame surfaces. Where a platform has no equivalent API, the resource is\ndeliberately **not mapped**, and the call raises a teaching error naming the\nresources that *do* exist on that platform.\n\nThat error means \"wrong platform for this question\". It is a correct, final\nanswer. A model that treats it as a transient tool failure will retry the same\ncall, or report \"the CI/CD server is unreachable\" — both wrong.\n\n**GitLab only** (a Gitea target raises the teaching error):\n\n| Tool | Why |\n|---|---|\n| `list_runners`, `runner_detail` | Gitea API v1 has no runner-administration endpoint |\n| `pause_runner`, `resume_runner` | same — no runner update endpoint |\n| `retry_pipeline`, `cancel_pipeline` | Gitea Actions exposes no run retry/cancel endpoint |\n| `delete_artifacts` | Gitea exposes no artifact-deletion endpoint (list only) |\n| `runner_health_rca` **when it pulls live** | it pulls the runner fleet, so it inherits the above. Injecting `runners=[...]` makes it pure analysis and it works anywhere |\n\nEverything else — `server_version`, `current_user`, `cicd_overview`,\n`list_projects`, `project_detail`, `list_pipelines`, `pipeline_detail`,\n`pipeline_jobs`, `job_trace_tail`, `list_artifacts`, `list_merge_requests`,\n`list_branches`, `list_protected_branches`, `list_releases`,\n`update_branch_protection`, and the other three flagship analyses — works on\nboth platforms.\n\nCheck `cicd_overview`'s `platform` field first if you do not know which server\nyou are pointed at. When a tool is GitLab-only and the target is Gitea, do not\nretry: answer from the pipeline / job / repo surface instead, and say plainly\nthat this platform has no runner (or retry/cancel, or artifact-deletion) API.\n\n### Worse than a teaching error: a surface that returns *nothing* instead of refusing\n\nA teaching error is loud. These two are quiet, and they used to be\nindistinguishable from a real measurement. They are now labelled in the\npayload — **read the label, do not read the number alone**:\n\n| Where | The quiet gap | The label to read |\n|---|---|---|\n| `cicd_overview` on Gitea | `runnersTotal` / `runnersOnline` are `null` because the platform has no runner API — **not** because there are no runners | `runnersSupported: false`. Never report \"0 runners\" from this. |\n| `list_projects` / `project_detail` / `artifact_storage_bloat_analysis` on Gitea | Gitea reports a repo `size` but **no artifact or total-storage statistics**, so `artifactsBytes` and `storageBytes` are `null`. A storage RCA against a Gitea target ranks projects on repo bytes alone and finds **zero** reclaimable artifact bytes — which is a gap in the data, not a clean result | `artifactsBytesKnown: false` per project, `artifactBytesUnavailable: N` on the analysis |\n\nOne more bounded read worth naming: on GitLab, `list_artifacts` has no single\nartifacts endpoint, so the inventory is assembled by walking recent jobs. When\n`jobScanTruncated` is `true`, older jobs' artifacts are **not** in the result —\n`totalBytes` is then a lower bound, and `delete_artifacts` says so too\n(`priorState.complete: false`).\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 self-managed GitLab / Gitea CI/CD servers through the cicd-aiops\nMCP tools.\n\nTOOL USE\n- Before answering any question about the current CI/CD environment, 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- Some tools exist only on GitLab (runner list/detail/pause/resume, pipeline\n  retry/cancel, artifact deletion). On a Gitea target they return a teaching\n  error listing what IS available. That is a final answer about the platform,\n  not a transient failure: do not retry it, do not call it broken. Say the\n  platform has no such API and answer from another surface.\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. On the analyses \"truncated\" is a per-list\n  object — check each entry.\n- A null field means the server did not return that value. Report it as \"not\n  available\" — never infer it, and never report it as zero. In particular:\n  runnersSupported=false means \"this platform has no runner API\", and\n  artifactsBytesKnown=false means artifact storage was not measured.\n- A job trace is only the TAIL of the log. When \"truncated\" is true the first\n  error may be above the window — raise tail_lines before naming a root cause.\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  status strings, branch names, or IDs.\n- Work RCA findings in the order returned and cite the measured number each\n  finding carries (\"evidence\", \"cause\", byte counts, queue seconds).\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, storage, or reliability problem unless a tool\n  result supports it.\n- Do not add generic CI/CD advice that does not follow from the tool output.\n- Do not confuse a project path with a pipeline id, a pipeline id with a job\n  id, or a runner id with either. Job ids come from pipeline_jobs; pipeline ids\n  come from list_pipelines; runner ids come from list_runners.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the token's scope\nonly when you trust the setup — `delete_artifacts` is irreversible, and a\nmistaken pipeline retry or cancel burns runner minutes:\n\n```bash\n# e.g. use a GitLab/Gitea access token without write scope. Then:\ncicd-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 CICD_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CICD_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\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 the four RCA tools\n  (`pipeline_failure_rca`, `runner_health_rca`,\n  `artifact_storage_bloat_analysis`, `stale_work_audit`) — each does the\n  multi-step correlation inside one call, so the model does not have to chain\n  `list_pipelines` → `pipeline_jobs` → `job_trace_tail` and keep three\n  different id types straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions and use `--limit` / `tail_lines` deliberately rather than pulling\n  whole inventories or long traces.\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/CICD-AIops](https://github.com/AIops-tools/CICD-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.10.3:references/capabilities.md\n\n# cicd-aiops — capabilities reference\n\n28 governed MCP tools over two platforms (16 reads + 4 analyses + 6 writes +\n`undo_list`/`undo_apply`). Every tool takes an optional\n`target` (a name from `~/.cicd-aiops/config.yaml`); writes also take\n`dry_run: bool`.\n\n## Platforms\n\n| Platform | API | Auth | Project addressing |\n|---|---|---|---|\n| `gitlab` | REST v4 (`/api/v4/...`) | `PRIVATE-TOKEN: <token>` | numeric id or URL-encoded full path (`group%2Fproject`) |\n| `gitea` | API v1 (`/api/v1/...`) | `Authorization: token <token>` | `owner/repo` (two path segments) |\n\nSelf-managed/self-hosted instances only. Where Gitea lacks a surface, the\nplatform registry raises a teaching `KeyError` naming the resources that ARE\navailable: runner administration, pipeline retry/cancel, and artifact deletion\nare GitLab-only in v0.1.\n\n## Reads (16)\n\n| Tool | What it returns | GitLab path | Gitea path |\n|---|---|---|---|\n| `server_version` | version + revision | `/api/v4/version` | `/api/v1/version` |\n| `current_user` | token identity (scope probe) | `/api/v4/user` | `/api/v1/user` |\n| `cicd_overview` | version + identity + projects + runners | (composite) | (composite) |\n| `list_projects` | projects w/ storage bytes | `/api/v4/projects?statistics=true` | `/api/v1/repos/search` |\n| `project_detail` | one project incl. sizes | `/api/v4/projects/{p}` | `/api/v1/repos/{owner}/{repo}` |\n| `list_pipelines` | recent pipelines/runs | `/api/v4/projects/{p}/pipelines` | **unsupported** — Gitea API v1 has no run-level resource |\n| `pipeline_detail` | one pipeline/run | `.../pipelines/{id}` | **unsupported** (same reason) |\n| `pipeline_jobs` | jobs + failure_reason | `.../pipelines/{id}/jobs` | **unsupported**; the per-job listing is `/actions/tasks` |\n| `job_trace_tail` | last N log lines | `.../jobs/{id}/trace` | `.../actions/jobs/{id}/logs` |\n| `list_runners` | fleet, offline first | `/api/v4/runners/all` | — teaching error |\n| `runner_detail` | contacted_at, tags, paused | `/api/v4/runners/{id}` | — teaching error |\n| `list_merge_requests` | MRs / PRs | `.../merge_requests` | `.../pulls` |\n| `list_branches` | branches + last-commit date | `.../repository/branches` | `.../branches` |\n| `list_protected_branches` | protection rules + force-push flags | `.../protected_branches` | `.../branch_protections` |\n| `list_releases` | releases newest first | `.../releases` | `.../releases` |\n| `list_artifacts` | files, sizes, expiry, expired-but-kept | via `.../jobs` artifacts | `.../actions/artifacts` |\n\n## Flagship analyses (4, read-only, thresholds are parameters)\n\n| Tool | Flags | Key thresholds |\n|---|---|---|\n| `pipeline_failure_rca` | each failed job classified: test-failure / dependency-network / runner-timeout / oom / script-error, with matched evidence + action | `limit` (pipelines), `tail_lines` |\n| `runner_health_rca` | offline / stale / paused runners; long-queued jobs; saturated tags | `stale_contact_min` (30), `queue_sec` (300), `saturation_ratio` (2.0) |\n| `artifact_storage_bloat_analysis` | projects ranked by repo+artifact bytes; expired-but-kept; reclaimable estimate | `old_artifact_days` (30) |\n| `stale_work_audit` | idle open MRs; idle branches; unprotected default branch; force-push allowed | `stale_mr_days` (14), `stale_branch_days` (90) |\n\nAll four accept injected rows for pure/offline analysis, or pull live from a\ntarget. Classification order in `pipeline_failure_rca` is most-specific first:\nOOM > timeout > network > test > script; GitLab `failure_reason` values\n(`stuck_or_timeout_failure`, `runner_system_failure`, …) classify without a\ntrace.\n\n## Writes (6, governed, all with `dry_run`)\n\n| Tool | Risk | Prior state captured | Undo |\n|---|---|---|---|\n| `retry_pipeline` | medium | pipeline status | none (a retry is a new run) |\n| `cancel_pipeline` | medium | pipeline status | none (irreversible) |\n| `pause_runner` | medium | runner `paused` flag | `resume_runner` (skipped if it was already paused) |\n| `resume_runner` | medium | runner `paused` flag | `pause_runner` (skipped if it was not paused) |\n| `delete_artifacts` | **high** | artifact count + bytes destroyed | none (irreversible) |\n| `update_branch_protection` | medium | prior protection settings (or \"unprotected\") | replays this tool with the prior settings |\n\n`delete_artifacts(older_than_days=N)` deletes per-job only artifacts created\nbefore the cutoff; `0` uses GitLab's bulk-delete of eligible artifacts.\n\n## Safety plumbing\n\n- Every substituted URL path value is percent-encoded (`quote(..., safe=\"\")`);\n  Gitea's `owner/repo` keeps its `/` but each piece is encoded and empty /\n  `.` / `..` pieces are rejected (path-traversal defense).\n- All server-returned text passes an injection-safe normaliser (bounded string\n  length, capped nesting depth) before an agent sees it.\n- Non-2xx responses become teaching errors (what failed + what to check);\n  plain-text trace endpoints pass through as text.\n\nFile v0.10.3:references/cli-reference.md\n\n# cicd-aiops — CLI reference\n\nAll commands accept `--target/-t <name>` (default: the first target in\nconfig.yaml). Writes accept `--dry-run` and double-confirm before executing;\nconfirmed writes run through the same governed path as the MCP tools (audited).\n\n## Setup / health\n\n```bash\ncicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)\ncicd-aiops doctor               # config + secrets + connectivity + token-scope probe\ncicd-aiops doctor --skip-auth   # config/secrets checks only\ncicd-aiops overview             # version, identity, projects, runners\ncicd-aiops projects [--search x] [--limit N]\n```\n\n## Pipelines\n\n```bash\ncicd-aiops pipelines list <project> [--status failed] [--limit N]\ncicd-aiops pipelines show <project> <pipeline>\ncicd-aiops pipelines jobs <project> <pipeline>\ncicd-aiops pipelines trace <project> <job> [--lines 60]\ncicd-aiops pipelines retry <project> <pipeline> [--dry-run]    # governed write\ncicd-aiops pipelines cancel <project> <pipeline> [--dry-run]   # governed write\n```\n\n## Runners\n\n```bash\ncicd-aiops runners list [--status offline]\ncicd-aiops runners show <runner>\ncicd-aiops runners pause <runner> [--dry-run]     # governed write, undo-recorded\ncicd-aiops runners resume <runner> [--dry-run]    # governed write, undo-recorded\n```\n\n## Artifacts\n\n```bash\ncicd-aiops artifacts list <project>\ncicd-aiops artifacts delete <project> [--older-than-days 30] [--dry-run]\n# risk=high: requires CICD_AUDIT_APPROVED_BY (+ CICD_AUDIT_RATIONALE)\n```\n\n## Flagship RCAs\n\n```bash\ncicd-aiops rca pipelines <project> [--limit 10]   # classify failed pipelines\ncicd-aiops rca runners                            # offline/stale/saturation\ncicd-aiops rca storage [--old-days 30]            # bloat + reclaimable bytes\ncicd-aiops rca stale <project> [--mr-days 14] [--branch-days 90]\n```\n\n## Secrets\n\n```bash\ncicd-aiops secret set <target>      # store a token (encrypted)\ncicd-aiops secret list              # names only, never values\ncicd-aiops secret remove <target>\ncicd-aiops secret migrate           # legacy .env → encrypted store\n```\n\n## MCP\n\n```bash\ncicd-aiops mcp                      # start the MCP server (stdio)\n```\n\n## Environment variables\n\n| Var | Purpose |\n|---|---|\n| `CICD_AIOPS_HOME` | relocate config/audit/undo/secrets (default `~/.cicd-aiops`) |\n| `CICD_AIOPS_CONFIG` | explicit config.yaml path for the MCP server |\n| `CICD_AIOPS_MASTER_PASSWORD` | unlock secrets.enc non-interactively |\n| `CICD_AUDIT_APPROVED_BY` / `CICD_AUDIT_RATIONALE` | optional audit annotations (who/why) — recorded, never required |\n| `CICD_MAX_TOOL_CALLS` / `CICD_MAX_TOOL_SECONDS` | budget caps |\n| `CICD_RUNAWAY_MAX` / `CICD_RUNAWAY_WINDOW_SEC` | runaway breaker |\n| `CICD_<TARGET>_SECRET` | legacy plaintext token fallback (deprecated) |\n\nFile v0.10.3:references/setup-guide.md\n\n# cicd-aiops — setup guide\n\n## 1. Install\n\n```bash\nuv tool install cicd-aiops        # or: pip install cicd-aiops\n```\n\nRequires Python >= 3.11.\n\n## 2. Create a token on the server\n\n**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or\nproject) access token with the `api` scope. Runner administration\n(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an\nadmin-capable account.\n\n**Gitea (self-hosted)** — Settings → Applications → Generate new token. Grant\nread scopes for repository/issue and write where you want\n`update_branch_protection` to work.\n\nLeast privilege applies: a read-only token still powers every read and all\nfour RCAs; only the six write tools need write scopes.\n\n## 3. Onboard\n\n```bash\ncicd-aiops init\n```\n\nThe wizard asks for:\n\n1. **Master password** — encrypts `~/.cicd-aiops/secrets.enc` (Fernet +\n   scrypt). For MCP / non-interactive use export\n   `CICD_AIOPS_MASTER_PASSWORD=...`.\n2. **Target name** (e.g. `gl1`), **platform** (`gitlab` / `gitea`), and\n   **base URL** (e.g. `https://git.example.com` — scheme optional, added\n   automatically).\n3. **TLS verification** — defaults to **Yes**; answer No only for\n   self-signed lab certs.\n4. **Access token** — prompted hidden, stored encrypted, never in\n   config.yaml.\n\nResulting `~/.cicd-aiops/config.yaml`:\n\n```yaml\ntargets:\n  - name: gl1\n    platform: gitlab\n    base_url: https://git.example.com\n    verify_ssl: true\n  - name: gt1\n    platform: gitea\n    base_url: https://gitea.example.com\n    verify_ssl: true\n```\n\n## 4. Verify\n\n```bash\ncicd-aiops doctor\n```\n\nChecks per target: config present, encrypted store + token present, the\nserver's **version endpoint** answers, and a **token-scope probe**\n(`current_user`) confirms the token authenticates. A reachable server with a\ndud token is reported as unhealthy.\n\n## 5. MCP client config\n\n```json\n{\n  \"mcpServers\": {\n    \"cicd-aiops\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"cicd-aiops\", \"cicd-aiops-mcp\"],\n      \"env\": {\n        \"CICD_AIOPS_MASTER_PASSWORD\": \"your-master-password\"\n      }\n    }\n  }\n}\n```\n\nMCP clients do not source your shell profile — set\n`CICD_AIOPS_MASTER_PASSWORD` in the `env` block.\n\n## Audit-annotation env vars (optional)\n\nThe skill does not decide whether a write is permitted — that is the agent's\njudgement or the connecting token's scope. If you want the audit trail to record\n*who* ran a destructive op and *why*, set these; they are recorded on the row,\nnever required, and gate nothing:\n\n```bash\nexport CICD_AUDIT_APPROVED_BY='you@example.com'\nexport CICD_AUDIT_RATIONALE='why this destructive op is justified'\n```\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---|---|\n| `401/403` in doctor | token expired or missing `api` scope — reissue and `cicd-aiops secret set <target>` |\n| `Could not reach ...` | check `base_url`, VPN/network path, and that the API is enabled |\n| self-signed cert errors | re-run `init` and answer No to TLS verify (lab only) |\n| `Resource ... not available on platform 'gitea'` | expected: runner admin / pipeline retry / artifact delete are GitLab surfaces in v0.1 |\n| a write fails with `403` | the token lacks the write scope — reissue with write access (or keep it read-only by design) |\n\nFile v0.10.3:skill-card.md\n\n## Description:\n\nCICD AIops helps agents inspect and operate self-managed GitLab and self-hosted Gitea CI/CD servers, including pipelines, jobs, runners, artifacts, branch protection, releases, root-cause analyses, and governed write actions.\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, DevOps engineers, and CI/CD operators use this skill to query self-managed GitLab or self-hosted Gitea environments, investigate failing pipelines, runner capacity, artifact storage, and stale repository work, and perform controlled maintenance actions when their token permits it.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can perform write-capable GitLab or Gitea operations when connected with a token that has write or admin scopes.\n\nMitigation: Use a dedicated least-privilege token by default, keep observe-only sessions on read-only credentials, and enable write or admin scopes only for deliberate maintenance sessions.\n\nRisk: The master password and local audit database may expose sensitive CI/CD access or operational history if handled carelessly.\n\nMitigation: Avoid storing the master password in plaintext MCP configuration, protect the local configuration directory, and assume the audit database may contain sensitive CI/CD data.\n\nRisk: Destructive maintenance actions such as artifact deletion or branch protection changes can remove data or disrupt workflows.\n\nMitigation: Review dry-run output before destructive actions, use explicit maintenance intent, and preserve undo or audit context where the tool provides it.\n\n## Reference(s):\n\n- [CICD-AIops GitHub repository](https://github.com/AIops-tools/CICD-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup 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 CI/CD findings]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include API-result summaries, RCA findings, dry-run recommendations, audit context, and undo guidance.]\n\n## Skill Version(s):\n\n0.10.3 (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.10.2: 7 files, 19392 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4930b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2935b), SKILL.md (16907b), _meta.json (130b)\n\nFile v0.10.2:SKILL.md\n\n---\nname: cicd-aiops\nslug: cicd-aiops\ndisplayName: \"CICD AIops\"\nsummary: \"Governed self-managed GitLab + Gitea CI/CD ops: pipelines, runners, artifacts, RCA. 28 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/CICD-AIops\ntags: [aiops, mcp, governance, cicd]\ndescription: >\n  Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection).\n  Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance.\n  Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances.\n  Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).\ninstaller:\n  kind: uv\n  package: cicd-aiops\nargument-hint: \"[a project path, pipeline/runner id, or describe your CI/CD task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"cicd-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CICD_AIOPS_CONFIG\",\"CICD_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/CICD-AIops\",\"emoji\":\"🔁\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via \"Authorization: token\"). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).\n  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double confirmation and is irreversible (priorState records the destroyed count/bytes). Reversible writes (pause_runner/resume_runner as an undo pair; update_branch_protection replaying prior settings) capture the real fetched before-state and record an inverse undo descriptor; retry_pipeline/cancel_pipeline record priorState (the pipeline's prior status) only.\n  Webhooks: none — no outbound network calls beyond the configured GitLab / Gitea REST API.\n  SSL: verify_ssl defaults to ON; the init wizard asks before disabling it for self-signed lab certs.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Verification status: mock-validated; no recorded end-to-end run against a live server yet, and the modelled REST paths are the largest verification debt. Both GitLab CE and Gitea are free/self-hostable (each runs from a container), so a home lab is the cheapest live check. See docs/VERIFICATION.md.\n---\n\n# CICD AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by GitLab Inc. or the Gitea project.** GitLab and Gitea are trademarks of their respective owners. Source at [github.com/AIops-tools/CICD-AIops](https://github.com/AIops-tools/CICD-AIops) under the MIT license.\n\nGoverned CI/CD operations — **28 MCP tools** across **self-managed GitLab** (REST\n`/api/v4/...`) and **self-hosted Gitea** (API `/api/v1/...`), every one wrapped with\nthe bundled `@governed_tool` harness: a local unified audit log under\n`~/.cicd-aiops/`, token/runaway budget guard, undo-token recording, and\ndescriptive risk tiers. A per-target `platform` field selects the API shape, so\nthe same tools work on both servers and one config can span a mixed estate. The\naccess token is stored **encrypted** (`~/.cicd-aiops/secrets.enc`, Fernet +\nscrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package\n> (`cicd_aiops.governance`) — no external skill-family dependency. Both\n> platforms are free/self-hostable, so a home lab is the cheapest live check;\n> verification status and the checklist are in `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Group | Tools | Count | R/W |\n|-------|-------|:-----:|:---:|\n| **Server** | server_version, current_user, cicd_overview | 3 | read |\n| **Projects** | list_projects, project_detail | 2 | read |\n| **Pipelines** | list_pipelines, pipeline_detail, pipeline_jobs, job_trace_tail | 4 | read |\n| **Runners** | list_runners, runner_detail | 2 | read |\n| **Repo surface** | list_merge_requests, list_branches, list_protected_branches, list_releases | 4 | read |\n| **Artifacts** | list_artifacts | 1 | read |\n| **Flagship analyses** | pipeline_failure_rca, runner_health_rca, artifact_storage_bloat_analysis, stale_work_audit | 4 | read |\n| **Writes** | retry_pipeline, cancel_pipeline, pause_runner, resume_runner, update_branch_protection | 5 | write (med) |\n| **Writes** | delete_artifacts | 1 | write (**high**) |\n| **Undo** | undo_list, undo_apply | 2 | read + replay |\n\nThe four flagship analyses are transparent heuristics that report their numbers,\nnever a black-box verdict: `pipeline_failure_rca` classifies each failed job from\nits failure_reason + trace-tail markers (test-failure / dependency-network /\nrunner-timeout / oom / script-error) with matched evidence; `runner_health_rca`\nflags offline/stale/paused runners, long-queued jobs, and per-tag saturation;\n`artifact_storage_bloat_analysis` ranks projects by repo + artifact bytes and\nestimates reclaimable bytes; `stale_work_audit` flags idle MRs/branches and\nprotection gaps.\n\n## Quick Install\n\n```bash\nuv tool install cicd-aiops\ncicd-aiops init       # wizard: pick platform (gitlab/gitea) + base URL + encrypted token\ncicd-aiops doctor     # version endpoint + token-scope probe per target\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@zw008/cicd-aiops\nopenclaw skills info cicd-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- Get a one-shot snapshot (`overview` / `server_version` / `current_user`)\n- Answer \"why is CI red?\" (`rca pipelines` / `pipeline_failure_rca`) → cause +\n  action per failed pipeline, with the trace evidence that drove the call\n- Find wedged capacity (`rca runners` / `runner_health_rca`) → offline/stale\n  runners, long-queued jobs, saturated tags\n- Reclaim disk (`rca storage` / `artifact_storage_bloat_analysis`) → ranked\n  projects + reclaimable bytes, feeding `delete_artifacts --dry-run`\n- Repo hygiene (`rca stale` / `stale_work_audit`) → idle MRs/branches,\n  unprotected default branch, force-push gaps\n- Safely act: `retry_pipeline` / `cancel_pipeline`, `pause_runner` /\n  `resume_runner` (undo pair), `update_branch_protection` (undo replays prior\n  settings), `delete_artifacts` (risk=high, dry-run + double confirm)\n\n**Do NOT use when** the target is not a GitLab/Gitea CI/CD server — route\nhypervisor, storage, backup, database, network, or OT/industrial work to the\nappropriate other AIops-tools skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Self-managed GitLab / Gitea CI/CD ops | **cicd-aiops** (this skill) |\n| Kubernetes deploy state (what the cluster is actually running) | **k8s-aiops** |\n| A non-CI/CD platform (hypervisor, storage, backup, database, network, OT edge) | the appropriate **other AIops-tools** skill |\n| GitLab.com / Gitea Cloud SaaS accounts | out of scope for this tool |\n\n## Common Workflows\n\nEach recipe starts from one of the four RCAs and ends in a governed write.\nEvery CLI write accepts `--dry-run` and otherwise double-confirms. Note that\nrunner administration and pipeline retry/cancel are **GitLab-only** — on a\nGitea target those tools raise a teaching error listing what is available.\n\n### 1. \"The nightly pipeline has been red for three days\"\n\n1. `cicd-aiops pipelines list dev/api --status failed -n 20` → the recent\n   failed pipelines, newest first.\n2. `cicd-aiops rca pipelines dev/api` → each failed job classified from its\n   `failure_reason` plus trace-tail markers: test-failure, dependency-network,\n   runner-timeout, OOM, or script-error, with the evidence and a suggested\n   action.\n3. `cicd-aiops pipelines jobs dev/api <pipeline-id>` → which stage and job the\n   classification came from.\n4. `cicd-aiops pipelines trace dev/api <job-id> -n 120` → the actual log tail,\n   so you confirm the classification instead of trusting it.\n5. Fix the cause. If the RCA said the failure was transient (dependency-network\n   or runner-timeout): `cicd-aiops pipelines retry dev/api <pipeline-id>\n   --dry-run`, then re-run for real (double confirm).\n6. `cicd-aiops rca pipelines dev/api` again to confirm the class of failure is\n   gone rather than merely quieter.\n\n**Failure branch**: if the RCA classifies the failures as **test-failure** or\n**script-error**, do not retry — the code is broken and a retry burns runner\nminutes to reach the same red. Retry is only honest for transient classes. If\nthe retry itself fails to submit on a Gitea target, that is the teaching error:\nretry/cancel have no Gitea API v1 equivalent, so re-run the job from the Gitea\nUI instead.\n\n### 2. \"Jobs are sitting in the queue and nothing is picking them up\"\n\n1. `cicd-aiops runners list --status offline` and `--status paused` → the\n   obvious suspects first.\n2. `cicd-aiops rca runners` → stale contact ages, long-queued jobs, and **which\n   tag is saturated** (queued jobs versus online runners carrying that tag).\n3. `cicd-aiops runners show <runner-id>` → the specific runner's tags, last\n   contact and status.\n4. If a needed runner was paused: `cicd-aiops runners resume <runner-id>\n   --dry-run`, then for real (reversible — an inverse `pause_runner` is\n   recorded).\n5. If a wedged runner is grabbing jobs and failing them: `cicd-aiops runners\n   pause <runner-id>` to take it out of rotation (reversible — inverse\n   `resume_runner` recorded).\n6. `cicd-aiops rca runners` again to confirm the queue is draining.\n\n**Failure branch**: if the RCA shows a **saturated tag** rather than a\ndown runner, resuming runners will not help — no online runner carries the tag\nthose jobs require, so you need to add or retag capacity. And if you paused a\nrunner and the queue got worse, `cicd-aiops undo apply <id>` resumes exactly\nthe runner you paused. Runner administration is GitLab-only; a Gitea target\nraises a teaching error here.\n\n### 3. \"The CI server is out of disk\"\n\n1. `cicd-aiops rca storage --old-days 30` → projects ranked by repo + artifact\n   bytes with a reclaimable estimate at that age threshold.\n2. `cicd-aiops artifacts list dev/api` → the actual artifact files, their sizes\n   and their expiry, so you see what \"reclaimable\" really refers to.\n3. `cicd-aiops projects --limit 50` → cross-check that the top consumer is the\n   project you expect.\n4. `cicd-aiops artifacts delete dev/api --older-than-days 30 --dry-run` →\n   shows the scope, deletes nothing.\n5. Re-run without `--dry-run`: double confirm, **high** risk. Optionally set\n   `CICD_AUDIT_APPROVED_BY` + `CICD_AUDIT_RATIONALE` to annotate who/why on the\n   audit row. This is **irreversible** — priorState records the destroyed count\n   and bytes for the audit trail, but there is no undo.\n6. `cicd-aiops rca storage` again to confirm the reclaimed bytes landed.\n\n**Failure branch**: never run `artifacts delete` with `--older-than-days 0` as\na first move — 0 means **ALL** artifacts, including the ones a release or a\nrunning deploy depends on. If the dry-run scope reads \"ALL\" and you did not\nintend that, stop and set an age. Since there is no undo for this operation,\nthe dry-run is the only safety net you get; if the bloat is mostly **repo**\nbytes rather than artifact bytes, deleting artifacts will not help at all.\n\n### 4. \"Tighten repo hygiene before the release freeze\"\n\n1. `cicd-aiops rca stale dev/api --mr-days 14 --branch-days 60` → stale open\n   merge requests, idle branches, and **protection gaps** such as an\n   unprotected default branch or force-push left allowed.\n2. Confirm the current state via MCP `list_protected_branches` and\n   `list_branches` for the project.\n3. MCP `list_merge_requests` → the stale MRs the audit named, so you can close\n   or revive them with their owners rather than in bulk.\n4. Close the protection gap with MCP `update_branch_protection` (e.g.\n   `allow_force_push=False` on the default branch) — it fetches and captures\n   the prior settings and records an undo that replays them exactly.\n5. `cicd-aiops undo list` → confirm the protection change is reversible.\n6. `cicd-aiops rca stale dev/api` again to confirm the gap closed.\n\n**Failure branch**: if tightening protection blocks a legitimate workflow — a\nrelease automation that force-pushes tags, say — `cicd-aiops undo apply <id>`\nrestores the exact prior protection settings rather than a guessed default.\nFix the automation before re-applying, and do not disable protection\nfleet-wide to unblock one job.\n\n## Governance & 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 token you connect it with (a GitLab/Gitea access token without write\nscope — writes then fail at the server). There is no read-only switch, policy\nfile, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.cicd-aiops/audit.db` (relocatable via `CICD_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CICD_AUDIT_APPROVED_BY` / `CICD_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: the same call looped in a tight window trips a circuit breaker. Disable with `CICD_RUNAWAY_MAX=0`.\n- Destructive writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI. `delete_artifacts` is irreversible (priorState records the destroyed count/bytes; audit only).\n- Reversible writes fetch the real before-state and record an inverse descriptor (pause_runner↔resume_runner, update_branch_protection→prior settings); irreversible ops (retry_pipeline, cancel_pipeline, delete_artifacts) record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + platform + API-path reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n- `references/agent-guardrails.md` — which guardrails the harness enforces, the\n  GitLab-only vs Gitea platform asymmetry, and a ready-made system prompt for\n  smaller / local models\n\nFile v0.10.2:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"cicd-aiops\",\n  \"version\": \"0.10.2\",\n  \"publishedAt\": 1789221591874\n}\n\nFile v0.10.2:references/agent-guardrails.md\n\n# Agent guardrails — running cicd-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 token you connect with.** Give it a GitLab/Gitea access token without\n  write scope. A write then fails at the server, which is the only place the\n  permission actually lives — no skill-side flag can be argued around by a\n  model, but a token without the scope cannot be.\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| \"Log everything you do, over both MCP and the CLI\" | Every call is audited to `~/.cicd-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. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | A field the server did not return comes back as `null`, never as `\"\"`. A pipeline with no `ref`, a job with no `startedAt` or `failureReason`, a runner that has never reported `contactedAt` — all stay `null`, and the key is always present. |\n| \"Tell me if the output was cut off\" | Every listing returns `{\"<items>\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is **measured** (one extra row is fetched), never guessed from a full page. `job_trace_tail` adds `charsTruncated` for the byte ceiling. |\n| \"Tell me if a number is unknown rather than zero\" | Storage numbers a platform does not report come back as `null` with `artifactsBytesKnown: false`, and `artifact_storage_bloat_analysis` counts them in `artifactBytesUnavailable`. `cicd_overview` reports `runnersSupported`. |\n| \"Confirm before anything destructive\" | Destructive operations require a `--dry-run`-able preview + double confirmation at the CLI. |\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\n## Platform asymmetry — a teaching error is an ANSWER, not a failure\n\nThis is the one thing worth spending prompt budget on, because it is specific\nto this tool. `cicd-aiops` speaks to **two different servers** — self-managed\nGitLab (REST v4) and self-hosted Gitea (API v1) — and they do not expose the\nsame surfaces. Where a platform has no equivalent API, the resource is\ndeliberately **not mapped**, and the call raises a teaching error naming the\nresources that *do* exist on that platform.\n\nThat error means \"wrong platform for this question\". It is a correct, final\nanswer. A model that treats it as a transient tool failure will retry the same\ncall, or report \"the CI/CD server is unreachable\" — both wrong.\n\n**GitLab only** (a Gitea target raises the teaching error):\n\n| Tool | Why |\n|---|---|\n| `list_runners`, `runner_detail` | Gitea API v1 has no runner-administration endpoint |\n| `pause_runner`, `resume_runner` | same — no runner update endpoint |\n| `retry_pipeline`, `cancel_pipeline` | Gitea Actions exposes no run retry/cancel endpoint |\n| `delete_artifacts` | Gitea exposes no artifact-deletion endpoint (list only) |\n| `runner_health_rca` **when it pulls live** | it pulls the runner fleet, so it inherits the above. Injecting `runners=[...]` makes it pure analysis and it works anywhere |\n\nEverything else — `server_version`, `current_user`, `cicd_overview`,\n`list_projects`, `project_detail`, `list_pipelines`, `pipeline_detail`,\n`pipeline_jobs`, `job_trace_tail`, `list_artifacts`, `list_merge_requests`,\n`list_branches`, `list_protected_branches`, `list_releases`,\n`update_branch_protection`, and the other three flagship analyses — works on\nboth platforms.\n\nCheck `cicd_overview`'s `platform` field first if you do not know which server\nyou are pointed at. When a tool is GitLab-only and the target is Gitea, do not\nretry: answer from the pipeline / job / repo surface instead, and say plainly\nthat this platform has no runner (or retry/cancel, or artifact-deletion) API.\n\n### Worse than a teaching error: a surface that returns *nothing* instead of refusing\n\nA teaching error is loud. These two are quiet, and they used to be\nindistinguishable from a real measurement. They are now labelled in the\npayload — **read the label, do not read the number alone**:\n\n| Where | The quiet gap | The label to read |\n|---|---|---|\n| `cicd_overview` on Gitea | `runnersTotal` / `runnersOnline` are `null` because the platform has no runner API — **not** because there are no runners | `runnersSupported: false`. Never report \"0 runners\" from this. |\n| `list_projects` / `project_detail` / `artifact_storage_bloat_analysis` on Gitea | Gitea reports a repo `size` but **no artifact or total-storage statistics**, so `artifactsBytes` and `storageBytes` are `null`. A storage RCA against a Gitea target ranks projects on repo bytes alone and finds **zero** reclaimable artifact bytes — which is a gap in the data, not a clean result | `artifactsBytesKnown: false` per project, `artifactBytesUnavailable: N` on the analysis |\n\nOne more bounded read worth naming: on GitLab, `list_artifacts` has no single\nartifacts endpoint, so the inventory is assembled by walking recent jobs. When\n`jobScanTruncated` is `true`, older jobs' artifacts are **not** in the result —\n`totalBytes` is then a lower bound, and `delete_artifacts` says so too\n(`priorState.complete: false`).\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 self-managed GitLab / Gitea CI/CD servers through the cicd-aiops\nMCP tools.\n\nTOOL USE\n- Before answering any question about the current CI/CD environment, 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- Some tools exist only on GitLab (runner list/detail/pause/resume, pipeline\n  retry/cancel, artifact deletion). On a Gitea target they return a teaching\n  error listing what IS available. That is a final answer about the platform,\n  not a transient failure: do not retry it, do not call it broken. Say the\n  platform has no such API and answer from another surface.\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. On the analyses \"truncated\" is a per-list\n  object — check each entry.\n- A null field means the server did not return that value. Report it as \"not\n  available\" — never infer it, and never report it as zero. In particular:\n  runnersSupported=false means \"this platform has no runner API\", and\n  artifactsBytesKnown=false means artifact storage was not measured.\n- A job trace is only the TAIL of the log. When \"truncated\" is true the first\n  error may be above the window — raise tail_lines before naming a root cause.\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  status strings, branch names, or IDs.\n- Work RCA findings in the order returned and cite the measured number each\n  finding carries (\"evidence\", \"cause\", byte counts, queue seconds).\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, storage, or reliability problem unless a tool\n  result supports it.\n- Do not add generic CI/CD advice that does not follow from the tool output.\n- Do not confuse a project path with a pipeline id, a pipeline id with a job\n  id, or a runner id with either. Job ids come from pipeline_jobs; pipeline ids\n  come from list_pipelines; runner ids come from list_runners.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the token's scope\nonly when you trust the setup — `delete_artifacts` is irreversible, and a\nmistaken pipeline retry or cancel burns runner minutes:\n\n```bash\n# e.g. use a GitLab/Gitea access token without write scope. Then:\ncicd-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 CICD_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CICD_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\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 the four RCA tools\n  (`pipeline_failure_rca`, `runner_health_rca`,\n  `artifact_storage_bloat_analysis`, `stale_work_audit`) — each does the\n  multi-step correlation inside one call, so the model does not have to chain\n  `list_pipelines` → `pipeline_jobs` → `job_trace_tail` and keep three\n  different id types straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions and use `--limit` / `tail_lines` deliberately rather than pulling\n  whole inventories or long traces.\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/CICD-AIops](https://github.com/AIops-tools/CICD-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.10.2:references/capabilities.md\n\n# cicd-aiops — capabilities reference\n\n28 governed MCP tools over two platforms (16 reads + 4 analyses + 6 writes +\n`undo_list`/`undo_apply`). Every tool takes an optional\n`target` (a name from `~/.cicd-aiops/config.yaml`); writes also take\n`dry_run: bool`.\n\n## Platforms\n\n| Platform | API | Auth | Project addressing |\n|---|---|---|---|\n| `gitlab` | REST v4 (`/api/v4/...`) | `PRIVATE-TOKEN: <token>` | numeric id or URL-encoded full path (`group%2Fproject`) |\n| `gitea` | API v1 (`/api/v1/...`) | `Authorization: token <token>` | `owner/repo` (two path segments) |\n\nSelf-managed/self-hosted instances only. Where Gitea lacks a surface, the\nplatform registry raises a teaching `KeyError` naming the resources that ARE\navailable: runner administration, pipeline retry/cancel, and artifact deletion\nare GitLab-only in v0.1.\n\n## Reads (16)\n\n| Tool | What it returns | GitLab path | Gitea path |\n|---|---|---|---|\n| `server_version` | version + revision | `/api/v4/version` | `/api/v1/version` |\n| `current_user` | token identity (scope probe) | `/api/v4/user` | `/api/v1/user` |\n| `cicd_overview` | version + identity + projects + runners | (composite) | (composite) |\n| `list_projects` | projects w/ storage bytes | `/api/v4/projects?statistics=true` | `/api/v1/repos/search` |\n| `project_detail` | one project incl. sizes | `/api/v4/projects/{p}` | `/api/v1/repos/{owner}/{repo}` |\n| `list_pipelines` | recent pipelines/runs | `/api/v4/projects/{p}/pipelines` | **unsupported** — Gitea API v1 has no run-level resource |\n| `pipeline_detail` | one pipeline/run | `.../pipelines/{id}` | **unsupported** (same reason) |\n| `pipeline_jobs` | jobs + failure_reason | `.../pipelines/{id}/jobs` | **unsupported**; the per-job listing is `/actions/tasks` |\n| `job_trace_tail` | last N log lines | `.../jobs/{id}/trace` | `.../actions/jobs/{id}/logs` |\n| `list_runners` | fleet, offline first | `/api/v4/runners/all` | — teaching error |\n| `runner_detail` | contacted_at, tags, paused | `/api/v4/runners/{id}` | — teaching error |\n| `list_merge_requests` | MRs / PRs | `.../merge_requests` | `.../pulls` |\n| `list_branches` | branches + last-commit date | `.../repository/branches` | `.../branches` |\n| `list_protected_branches` | protection rules + force-push flags | `.../protected_branches` | `.../branch_protections` |\n| `list_releases` | releases newest first | `.../releases` | `.../releases` |\n| `list_artifacts` | files, sizes, expiry, expired-but-kept | via `.../jobs` artifacts | `.../actions/artifacts` |\n\n## Flagship analyses (4, read-only, thresholds are parameters)\n\n| Tool | Flags | Key thresholds |\n|---|---|---|\n| `pipeline_failure_rca` | each failed job classified: test-failure / dependency-network / runner-timeout / oom / script-error, with matched evidence + action | `limit` (pipelines), `tail_lines` |\n| `runner_health_rca` | offline / stale / paused runners; long-queued jobs; saturated tags | `stale_contact_min` (30), `queue_sec` (300), `saturation_ratio` (2.0) |\n| `artifact_storage_bloat_analysis` | projects ranked by repo+artifact bytes; expired-but-kept; reclaimable estimate | `old_artifact_days` (30) |\n| `stale_work_audit` | idle open MRs; idle branches; unprotected default branch; force-push allowed | `stale_mr_days` (14), `stale_branch_days` (90) |\n\nAll four accept injected rows for pure/offline analysis, or pull live from a\ntarget. Classification order in `pipeline_failure_rca` is most-specific first:\nOOM > timeout > network > test > script; GitLab `failure_reason` values\n(`stuck_or_timeout_failure`, `runner_system_failure`, …) classify without a\ntrace.\n\n## Writes (6, governed, all with `dry_run`)\n\n| Tool | Risk | Prior state captured | Undo |\n|---|---|---|---|\n| `retry_pipeline` | medium | pipeline status | none (a retry is a new run) |\n| `cancel_pipeline` | medium | pipeline status | none (irreversible) |\n| `pause_runner` | medium | runner `paused` flag | `resume_runner` (skipped if it was already paused) |\n| `resume_runner` | medium | runner `paused` flag | `pause_runner` (skipped if it was not paused) |\n| `delete_artifacts` | **high** | artifact count + bytes destroyed | none (irreversible) |\n| `update_branch_protection` | medium | prior protection settings (or \"unprotected\") | replays this tool with the prior settings |\n\n`delete_artifacts(older_than_days=N)` deletes per-job only artifacts created\nbefore the cutoff; `0` uses GitLab's bulk-delete of eligible artifacts.\n\n## Safety plumbing\n\n- Every substituted URL path value is percent-encoded (`quote(..., safe=\"\")`);\n  Gitea's `owner/repo` keeps its `/` but each piece is encoded and empty /\n  `.` / `..` pieces are rejected (path-traversal defense).\n- All server-returned text passes an injection-safe normaliser (bounded string\n  length, capped nesting depth) before an agent sees it.\n- Non-2xx responses become teaching errors (what failed + what to check);\n  plain-text trace endpoints pass through as text.\n\nFile v0.10.2:references/cli-reference.md\n\n# cicd-aiops — CLI reference\n\nAll commands accept `--target/-t <name>` (default: the first target in\nconfig.yaml). Writes accept `--dry-run` and double-confirm before executing;\nconfirmed writes run through the same governed path as the MCP tools (audited).\n\n## Setup / health\n\n```bash\ncicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)\ncicd-aiops doctor               # config + secrets + connectivity + token-scope probe\ncicd-aiops doctor --skip-auth   # config/secrets checks only\ncicd-aiops overview             # version, identity, projects, runners\ncicd-aiops projects [--search x] [--limit N]\n```\n\n## Pipelines\n\n```bash\ncicd-aiops pipelines list <project> [--status failed] [--limit N]\ncicd-aiops pipelines show <project> <pipeline>\ncicd-aiops pipelines jobs <project> <pipeline>\ncicd-aiops pipelines trace <project> <job> [--lines 60]\ncicd-aiops pipelines retry <project> <pipeline> [--dry-run]    # governed write\ncicd-aiops pipelines cancel <project> <pipeline> [--dry-run]   # governed write\n```\n\n## Runners\n\n```bash\ncicd-aiops runners list [--status offline]\ncicd-aiops runners show <runner>\ncicd-aiops runners pause <runner> [--dry-run]     # governed write, undo-recorded\ncicd-aiops runners resume <runner> [--dry-run]    # governed write, undo-recorded\n```\n\n## Artifacts\n\n```bash\ncicd-aiops artifacts list <project>\ncicd-aiops artifacts delete <project> [--older-than-days 30] [--dry-run]\n# risk=high: requires CICD_AUDIT_APPROVED_BY (+ CICD_AUDIT_RATIONALE)\n```\n\n## Flagship RCAs\n\n```bash\ncicd-aiops rca pipelines <project> [--limit 10]   # classify failed pipelines\ncicd-aiops rca runners                            # offline/stale/saturation\ncicd-aiops rca storage [--old-days 30]            # bloat + reclaimable bytes\ncicd-aiops rca stale <project> [--mr-days 14] [--branch-days 90]\n```\n\n## Secrets\n\n```bash\ncicd-aiops secret set <target>      # store a token (encrypted)\ncicd-aiops secret list              # names only, never values\ncicd-aiops secret remove <target>\ncicd-aiops secret migrate           # legacy .env → encrypted store\n```\n\n## MCP\n\n```bash\ncicd-aiops mcp                      # start the MCP server (stdio)\n```\n\n## Environment variables\n\n| Var | Purpose |\n|---|---|\n| `CICD_AIOPS_HOME` | relocate config/audit/undo/secrets (default `~/.cicd-aiops`) |\n| `CICD_AIOPS_CONFIG` | explicit config.yaml path for the MCP server |\n| `CICD_AIOPS_MASTER_PASSWORD` | unlock secrets.enc non-interactively |\n| `CICD_AUDIT_APPROVED_BY` / `CICD_AUDIT_RATIONALE` | optional audit annotations (who/why) — recorded, never required |\n| `CICD_MAX_TOOL_CALLS` / `CICD_MAX_TOOL_SECONDS` | budget caps |\n| `CICD_RUNAWAY_MAX` / `CICD_RUNAWAY_WINDOW_SEC` | runaway breaker |\n| `CICD_<TARGET>_SECRET` | legacy plaintext token fallback (deprecated) |\n\nFile v0.10.2:references/setup-guide.md\n\n# cicd-aiops — setup guide\n\n## 1. Install\n\n```bash\nuv tool install cicd-aiops        # or: pip install cicd-aiops\n```\n\nRequires Python >= 3.11.\n\n## 2. Create a token on the server\n\n**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or\nproject) access token with the `api` scope. Runner administration\n(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an\nadmin-capable account.\n\n**Gitea (self-hosted)** — Settings → Applications → Generate new token. Grant\nread scopes for repository/issue and write where you want\n`update_branch_protection` to work.\n\nLeast privilege applies: a read-only token still powers every read and all\nfour RCAs; only the six write tools need write scopes.\n\n## 3. Onboard\n\n```bash\ncicd-aiops init\n```\n\nThe wizard asks for:\n\n1. **Master password** — encrypts `~/.cicd-aiops/secrets.enc` (Fernet +\n   scrypt). For MCP / non-interactive use export\n   `CICD_AIOPS_MASTER_PASSWORD=...`.\n2. **Target name** (e.g. `gl1`), **platform** (`gitlab` / `gitea`), and\n   **base URL** (e.g. `https://git.example.com` — scheme optional, added\n   automatically).\n3. **TLS verification** — defaults to **Yes**; answer No only for\n   self-signed lab certs.\n4. **Access token** — prompted hidden, stored encrypted, never in\n   config.yaml.\n\nResulting `~/.cicd-aiops/config.yaml`:\n\n```yaml\ntargets:\n  - name: gl1\n    platform: gitlab\n    base_url: https://git.example.com\n    verify_ssl: true\n  - name: gt1\n    platform: gitea\n    base_url: https://gitea.example.com\n    verify_ssl: true\n```\n\n## 4. Verify\n\n```bash\ncicd-aiops doctor\n```\n\nChecks per target: config present, encrypted store + token present, the\nserver's **version endpoint** answers, and a **token-scope probe**\n(`current_user`) confirms the token authenticates. A reachable server with a\ndud token is reported as unhealthy.\n\n## 5. MCP client config\n\n```json\n{\n  \"mcpServers\": {\n    \"cicd-aiops\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"cicd-aiops\", \"cicd-aiops-mcp\"],\n      \"env\": {\n        \"CICD_AIOPS_MASTER_PASSWORD\": \"your-master-password\"\n      }\n    }\n  }\n}\n```\n\nMCP clients do not source your shell profile — set\n`CICD_AIOPS_MASTER_PASSWORD` in the `env` block.\n\n## Audit-annotation env vars (optional)\n\nThe skill does not decide whether a write is permitted — that is the agent's\njudgement or the connecting token's scope. If you want the audit trail to record\n*who* ran a destructive op and *why*, set these; they are recorded on the row,\nnever required, and gate nothing:\n\n```bash\nexport CICD_AUDIT_APPROVED_BY='you@example.com'\nexport CICD_AUDIT_RATIONALE='why this destructive op is justified'\n```\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---|---|\n| `401/403` in doctor | token expired or missing `api` scope — reissue and `cicd-aiops secret set <target>` |\n| `Could not reach ...` | check `base_url`, VPN/network path, and that the API is enabled |\n| self-signed cert errors | re-run `init` and answer No to TLS verify (lab only) |\n| `Resource ... not available on platform 'gitea'` | expected: runner admin / pipeline retry / artifact delete are GitLab surfaces in v0.1 |\n| a write fails with `403` | the token lacks the write scope — reissue with write access (or keep it read-only by design) |\n\nFile v0.10.2:skill-card.md\n\n## Description:\n\nCICD AIops helps agents inspect and operate self-managed GitLab and self-hosted Gitea CI/CD servers, including pipelines, runners, artifacts, repository hygiene, RCA workflows, and governed write actions.\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 and CI/CD operators use this skill to diagnose failed pipelines, runner capacity, artifact storage, stale work, and branch protections on self-managed GitLab or self-hosted Gitea instances. They can use its CLI or MCP tools to prepare or execute governed remediation while preserving audit records.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The release installs external code without trusted provenance recorded for this version.\n\nMitigation: Review before installing and use an exact pinned package version or trusted provenance when deploying.\n\nRisk: The skill can perform high-impact GitLab or Gitea changes, including irreversible artifact deletion and branch-protection changes.\n\nMitigation: Use a read-only or narrowly scoped token by default and require an explicit local approval process before live writes.\n\nRisk: Providing the master password directly in MCP configuration can expose sensitive credentials through client configuration handling.\n\nMitigation: Avoid storing the master password directly in MCP config where possible and prefer environment handling appropriate to the deployment.\n\nRisk: Some platform surfaces are GitLab-only or have incomplete storage visibility on Gitea, which can lead to misleading conclusions if ignored.\n\nMitigation: Check platform support labels, truncation indicators, and null fields before interpreting runner, pipeline, artifact, or storage results.\n\n## Reference(s):\n\n- [CICD-AIops GitHub repository](https://github.com/AIops-tools/CICD-AIops)\n- [cicd-aiops ClawHub listing](https://clawhub.ai/zw008/skills/cicd-aiops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup 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, Analysis]\n\n**Output Format:** [Markdown with inline shell commands and structured tool-result summaries]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include CI/CD RCA findings, command recommendations, configuration snippets, and risk notes for governed write operations.]\n\n## Skill Version(s):\n\n0.10.2 (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.10.1: 7 files, 19219 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4930b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2524b), SKILL.md (16913b), _meta.json (130b)\n\nFile v0.10.1:SKILL.md\n\n---\nname: cicd-aiops\nslug: cicd-aiops\ndisplayName: \"CICD AIops\"\nsummary: \"Governed self-managed GitLab + Gitea CI/CD ops: pipelines, runners, artifacts, RCA. 28 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/CICD-AIops\ntags: [aiops, mcp, governance, cicd]\ndescription: >\n  Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection).\n  Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance.\n  Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances.\n  Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).\ninstaller:\n  kind: uv\n  package: cicd-aiops\nargument-hint: \"[a project path, pipeline/runner id, or describe your CI/CD task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"cicd-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CICD_AIOPS_CONFIG\",\"CICD_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/CICD-AIops\",\"emoji\":\"🔁\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via \"Authorization: token\"). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).\n  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double confirmation and is irreversible (priorState records the destroyed count/bytes). Reversible writes (pause_runner/resume_runner as an undo pair; update_branch_protection replaying prior settings) capture the real fetched before-state and record an inverse undo descriptor; retry_pipeline/cancel_pipeline record priorState (the pipeline's prior status) only.\n  Webhooks: none — no outbound network calls beyond the configured GitLab / Gitea REST API.\n  SSL: verify_ssl defaults to ON; the init wizard asks before disabling it for self-signed lab certs.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Verification status: mock-validated; no recorded end-to-end run against a live server yet, and the modelled REST paths are the largest verification debt. Both GitLab CE and Gitea are free/self-hostable (each runs from a container), so a home lab is the cheapest live check. See docs/VERIFICATION.md.\n---\n\n# CICD AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by GitLab Inc. or the Gitea project.** GitLab and Gitea are trademarks of their respective owners. Source at [github.com/AIops-tools/CICD-AIops](https://github.com/AIops-tools/CICD-AIops) under the MIT license.\n\nGoverned CI/CD operations — **28 MCP tools** across **self-managed GitLab** (REST\n`/api/v4/...`) and **self-hosted Gitea** (API `/api/v1/...`), every one wrapped with\nthe bundled `@governed_tool` harness: a local unified audit log under\n`~/.cicd-aiops/`, token/runaway budget guard, undo-token recording, and\ndescriptive risk tiers. A per-target `platform` field selects the API shape, so\nthe same tools work on both servers and one config can span a mixed estate. The\naccess token is stored **encrypted** (`~/.cicd-aiops/secrets.enc`, Fernet +\nscrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package\n> (`cicd_aiops.governance`) — no external skill-family dependency. Both\n> platforms are free/self-hostable, so a home lab is the cheapest live check;\n> verification status and the checklist are in `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Group | Tools | Count | R/W |\n|-------|-------|:-----:|:---:|\n| **Server** | server_version, current_user, cicd_overview | 3 | read |\n| **Projects** | list_projects, project_detail | 2 | read |\n| **Pipelines** | list_pipelines, pipeline_detail, pipeline_jobs, job_trace_tail | 4 | read |\n| **Runners** | list_runners, runner_detail | 2 | read |\n| **Repo surface** | list_merge_requests, list_branches, list_protected_branches, list_releases | 4 | read |\n| **Artifacts** | list_artifacts | 1 | read |\n| **Flagship analyses** | pipeline_failure_rca, runner_health_rca, artifact_storage_bloat_analysis, stale_work_audit | 4 | read |\n| **Writes** | retry_pipeline, cancel_pipeline, pause_runner, resume_runner, update_branch_protection | 5 | write (med) |\n| **Writes** | delete_artifacts | 1 | write (**high**) |\n| **Undo** | undo_list, undo_apply | 2 | read + replay |\n\nThe four flagship analyses are transparent heuristics that report their numbers,\nnever a black-box verdict: `pipeline_failure_rca` classifies each failed job from\nits failure_reason + trace-tail markers (test-failure / dependency-network /\nrunner-timeout / oom / script-error) with matched evidence; `runner_health_rca`\nflags offline/stale/paused runners, long-queued jobs, and per-tag saturation;\n`artifact_storage_bloat_analysis` ranks projects by repo + artifact bytes and\nestimates reclaimable bytes; `stale_work_audit` flags idle MRs/branches and\nprotection gaps.\n\n## Quick Install\n\n```bash\nuv tool install cicd-aiops\ncicd-aiops init       # wizard: pick platform (gitlab/gitea) + base URL + encrypted token\ncicd-aiops doctor     # version endpoint + token-scope probe per target\n```\n\nOr as an OpenClaw plugin, which installs this skill and its MCP server together:\n\n```bash\nopenclaw plugins install clawhub:@aiops-tools/cicd-aiops\nopenclaw skills info cicd-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- Get a one-shot snapshot (`overview` / `server_version` / `current_user`)\n- Answer \"why is CI red?\" (`rca pipelines` / `pipeline_failure_rca`) → cause +\n  action per failed pipeline, with the trace evidence that drove the call\n- Find wedged capacity (`rca runners` / `runner_health_rca`) → offline/stale\n  runners, long-queued jobs, saturated tags\n- Reclaim disk (`rca storage` / `artifact_storage_bloat_analysis`) → ranked\n  projects + reclaimable bytes, feeding `delete_artifacts --dry-run`\n- Repo hygiene (`rca stale` / `stale_work_audit`) → idle MRs/branches,\n  unprotected default branch, force-push gaps\n- Safely act: `retry_pipeline` / `cancel_pipeline`, `pause_runner` /\n  `resume_runner` (undo pair), `update_branch_protection` (undo replays prior\n  settings), `delete_artifacts` (risk=high, dry-run + double confirm)\n\n**Do NOT use when** the target is not a GitLab/Gitea CI/CD server — route\nhypervisor, storage, backup, database, network, or OT/industrial work to the\nappropriate other AIops-tools skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Self-managed GitLab / Gitea CI/CD ops | **cicd-aiops** (this skill) |\n| Kubernetes deploy state (what the cluster is actually running) | **k8s-aiops** |\n| A non-CI/CD platform (hypervisor, storage, backup, database, network, OT edge) | the appropriate **other AIops-tools** skill |\n| GitLab.com / Gitea Cloud SaaS accounts | out of scope for this tool |\n\n## Common Workflows\n\nEach recipe starts from one of the four RCAs and ends in a governed write.\nEvery CLI write accepts `--dry-run` and otherwise double-confirms. Note that\nrunner administration and pipeline retry/cancel are **GitLab-only** — on a\nGitea target those tools raise a teaching error listing what is available.\n\n### 1. \"The nightly pipeline has been red for three days\"\n\n1. `cicd-aiops pipelines list dev/api --status failed -n 20` → the recent\n   failed pipelines, newest first.\n2. `cicd-aiops rca pipelines dev/api` → each failed job classified from its\n   `failure_reason` plus trace-tail markers: test-failure, dependency-network,\n   runner-timeout, OOM, or script-error, with the evidence and a suggested\n   action.\n3. `cicd-aiops pipelines jobs dev/api <pipeline-id>` → which stage and job the\n   classification came from.\n4. `cicd-aiops pipelines trace dev/api <job-id> -n 120` → the actual log tail,\n   so you confirm the classification instead of trusting it.\n5. Fix the cause. If the RCA said the failure was transient (dependency-network\n   or runner-timeout): `cicd-aiops pipelines retry dev/api <pipeline-id>\n   --dry-run`, then re-run for real (double confirm).\n6. `cicd-aiops rca pipelines dev/api` again to confirm the class of failure is\n   gone rather than merely quieter.\n\n**Failure branch**: if the RCA classifies the failures as **test-failure** or\n**script-error**, do not retry — the code is broken and a retry burns runner\nminutes to reach the same red. Retry is only honest for transient classes. If\nthe retry itself fails to submit on a Gitea target, that is the teaching error:\nretry/cancel have no Gitea API v1 equivalent, so re-run the job from the Gitea\nUI instead.\n\n### 2. \"Jobs are sitting in the queue and nothing is picking them up\"\n\n1. `cicd-aiops runners list --status offline` and `--status paused` → the\n   obvious suspects first.\n2. `cicd-aiops rca runners` → stale contact ages, long-queued jobs, and **which\n   tag is saturated** (queued jobs versus online runners carrying that tag).\n3. `cicd-aiops runners show <runner-id>` → the specific runner's tags, last\n   contact and status.\n4. If a needed runner was paused: `cicd-aiops runners resume <runner-id>\n   --dry-run`, then for real (reversible — an inverse `pause_runner` is\n   recorded).\n5. If a wedged runner is grabbing jobs and failing them: `cicd-aiops runners\n   pause <runner-id>` to take it out of rotation (reversible — inverse\n   `resume_runner` recorded).\n6. `cicd-aiops rca runners` again to confirm the queue is draining.\n\n**Failure branch**: if the RCA shows a **saturated tag** rather than a\ndown runner, resuming runners will not help — no online runner carries the tag\nthose jobs require, so you need to add or retag capacity. And if you paused a\nrunner and the queue got worse, `cicd-aiops undo apply <id>` resumes exactly\nthe runner you paused. Runner administration is GitLab-only; a Gitea target\nraises a teaching error here.\n\n### 3. \"The CI server is out of disk\"\n\n1. `cicd-aiops rca storage --old-days 30` → projects ranked by repo + artifact\n   bytes with a reclaimable estimate at that age threshold.\n2. `cicd-aiops artifacts list dev/api` → the actual artifact files, their sizes\n   and their expiry, so you see what \"reclaimable\" really refers to.\n3. `cicd-aiops projects --limit 50` → cross-check that the top consumer is the\n   project you expect.\n4. `cicd-aiops artifacts delete dev/api --older-than-days 30 --dry-run` →\n   shows the scope, deletes nothing.\n5. Re-run without `--dry-run`: double confirm, **high** risk. Optionally set\n   `CICD_AUDIT_APPROVED_BY` + `CICD_AUDIT_RATIONALE` to annotate who/why on the\n   audit row. This is **irreversible** — priorState records the destroyed count\n   and bytes for the audit trail, but there is no undo.\n6. `cicd-aiops rca storage` again to confirm the reclaimed bytes landed.\n\n**Failure branch**: never run `artifacts delete` with `--older-than-days 0` as\na first move — 0 means **ALL** artifacts, including the ones a release or a\nrunning deploy depends on. If the dry-run scope reads \"ALL\" and you did not\nintend that, stop and set an age. Since there is no undo for this operation,\nthe dry-run is the only safety net you get; if the bloat is mostly **repo**\nbytes rather than artifact bytes, deleting artifacts will not help at all.\n\n### 4. \"Tighten repo hygiene before the release freeze\"\n\n1. `cicd-aiops rca stale dev/api --mr-days 14 --branch-days 60` → stale open\n   merge requests, idle branches, and **protection gaps** such as an\n   unprotected default branch or force-push left allowed.\n2. Confirm the current state via MCP `list_protected_branches` and\n   `list_branches` for the project.\n3. MCP `list_merge_requests` → the stale MRs the audit named, so you can close\n   or revive them with their owners rather than in bulk.\n4. Close the protection gap with MCP `update_branch_protection` (e.g.\n   `allow_force_push=False` on the default branch) — it fetches and captures\n   the prior settings and records an undo that replays them exactly.\n5. `cicd-aiops undo list` → confirm the protection change is reversible.\n6. `cicd-aiops rca stale dev/api` again to confirm the gap closed.\n\n**Failure branch**: if tightening protection blocks a legitimate workflow — a\nrelease automation that force-pushes tags, say — `cicd-aiops undo apply <id>`\nrestores the exact prior protection settings rather than a guessed default.\nFix the automation before re-applying, and do not disable protection\nfleet-wide to unblock one job.\n\n## Governance & 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 token you connect it with (a GitLab/Gitea access token without write\nscope — writes then fail at the server). There is no read-only switch, policy\nfile, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.cicd-aiops/audit.db` (relocatable via `CICD_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CICD_AUDIT_APPROVED_BY` / `CICD_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: the same call looped in a tight window trips a circuit breaker. Disable with `CICD_RUNAWAY_MAX=0`.\n- Destructive writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI. `delete_artifacts` is irreversible (priorState records the destroyed count/bytes; audit only).\n- Reversible writes fetch the real before-state and record an inverse descriptor (pause_runner↔resume_runner, update_branch_protection→prior settings); irreversible ops (retry_pipeline, cancel_pipeline, delete_artifacts) record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + platform + API-path reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n- `references/agent-guardrails.md` — which guardrails the harness enforces, the\n  GitLab-only vs Gitea platform asymmetry, and a ready-made system prompt for\n  smaller / local models\n\nFile v0.10.1:_meta.json\n\n{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"cicd-aiops\",\n  \"version\": \"0.10.1\",\n  \"publishedAt\": 1789206962594\n}\n\nFile v0.10.1:references/agent-guardrails.md\n\n# Agent guardrails — running cicd-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 token you connect with.** Give it a GitLab/Gitea access token without\n  write scope. A write then fails at the server, which is the only place the\n  permission actually lives — no skill-side flag can be argued around by a\n  model, but a token without the scope cannot be.\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| \"Log everything you do, over both MCP and the CLI\" | Every call is audited to `~/.cicd-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. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | A field the server did not return comes back as `null`, never as `\"\"`. A pipeline with no `ref`, a job with no `startedAt` or `failureReason`, a runner that has never reported `contactedAt` — all stay `null`, and the key is always present. |\n| \"Tell me if the output was cut off\" | Every listing returns `{\"<items>\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is **measured** (one extra row is fetched), never guessed from a full page. `job_trace_tail` adds `charsTruncated` for the byte ceiling. |\n| \"Tell me if a number is unknown rather than zero\" | Storage numbers a platform does not report come back as `null` with `artifactsBytesKnown: false`, and `artifact_storage_bloat_analysis` counts them in `artifactBytesUnavailable`. `cicd_overview` reports `runnersSupported`. |\n| \"Confirm before anything destructive\" | Destructive operations require a `--dry-run`-able preview + double confirmation at the CLI. |\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\n## Platform asymmetry — a teaching error is an ANSWER, not a failure\n\nThis is the one thing worth spending prompt budget on, because it is specific\nto this tool. `cicd-aiops` speaks to **two different servers** — self-managed\nGitLab (REST v4) and self-hosted Gitea (API v1) — and they do not expose the\nsame surfaces. Where a platform has no equivalent API, the resource is\ndeliberately **not mapped**, and the call raises a teaching error naming the\nresources that *do* exist on that platform.\n\nThat error means \"wrong platform for this question\". It is a correct, final\nanswer. A model that treats it as a transient tool failure will retry the same\ncall, or report \"the CI/CD server is unreachable\" — both wrong.\n\n**GitLab only** (a Gitea target raises the teaching error):\n\n| Tool | Why |\n|---|---|\n| `list_runners`, `runner_detail` | Gitea API v1 has no runner-administration endpoint |\n| `pause_runner`, `resume_runner` | same — no runner update endpoint |\n| `retry_pipeline`, `cancel_pipeline` | Gitea Actions exposes no run retry/cancel endpoint |\n| `delete_artifacts` | Gitea exposes no artifact-deletion endpoint (list only) |\n| `runner_health_rca` **when it pulls live** | it pulls the runner fleet, so it inherits the above. Injecting `runners=[...]` makes it pure analysis and it works anywhere |\n\nEverything else — `server_version`, `current_user`, `cicd_overview`,\n`list_projects`, `project_detail`, `list_pipelines`, `pipeline_detail`,\n`pipeline_jobs`, `job_trace_tail`, `list_artifacts`, `list_merge_requests`,\n`list_branches`, `list_protected_branches`, `list_releases`,\n`update_branch_protection`, and the other three flagship analyses — works on\nboth platforms.\n\nCheck `cicd_overview`'s `platform` field first if you do not know which server\nyou are pointed at. When a tool is GitLab-only and the target is Gitea, do not\nretry: answer from the pipeline / job / repo surface instead, and say plainly\nthat this platform has no runner (or retry/cancel, or artifact-deletion) API.\n\n### Worse than a teaching error: a surface that returns *nothing* instead of refusing\n\nA teaching error is loud. These two are quiet, and they used to be\nindistinguishable from a real measurement. They are now labelled in the\npayload — **read the label, do not read the number alone**:\n\n| Where | The quiet gap | The label to read |\n|---|---|---|\n| `cicd_overview` on Gitea | `runnersTotal` / `runnersOnline` are `null` because the platform has no runner API — **not** because there are no runners | `runnersSupported: false`. Never report \"0 runners\" from this. |\n| `list_projects` / `project_detail` / `artifact_storage_bloat_analysis` on Gitea | Gitea reports a repo `size` but **no artifact or total-storage statistics**, so `artifactsBytes` and `storageBytes` are `null`. A storage RCA against a Gitea target ranks projects on repo bytes alone and finds **zero** reclaimable artifact bytes — which is a gap in the data, not a clean result | `artifactsBytesKnown: false` per project, `artifactBytesUnavailable: N` on the analysis |\n\nOne more bounded read worth naming: on GitLab, `list_artifacts` has no single\nartifacts endpoint, so the inventory is assembled by walking recent jobs. When\n`jobScanTruncated` is `true`, older jobs' artifacts are **not** in the result —\n`totalBytes` is then a lower bound, and `delete_artifacts` says so too\n(`priorState.complete: false`).\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 self-managed GitLab / Gitea CI/CD servers through the cicd-aiops\nMCP tools.\n\nTOOL USE\n- Before answering any question about the current CI/CD environment, 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- Some tools exist only on GitLab (runner list/detail/pause/resume, pipeline\n  retry/cancel, artifact deletion). On a Gitea target they return a teaching\n  error listing what IS available. That is a final answer about the platform,\n  not a transient failure: do not retry it, do not call it broken. Say the\n  platform has no such API and answer from another surface.\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. On the analyses \"truncated\" is a per-list\n  object — check each entry.\n- A null field means the server did not return that value. Report it as \"not\n  available\" — never infer it, and never report it as zero. In particular:\n  runnersSupported=false means \"this platform has no runner API\", and\n  artifactsBytesKnown=false means artifact storage was not measured.\n- A job trace is only the TAIL of the log. When \"truncated\" is true the first\n  error may be above the window — raise tail_lines before naming a root cause.\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  status strings, branch names, or IDs.\n- Work RCA findings in the order returned and cite the measured number each\n  finding carries (\"evidence\", \"cause\", byte counts, queue seconds).\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, storage, or reliability problem unless a tool\n  result supports it.\n- Do not add generic CI/CD advice that does not follow from the tool output.\n- Do not confuse a project path with a pipeline id, a pipeline id with a job\n  id, or a runner id with either. Job ids come from pipeline_jobs; pipeline ids\n  come from list_pipelines; runner ids come from list_runners.\n```\n\n## Recommended setup for a local model\n\nStart with a connection that *cannot* write, verify, and widen the token's scope\nonly when you trust the setup — `delete_artifacts` is irreversible, and a\nmistaken pipeline retry or cancel burns runner minutes:\n\n```bash\n# e.g. use a GitLab/Gitea access token without write scope. Then:\ncicd-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 CICD_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CICD_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\"\n```\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 the four RCA tools\n  (`pipeline_failure_rca`, `runner_health_rca`,\n  `artifact_storage_bloat_analysis`, `stale_work_audit`) — each does the\n  multi-step correlation inside one call, so the model does not have to chain\n  `list_pipelines` → `pipeline_jobs` → `job_trace_tail` and keep three\n  different id types straight.\n- **The model ignores later tool results in a long context.** Ask narrower\n  questions and use `--limit` / `tail_lines` deliberately rather than pulling\n  whole inventories or long traces.\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/CICD-AIops](https://github.com/AIops-tools/CICD-AIops/issues)\nwith the model, runtime, and what went wrong.\n\nFile v0.10.1:references/capabilities.md\n\n# cicd-aiops — capabilities reference\n\n28 governed MCP tools over two platforms (16 reads + 4 analyses + 6 writes +\n`undo_list`/`undo_apply`). Every tool takes an optional\n`target` (a name from `~/.cicd-aiops/config.yaml`); writes also take\n`dry_run: bool`.\n\n## Platforms\n\n| Platform | API | Auth | Project addressing |\n|---|---|---|---|\n| `gitlab` | REST v4 (`/api/v4/...`) | `PRIVATE-TOKEN: <token>` | numeric id or URL-encoded full path (`group%2Fproject`) |\n| `gitea` | API v1 (`/api/v1/...`) | `Authorization: token <token>` | `owner/repo` (two path segments) |\n\nSelf-managed/self-hosted instances only. Where Gitea lacks a surface, the\nplatform registry raises a teaching `KeyError` naming the resources that ARE\navailable: runner administration, pipeline retry/cancel, and artifact deletion\nare GitLab-only in v0.1.\n\n## Reads (16)\n\n| Tool | What it returns | GitLab path | Gitea path |\n|---|---|---|---|\n| `server_version` | version + revision | `/api/v4/version` | `/api/v1/version` |\n| `current_user` | token identity (scope probe) | `/api/v4/user` | `/api/v1/user` |\n| `cicd_overview` | version + identity + projects + runners | (composite) | (composite) |\n| `list_projects` | projects w/ storage bytes | `/api/v4/projects?statistics=true` | `/api/v1/repos/search` |\n| `project_detail` | one project incl. sizes | `/api/v4/projects/{p}` | `/api/v1/repos/{owner}/{repo}` |\n| `list_pipelines` | recent pipelines/runs | `/api/v4/projects/{p}/pipelines` | **unsupported** — Gitea API v1 has no run-level resource |\n| `pipeline_detail` | one pipeline/run | `.../pipelines/{id}` | **unsupported** (same reason) |\n| `pipeline_jobs` | jobs + failure_reason | `.../pipelines/{id}/jobs` | **unsupported**; the per-job listing is `/actions/tasks` |\n| `job_trace_tail` | last N log lines | `.../jobs/{id}/trace` | `.../actions/jobs/{id}/logs` |\n| `list_runners` | fleet, offline first | `/api/v4/runners/all` | — teaching error |\n| `runner_detail` | contacted_at, tags, paused | `/api/v4/runners/{id}` | — teaching error |\n| `list_merge_requests` | MRs / PRs | `.../merge_requests` | `.../pulls` |\n| `list_branches` | branches + last-commit date | `.../repository/branches` | `.../branches` |\n| `list_protected_branches` | protection rules + force-push flags | `.../protected_branches` | `.../branch_protections` |\n| `list_releases` | releases newest first | `.../releases` | `.../releases` |\n| `list_artifacts` | files, sizes, expiry, expired-but-kept | via `.../jobs` artifacts | `.../actions/artifacts` |\n\n## Flagship analyses (4, read-only, thresholds are parameters)\n\n| Tool | Flags | Key thresholds |\n|---|---|---|\n| `pipeline_failure_rca` | each failed job classified: test-failure / dependency-network / runner-timeout / oom / script-error, with matched evidence + action | `limit` (pipelines), `tail_lines` |\n| `runner_health_rca` | offline / stale / paused runners; long-queued jobs; saturated tags | `stale_contact_min` (30), `queue_sec` (300), `saturation_ratio` (2.0) |\n| `artifact_storage_bloat_analysis` | projects ranked by repo+artifact bytes; expired-but-kept; reclaimable estimate | `old_artifact_days` (30) |\n| `stale_work_audit` | idle open MRs; idle branches; unprotected default branch; force-push allowed | `stale_mr_days` (14), `stale_branch_days` (90) |\n\nAll four accept injected rows for pure/offline analysis, or pull live from a\ntarget. Classification order in `pipeline_failure_rca` is most-specific first:\nOOM > timeout > network > test > script; GitLab `failure_reason` values\n(`stuck_or_timeout_failure`, `runner_system_failure`, …) classify without a\ntrace.\n\n## Writes (6, governed, all with `dry_run`)\n\n| Tool | Risk | Prior state captured | Undo |\n|---|---|---|---|\n| `retry_pipeline` | medium | pipeline status | none (a retry is a new run) |\n| `cancel_pipeline` | medium | pipeline status | none (irreversible) |\n| `pause_runner` | medium | runner `paused` flag | `resume_runner` (skipped if it was already paused) |\n| `resume_runner` | medium | runner `paused` flag | `pause_runner` (skipped if it was not paused) |\n| `delete_artifacts` | **high** | artifact count + bytes destroyed | none (irreversible) |\n| `update_branch_protection` | medium | prior protection settings (or \"unprotected\") | replays this tool with the prior settings |\n\n`delete_artifacts(older_than_days=N)` deletes per-job only artifacts created\nbefore the cutoff; `0` uses GitLab's bulk-delete of eligible artifacts.\n\n## Safety plumbing\n\n- Every substituted URL path value is percent-encoded (`quote(..., safe=\"\")`);\n  Gitea's `owner/repo` keeps its `/` but each piece is encoded and empty /\n  `.` / `..` pieces are rejected (path-traversal defense).\n- All server-returned text passes an injection-safe normaliser (bounded string\n  length, capped nesting depth) before an agent sees it.\n- Non-2xx responses become teaching errors (what failed + what to check);\n  plain-text trace endpoints pass through as text.\n\nFile v0.10.1:references/cli-reference.md\n\n# cicd-aiops — CLI reference\n\nAll commands accept `--target/-t <name>` (default: the first target in\nconfig.yaml). Writes accept `--dry-run` and double-confirm before executing;\nconfirmed writes run through the same governed path as the MCP tools (audited).\n\n## Setup / health\n\n```bash\ncicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)\ncicd-aiops doctor               # config + secrets + connectivity + token-scope probe\ncicd-aiops doctor --skip-auth   # config/secrets checks only\ncicd-aiops overview             # version, identity, projects, runners\ncicd-aiops projects [--search x] [--limit N]\n```\n\n## Pipelines\n\n```bash\ncicd-aiops pipelines list <project> [--status failed] [--limit N]\ncicd-aiops pipelines show <project> <pipeline>\ncicd-aiops pipelines jobs <project> <pipeline>\ncicd-aiops pipelines trace <project> <job> [--lines 60]\ncicd-aiops pipelines retry <project> <pipeline> [--dry-run]    # governed write\ncicd-aiops pipelines cancel <project> <pipeline> [--dry-run]   # governed write\n```\n\n## Runners\n\n```bash\ncicd-aiops runners list [--status offline]\ncicd-aiops runners show <runner>\ncicd-aiops runners pause <runner> [--dry-run]     # governed write, undo-recorded\ncicd-aiops runners resume <runner> [--dry-run]    # governed write, undo-recorded\n```\n\n## Artifacts\n\n```bash\ncicd-aiops artifacts list <project>\ncicd-aiops artifacts delete <project> [--older-than-days 30] [--dry-run]\n# risk=high: requires CICD_AUDIT_APPROVED_BY (+ CICD_AUDIT_RATIONALE)\n```\n\n## Flagship RCAs\n\n```bash\ncicd-aiops rca pipelines <project> [--limit 10]   # classify failed pipelines\ncicd-aiops rca runners                            # offline/stale/saturation\ncicd-aiops rca storage [--old-days 30]            # bloat + reclaimable bytes\ncicd-aiops rca stale <project> [--mr-days 14] [--branch-days 90]\n```\n\n## Secrets\n\n```bash\ncicd-aiops secret set <target>      # store a token (encrypted)\ncicd-aiops secret list              # names only, never values\ncicd-aiops secret remove <target>\ncicd-aiops secret migrate           # legacy .env → encrypted store\n```\n\n## MCP\n\n```bash\ncicd-aiops mcp                      # start the MCP server (stdio)\n```\n\n## Environment variables\n\n| Var | Purpose |\n|---|---|\n| `CICD_AIOPS_HOME` | relocate config/audit/undo/secrets (default `~/.cicd-aiops`) |\n| `CICD_AIOPS_CONFIG` | explicit config.yaml path for the MCP server |\n| `CICD_AIOPS_MASTER_PASSWORD` | unlock secrets.enc non-interactively |\n| `CICD_AUDIT_APPROVED_BY` / `CICD_AUDIT_RATIONALE` | optional audit annotations (who/why) — recorded, never required |\n| `CICD_MAX_TOOL_CALLS` / `CICD_MAX_TOOL_SECONDS` | budget caps |\n| `CICD_RUNAWAY_MAX` / `CICD_RUNAWAY_WINDOW_SEC` | runaway breaker |\n| `CICD_<TARGET>_SECRET` | legacy plaintext token fallback (deprecated) |\n\nFile v0.10.1:references/setup-guide.md\n\n# cicd-aiops — setup guide\n\n## 1. Install\n\n```bash\nuv tool install cicd-aiops        # or: pip install cicd-aiops\n```\n\nRequires Python >= 3.11.\n\n## 2. Create a token on the server\n\n**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or\nproject) access token with the `api` scope. Runner administration\n(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an\nadmin-capable account.\n\n**Gitea (self-hosted)** — Settings → Applications → Generate new token. Grant\nread scopes for repository/issue and write where you want\n`update_branch_protection` to work.\n\nLeast privilege applies: a read-only token still powers every read and all\nfour RCAs; only the six write tools need write scopes.\n\n## 3. Onboard\n\n```bash\ncicd-aiops init\n```\n\nThe wizard asks for:\n\n1. **Master password** — encrypts `~/.cicd-aiops/secrets.enc` (Fernet +\n   scrypt). For MCP / non-interactive use export\n   `CICD_AIOPS_MASTER_PASSWORD=...`.\n2. **Target name** (e.g. `gl1`), **platform** (`gitlab` / `gitea`), and\n   **base URL** (e.g. `https://git.example.com` — scheme optional, added\n   automatically).\n3. **TLS verification** — defaults to **Yes**; answer No only for\n   self-signed lab certs.\n4. **Access token** — prompted hidden, stored encrypted, never in\n   config.yaml.\n\nResulting `~/.cicd-aiops/config.yaml`:\n\n```yaml\ntargets:\n  - name: gl1\n    platform: gitlab\n    base_url: https://git.example.com\n    verify_ssl: true\n  - name: gt1\n    platform: gitea\n    base_url: https://gitea.example.com\n    verify_ssl: true\n```\n\n## 4. Verify\n\n```bash\ncicd-aiops doctor\n```\n\nChecks per target: config present, encrypted store + token present, the\nserver's **version endpoint** answers, and a **token-scope probe**\n(`current_user`) confirms the token authenticates. A reachable server with a\ndud token is reported as unhealthy.\n\n## 5. MCP client config\n\n```json\n{\n  \"mcpServers\": {\n    \"cicd-aiops\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"cicd-aiops\", \"cicd-aiops-mcp\"],\n      \"env\": {\n        \"CICD_AIOPS_MASTER_PASSWORD\": \"your-master-password\"\n      }\n    }\n  }\n}\n```\n\nMCP clients do not source your shell profile — set\n`CICD_AIOPS_MASTER_PASSWORD` in the `env` block.\n\n## Audit-annotation env vars (optional)\n\nThe skill does not decide whether a write is permitted — that is the agent's\njudgement or the connecting token's scope. If you want the audit trail to record\n*who* ran a destructive op and *why*, set these; they are recorded on the row,\nnever required, and gate nothing:\n\n```bash\nexport CICD_AUDIT_APPROVED_BY='you@example.com'\nexport CICD_AUDIT_RATIONALE='why this destructive op is justified'\n```\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---|---|\n| `401/403` in doctor | token expired or missing `api` scope — reissue and `cicd-aiops secret set <target>` |\n| `Could not reach ...` | check `base_url`, VPN/network path, and that the API is enabled |\n| self-signed cert errors | re-run `init` and answer No to TLS verify (lab only) |\n| `Resource ... not available on platform 'gitea'` | expected: runner admin / pipeline retry / artifact delete are GitLab surfaces in v0.1 |\n| a write fails with `403` | the token lacks the write scope — reissue with write access (or keep it read-only by design) |\n\nFile v0.10.1:skill-card.md\n\n## Description:\n\nCICD AIops helps agents inspect, troubleshoot, and perform governed operations on self-managed GitLab and self-hosted Gitea CI/CD servers.\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 and operations engineers use this skill to inspect CI/CD server state, diagnose failed pipelines, runner capacity, artifact storage, and stale repository work, then perform governed remediation actions when appropriate.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can make high-impact GitLab or Gitea changes without built-in read-only or approval enforcement.\n\nMitigation: Use read-only or narrowly scoped tokens by default, reserve write or admin-capable tokens for specific tasks, and review every write before execution.\n\nRisk: Destructive CI/CD operations can delete artifacts or otherwise change server state.\n\nMitigation: Run destructive actions only after a dry-run preview, require a clear operator rationale, and avoid broad deletion scopes unless the preview matches the intended maintenance window.\n\nRisk: Credential handling can expose the master password if it is placed in shared, synced, or source-controlled MCP configuration.\n\nMitigation: Keep the master password out of shared files and source control, and provide it through local secret management or narrowly scoped runtime environment injection.\n\n## Reference(s):\n\n- [CICD-AIops GitHub repository](https://github.com/AIops-tools/CICD-AIops)\n- [Capabilities reference](references/capabilities.md)\n- [CLI reference](references/cli-reference.md)\n- [Setup 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 guidance with inline shell commands, configuration snippets, and structured operational findings]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include CI/CD RCA findings, dry-run recommendations, audit guidance, and platform-specific limitations.]\n\n## Skill Version(s):\n\n0.10.1 (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.10.0: 7 files, 19202 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4930b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2901b), SKILL.md (16605b), _meta.json (130b)\n\nFile v0.10.0:SKILL.md\n\n---\nname: cicd-aiops\nslug: cicd-aiops\ndisplayName: \"CICD AIops\"\nsummary: \"Governed self-managed GitLab + Gitea CI/CD ops: pipelines, runners, artifacts, RCA. 28 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/CICD-AIops\ntags: [aiops, mcp, governance, cicd]\ndescription: >\n  Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection).\n  Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance.\n  Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances.\n  Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).\ninstaller:\n  kind: uv\n  package: cicd-aiops\nargument-hint: \"[a project path, pipeline/runner id, or describe your CI/CD task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"cicd-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CICD_AIOPS_CONFIG\",\"CICD_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/CICD-AIops\",\"emoji\":\"🔁\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via \"Authorization: token\"). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).\n  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.\n  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double confirmation and is irreversible (priorState records the destroyed count/bytes). Reversible writes (pause_runner/resume_runner as an undo pair; update_branch_protection replaying prior settings) capture the real fetched before-state and record an inverse undo descriptor; retry_pipeline/cancel_pipeline record priorState (the pipeline's prior status) only.\n  Webhooks: none — no outbound network calls beyond the configured GitLab / Gitea REST API.\n  SSL: verify_ssl defaults to ON; the init wizard asks before disabling it for self-signed lab certs.\n  Transitive dependencies: httpx (HTTP client) and the MCP SDK. No post-install scripts or background services.\n  Verification status: mock-validated; no recorded end-to-end run against a live server yet, and the modelled REST paths are the largest verification debt. Both GitLab CE and Gitea are free/self-hostable (each runs from a container), so a home lab is the cheapest live check. See docs/VERIFICATION.md.\n---\n\n# CICD AIops\n\n> **Disclaimer**: Community-maintained open-source project, **not affiliated with, endorsed by, or sponsored by GitLab Inc. or the Gitea project.** GitLab and Gitea are trademarks of their respective owners. Source at [github.com/AIops-tools/CICD-AIops](https://github.com/AIops-tools/CICD-AIops) under the MIT license.\n\nGoverned CI/CD operations — **28 MCP tools** across **self-managed GitLab** (REST\n`/api/v4/...`) and **self-hosted Gitea** (API `/api/v1/...`), every one wrapped with\nthe bundled `@governed_tool` harness: a local unified audit log under\n`~/.cicd-aiops/`, token/runaway budget guard, undo-token recording, and\ndescriptive risk tiers. A per-target `platform` field selects the API shape, so\nthe same tools work on both servers and one config can span a mixed estate. The\naccess token is stored **encrypted** (`~/.cicd-aiops/secrets.enc`, Fernet +\nscrypt) — never plaintext on disk.\n\n> **Standalone**: the governance harness is bundled in the package\n> (`cicd_aiops.governance`) — no external skill-family dependency. Both\n> platforms are free/self-hostable, so a home lab is the cheapest live check;\n> verification status and the checklist are in `docs/VERIFICATION.md`.\n\n## What This Skill Does\n\n| Group | Tools | Count | R/W |\n|-------|-------|:-----:|:---:|\n| **Server** | server_version, current_user, cicd_overview | 3 | read |\n| **Projects** | list_projects, project_detail | 2 | read |\n| **Pipelines** | list_pipelines, pipeline_detail, pipeline_jobs, job_trace_tail | 4 | read |\n| **Runners** | list_runners, runner_detail | 2 | read |\n| **Repo surface** | list_merge_requests, list_branches, list_protected_branches, list_releases | 4 | read |\n| **Artifacts** | list_artifacts | 1 | read |\n| **Flagship analyses** | pipeline_failure_rca, runner_health_rca, artifact_storage_bloat_analysis, stale_work_audit | 4 | read |\n| **Writes** | retry_pipeline, cancel_pipeline, pause_runner, resume_runner, update_branch_protection | 5 | write (med) |\n| **Writes** | delete_artifacts | 1 | write (**high**) |\n| **Undo** | undo_list, undo_apply | 2 | read + replay |\n\nThe four flagship analyses are transparent heuristics that report their numbers,\nnever a black-box verdict: `pipeline_failure_rca` classifies each failed job from\nits failure_reason + trace-tail markers (test-failure / dependency-network /\nrunner-timeout / oom / script-error) with matched evidence; `runner_health_rca`\nflags offline/stale/paused runners, long-queued jobs, and per-tag saturation;\n`artifact_storage_bloat_analysis` ranks projects by repo + artifact bytes and\nestimates reclaimable bytes; `stale_work_audit` flags idle MRs/branches and\nprotection gaps.\n\n## Quick Install\n\n```bash\nuv tool install cicd-aiops\ncicd-aiops init       # wizard: pick platform (gitlab/gitea) + base URL + encrypted token\ncicd-aiops doctor     # version endpoint + token-scope probe per target\n```\n\n## When to Use This Skill\n\n- Get a one-shot snapshot (`overview` / `server_version` / `current_user`)\n- Answer \"why is CI red?\" (`rca pipelines` / `pipeline_failure_rca`) → cause +\n  action per failed pipeline, with the trace evidence that drove the call\n- Find wedged capacity (`rca runners` / `runner_health_rca`) → offline/stale\n  runners, long-queued jobs, saturated tags\n- Reclaim disk (`rca storage` / `artifact_storage_bloat_analysis`) → ranked\n  projects + reclaimable bytes, feeding `delete_artifacts --dry-run`\n- Repo hygiene (`rca stale` / `stale_work_audit`) → idle MRs/branches,\n  unprotected default branch, force-push gaps\n- Safely act: `retry_pipeline` / `cancel_pipeline`, `pause_runner` /\n  `resume_runner` (undo pair), `update_branch_protection` (undo replays prior\n  settings), `delete_artifacts` (risk=high, dry-run + double confirm)\n\n**Do NOT use when** the target is not a GitLab/Gitea CI/CD server — route\nhypervisor, storage, backup, database, network, or OT/industrial work to the\nappropriate other AIops-tools skill.\n\n## Related Skills — Skill Routing\n\n| If the user wants… | Use |\n|--------------------|-----|\n| Self-managed GitLab / Gitea CI/CD ops | **cicd-aiops** (this skill) |\n| Kubernetes deploy state (what the cluster is actually running) | **k8s-aiops** |\n| A non-CI/CD platform (hypervisor, storage, backup, database, network, OT edge) | the appropriate **other AIops-tools** skill |\n| GitLab.com / Gitea Cloud SaaS accounts | out of scope for this tool |\n\n## Common Workflows\n\nEach recipe starts from one of the four RCAs and ends in a governed write.\nEvery CLI write accepts `--dry-run` and otherwise double-confirms. Note that\nrunner administration and pipeline retry/cancel are **GitLab-only** — on a\nGitea target those tools raise a teaching error listing what is available.\n\n### 1. \"The nightly pipeline has been red for three days\"\n\n1. `cicd-aiops pipelines list dev/api --status failed -n 20` → the recent\n   failed pipelines, newest first.\n2. `cicd-aiops rca pipelines dev/api` → each failed job classified from its\n   `failure_reason` plus trace-tail markers: test-failure, dependency-network,\n   runner-timeout, OOM, or script-error, with the evidence and a suggested\n   action.\n3. `cicd-aiops pipelines jobs dev/api <pipeline-id>` → which stage and job the\n   classification came from.\n4. `cicd-aiops pipelines trace dev/api <job-id> -n 120` → the actual log tail,\n   so you confirm the classification instead of trusting it.\n5. Fix the cause. If the RCA said the failure was transient (dependency-network\n   or runner-timeout): `cicd-aiops pipelines retry dev/api <pipeline-id>\n   --dry-run`, then re-run for real (double confirm).\n6. `cicd-aiops rca pipelines dev/api` again to confirm the class of failure is\n   gone rather than merely quieter.\n\n**Failure branch**: if the RCA classifies the failures as **test-failure** or\n**script-error**, do not retry — the code is broken and a retry burns runner\nminutes to reach the same red. Retry is only honest for transient classes. If\nthe retry itself fails to submit on a Gitea target, that is the teaching error:\nretry/cancel have no Gitea API v1 equivalent, so re-run the job from the Gitea\nUI instead.\n\n### 2. \"Jobs are sitting in the queue and nothing is picking them up\"\n\n1. `cicd-aiops runners list --status offline` and `--status paused` → the\n   obvious suspects first.\n2. `cicd-aiops rca runners` → stale contact ages, long-queued jobs, and **which\n   tag is saturated** (queued jobs versus online runners carrying that tag).\n3. `cicd-aiops runners show <runner-id>` → the specific runner's tags, last\n   contact and status.\n4. If a needed runner was paused: `cicd-aiops runners resume <runner-id>\n   --dry-run`, then for real (reversible — an inverse `pause_runner` is\n   recorded).\n5. If a wedged runner is grabbing jobs and failing them: `cicd-aiops runners\n   pause <runner-id>` to take it out of rotation (reversible — inverse\n   `resume_runner` recorded).\n6. `cicd-aiops rca runners` again to confirm the queue is draining.\n\n**Failure branch**: if the RCA shows a **saturated tag** rather than a\ndown runner, resuming runners will not help — no online runner carries the tag\nthose jobs require, so you need to add or retag capacity. And if you paused a\nrunner and the queue got worse, `cicd-aiops undo apply <id>` resumes exactly\nthe runner you paused. Runner administration is GitLab-only; a Gitea target\nraises a teaching error here.\n\n### 3. \"The CI server is out of disk\"\n\n1. `cicd-aiops rca storage --old-days 30` → projects ranked by repo + artifact\n   bytes with a reclaimable estimate at that age threshold.\n2. `cicd-aiops artifacts list dev/api` → the actual artifact files, their sizes\n   and their expiry, so you see what \"reclaimable\" really refers to.\n3. `cicd-aiops projects --limit 50` → cross-check that the top consumer is the\n   project you expect.\n4. `cicd-aiops artifacts delete dev/api --older-than-days 30 --dry-run` →\n   shows the scope, deletes nothing.\n5. Re-run without `--dry-run`: double confirm, **high** risk. Optionally set\n   `CICD_AUDIT_APPROVED_BY` + `CICD_AUDIT_RATIONALE` to annotate who/why on the\n   audit row. This is **irreversible** — priorState records the destroyed count\n   and bytes for the audit trail, but there is no undo.\n6. `cicd-aiops rca storage` again to confirm the reclaimed bytes landed.\n\n**Failure branch**: never run `artifacts delete` with `--older-than-days 0` as\na first move — 0 means **ALL** artifacts, including the ones a release or a\nrunning deploy depends on. If the dry-run scope reads \"ALL\" and you did not\nintend that, stop and set an age. Since there is no undo for this operation,\nthe dry-run is the only safety net you get; if the bloat is mostly **repo**\nbytes rather than artifact bytes, deleting artifacts will not help at all.\n\n### 4. \"Tighten repo hygiene before the release freeze\"\n\n1. `cicd-aiops rca stale dev/api --mr-days 14 --branch-days 60` → stale open\n   merge requests, idle branches, and **protection gaps** such as an\n   unprotected default branch or force-push left allowed.\n2. Confirm the current state via MCP `list_protected_branches` and\n   `list_branches` for the project.\n3. MCP `list_merge_requests` → the stale MRs the audit named, so you can close\n   or revive them with their owners rather than in bulk.\n4. Close the protection gap with MCP `update_branch_protection` (e.g.\n   `allow_force_push=False` on the default branch) — it fetches and captures\n   the prior settings and records an undo that replays them exactly.\n5. `cicd-aiops undo list` → confirm the protection change is reversible.\n6. `cicd-aiops rca stale dev/api` again to confirm the gap closed.\n\n**Failure branch**: if tightening protection blocks a legitimate workflow — a\nrelease automation that force-pushes tags, say — `cicd-aiops undo apply <id>`\nrestores the exact prior protection settings rather than a guessed default.\nFix the automation before re-applying, and do not disable protection\nfleet-wide to unblock one job.\n\n## Governance & 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 token you connect it with (a GitLab/Gitea access token without write\nscope — writes then fail at the server). There is no read-only switch, policy\nfile, or approval gate.\n\n- **Audit is the guarantee, and it is not bypassable.** Every operation — MCP and CLI alike — is logged to `~/.cicd-aiops/audit.db` (relocatable via `CICD_AIOPS_HOME`): params, result, status, duration, and the risk tier. The CLI writes the same row the MCP path does.\n- `CICD_AUDIT_APPROVED_BY` / `CICD_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: the same call looped in a tight window trips a circuit breaker. Disable with `CICD_RUNAWAY_MAX=0`.\n- Destructive writes support `--dry-run` / `dry_run=True` and double confirmation at the CLI. `delete_artifacts` is irreversible (priorState records the destroyed count/bytes; audit only).\n- Reversible writes fetch the real before-state and record an inverse descriptor (pause_runner↔resume_runner, update_branch_protection→prior settings); irreversible ops (retry_pipeline, cancel_pipeline, delete_artifacts) record only the before-state.\n\n## References\n\n- `references/capabilities.md` — full tool + platform + API-path reference\n- `references/cli-reference.md` — CLI command reference\n- `references/setup-guide.md` — onboarding, credentials, and connectivity\n- `references/agent-guardrails.md` — wh\n\nArchive v0.9.0: 7 files, 19217 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4930b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2760b), SKILL.md (16704b), _meta.json (129b)\n\nArchive v0.8.0: 7 files, 19173 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4930b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2674b), SKILL.md (16704b), _meta.json (129b)\n\nArchive v0.7.0: 7 files, 19143 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4874b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2799b), SKILL.md (16704b), _meta.json (129b)\n\nArchive v0.6.0: 7 files, 19050 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4874b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2626b), SKILL.md (16704b), _meta.json (129b)\n\nArchive v0.5.0: 7 files, 19270 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4874b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (3140b), SKILL.md (16704b), _meta.json (129b)\n\nArchive v0.4.0: 7 files, 19212 bytes\n\nFiles: references/agent-guardrails.md (10681b), references/capabilities.md (4874b), references/cli-reference.md (2806b), references/setup-guide.md (3259b), skill-card.md (2996b), SKILL.md (16704b), _meta.json (129b)","readmeExcerpt":"Skill: cicd-aiops Owner: zw008 Summary: Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures,","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"uv tool install cicd-aiops\ncicd-aiops init       # wizard: pick platform (gitlab/gitea) + base URL + encrypted token\ncicd-aiops doctor     # version endpoint + token-scope probe per target"},{"language":"bash","snippet":"openclaw plugins install clawhub:@zw008/cicd-aiops\nopenclaw skills info cicd-aiops          # expect: Visible to model: yes"},{"language":"text","snippet":"You operate self-managed GitLab / Gitea CI/CD servers through the cicd-aiops\nMCP tools.\n\nTOOL USE\n- Before answering any question about the current CI/CD environment, 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- Some tools exist only on GitLab (runner list/detail/pause/resume, pipeline\n  retry/cancel, artifact deletion). On a Gitea target they return a teaching\n  error listing what IS available. That is a final answer about the platform,\n  not a transient failure: do not retry it, do not call it broken. Say the\n  platform has no such API and answer from another surface.\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. On the analyses \"truncated\" is a per-list\n  object — check each entry.\n- A null field means the server did not return that value. Report it as \"not\n  available\" — never infer it, and never report it as zero. In particular:\n  runnersSupported=false means \"this platform has no runner API\", and\n  artifactsBytesKnown=false means artifact storage was not measured.\n- A job trace is only the TAIL of the log. When \"truncated\" is true the first\n  error may be above the window — raise tail_lines before naming a root cause.\n- Report values exactly as returned. Do not normalise, translate, or prettify\n  status strings, branch names, or IDs.\n- Work RCA findings in the order returned and cite the measured number each\n  finding carries (\"evidence\", \"cause\", byte counts, queue seconds).\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, sto"},{"language":"bash","snippet":"# e.g. use a GitLab/Gitea access token without write scope. Then:\ncicd-aiops doctor"},{"language":"bash","snippet":"export CICD_AUDIT_APPROVED_BY=\"your.name@example.com\"\nexport CICD_AUDIT_RATIONALE=\"scheduled maintenance window 2026-07-20\""},{"language":"bash","snippet":"cicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)\ncicd-aiops doctor               # config + secrets + connectivity + token-scope probe\ncicd-aiops doctor --skip-auth   # config/secrets checks only\ncicd-aiops overview             # version, identity, projects, runners\ncicd-aiops projects [--search x] [--limit N]"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: cicd-aiops\nslug: cicd-aiops\ndisplayName: \"CICD AIops\"\nsummary: \"Governed self-managed GitLab + Gitea CI/CD ops: pipelines, runners, artifacts, RCA. 28 tools.\"\nlicense: MIT\nhomepage: https://github.com/AIops-tools/CICD-AIops\ntags: [aiops, mcp, governance, cicd]\ndescription: >\n  Use this skill whenever the user needs to operate a self-managed GitLab or self-hosted Gitea CI/CD server — a one-shot overview, server version and token identity, projects with storage statistics, pipelines/runs with jobs and trace tails, the runner fleet, merge/pull requests, branches, protection rules and releases, artifact inventories, four flagship RCAs (pipeline failures, runner health & queue, artifact/storage bloat, stale work), and governed writes (retry/cancel a pipeline, pause/resume a runner, delete artifacts, update branch protection).\n  Always use this skill for \"GitLab\", \"Gitea\", \"pipeline failed\", \"CI is red\", \"job trace\", \"runner offline\", \"jobs stuck in queue\", \"artifact storage full\", \"stale merge requests\", \"stale branches\", \"protect the default branch\", \"retry the pipeline\", \"cancel the pipeline\", \"delete old artifacts\" when the context is a self-managed GitLab or Gitea instance.\n  Do NOT use when the target is something other than a GitLab/Gitea CI/CD server (a hypervisor, storage appliance, backup product, database, network gear, or OT/industrial equipment) — route those to the appropriate other AIops-tools skill. Do NOT use for Kubernetes deploy state — use k8s-aiops. GitLab.com / Gitea Cloud SaaS accounts are out of scope: this tool targets self-managed instances.\n  Governed CI/CD operations with a built-in governance harness (audit, policy, token budget, undo, risk-tiers).\ninstaller:\n  kind: uv\n  package: cicd-aiops\nargument-hint: \"[a project path, pipeline/runner id, or describe your CI/CD task]\"\nallowed-tools:\n  - Bash\nmetadata: {\"openclaw\":{\"requires\":{\"anyBins\":[\"cicd-aiops\",\"uvx\"]},\"optional\":{\"env\":[\"CICD_AIOPS_CONFIG\",\"CICD_AIOPS_MASTER_PASSWORD\"]},\"homepage\":\"https://github.com/AIops-tools/CICD-AIops\",\"emoji\":\"🔁\",\"os\":[\"macos\",\"linux\"]}}\ncompatibility: >\n  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via \"Authorization: token\"). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).\n  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secr"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7b067awq2s97bn3d7p5qfhw5827pxc\",\n  \"slug\": \"cicd-aiops\",\n  \"version\": \"0.10.3\",\n  \"publishedAt\": 1789451311953\n}"},{"path":"references/agent-guardrails.md","content":"# Agent guardrails — running cicd-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 token you connect with.** Give it a GitLab/Gitea access token without\n  write scope. A write then fails at the server, which is the only place the\n  permission actually lives — no skill-side flag can be argued around by a\n  model, but a token without the scope cannot be.\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| \"Log everything you do, over both MCP and the CLI\" | Every call is audited to `~/.cicd-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. Reversible writes also record an undo token capturing the *prior* state. |\n| \"Don't invent a value when a field is missing\" | A field the server did not return comes back as `null`, never as `\"\"`. A pipeline with no `ref`, a job with no `startedAt` or `failureReason`, a runner that has never reported `contactedAt` — all stay `null`, and the key is always present. |\n| \"Tell me if the output was cut off\" | Every listing returns `{\"<items>\": [...], \"returned\": N, \"limit\": L, \"truncated\": true/false}`. Truncation is **measured** (one extra row is fetched), never guessed from a full page. `job_trace_tail` adds `charsTruncated` for the byte ceiling. |\n| \"Tell me if a number is unknown rather than zero\" | Storage numbers a platform does not report come back as `null` with `artifactsBytesKnown: false`, and `artifact_storage_bloat_analysis` counts them in `artifactBytesUnavailable`. `cicd_overview` reports `runnersSupported`. |\n| \"Confirm before anything destructive\" | Destructive operations require a `--dry-run`-able preview + double confirmation at the CLI. |\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 tim"},{"path":"references/capabilities.md","content":"# cicd-aiops — capabilities reference\n\n28 governed MCP tools over two platforms (16 reads + 4 analyses + 6 writes +\n`undo_list`/`undo_apply`). Every tool takes an optional\n`target` (a name from `~/.cicd-aiops/config.yaml`); writes also take\n`dry_run: bool`.\n\n## Platforms\n\n| Platform | API | Auth | Project addressing |\n|---|---|---|---|\n| `gitlab` | REST v4 (`/api/v4/...`) | `PRIVATE-TOKEN: <token>` | numeric id or URL-encoded full path (`group%2Fproject`) |\n| `gitea` | API v1 (`/api/v1/...`) | `Authorization: token <token>` | `owner/repo` (two path segments) |\n\nSelf-managed/self-hosted instances only. Where Gitea lacks a surface, the\nplatform registry raises a teaching `KeyError` naming the resources that ARE\navailable: runner administration, pipeline retry/cancel, and artifact deletion\nare GitLab-only in v0.1.\n\n## Reads (16)\n\n| Tool | What it returns | GitLab path | Gitea path |\n|---|---|---|---|\n| `server_version` | version + revision | `/api/v4/version` | `/api/v1/version` |\n| `current_user` | token identity (scope probe) | `/api/v4/user` | `/api/v1/user` |\n| `cicd_overview` | version + identity + projects + runners | (composite) | (composite) |\n| `list_projects` | projects w/ storage bytes | `/api/v4/projects?statistics=true` | `/api/v1/repos/search` |\n| `project_detail` | one project incl. sizes | `/api/v4/projects/{p}` | `/api/v1/repos/{owner}/{repo}` |\n| `list_pipelines` | recent pipelines/runs | `/api/v4/projects/{p}/pipelines` | **unsupported** — Gitea API v1 has no run-level resource |\n| `pipeline_detail` | one pipeline/run | `.../pipelines/{id}` | **unsupported** (same reason) |\n| `pipeline_jobs` | jobs + failure_reason | `.../pipelines/{id}/jobs` | **unsupported**; the per-job listing is `/actions/tasks` |\n| `job_trace_tail` | last N log lines | `.../jobs/{id}/trace` | `.../actions/jobs/{id}/logs` |\n| `list_runners` | fleet, offline first | `/api/v4/runners/all` | — teaching error |\n| `runner_detail` | contacted_at, tags, paused | `/api/v4/runners/{id}` | — teaching error |\n| `list_merge_requests` | MRs / PRs | `.../merge_requests` | `.../pulls` |\n| `list_branches` | branches + last-commit date | `.../repository/branches` | `.../branches` |\n| `list_protected_branches` | protection rules + force-push flags | `.../protected_branches` | `.../branch_protections` |\n| `list_releases` | releases newest first | `.../releases` | `.../releases` |\n| `list_artifacts` | files, sizes, expiry, expired-but-kept | via `.../jobs` artifacts | `.../actions/artifacts` |\n\n## Flagship analyses (4, read-only, thresholds are parameters)\n\n| Tool | Flags | Key thresholds |\n|---|---|---|\n| `pipeline_failure_rca` | each failed job classified: test-failure / dependency-network / runner-timeout / oom / script-error, with matched evidence + action | `limit` (pipelines), `tail_lines` |\n| `runner_health_rca` | offline / stale / paused runners; long-queued jobs; saturated tags | `stale_contact_min` (30), `queue_sec` (300), `saturation_ratio` (2.0) |\n| `artifact_storage"},{"path":"references/cli-reference.md","content":"# cicd-aiops — CLI reference\n\nAll commands accept `--target/-t <name>` (default: the first target in\nconfig.yaml). Writes accept `--dry-run` and double-confirm before executing;\nconfirmed writes run through the same governed path as the MCP tools (audited).\n\n## Setup / health\n\n```bash\ncicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)\ncicd-aiops doctor               # config + secrets + connectivity + token-scope probe\ncicd-aiops doctor --skip-auth   # config/secrets checks only\ncicd-aiops overview             # version, identity, projects, runners\ncicd-aiops projects [--search x] [--limit N]\n```\n\n## Pipelines\n\n```bash\ncicd-aiops pipelines list <project> [--status failed] [--limit N]\ncicd-aiops pipelines show <project> <pipeline>\ncicd-aiops pipelines jobs <project> <pipeline>\ncicd-aiops pipelines trace <project> <job> [--lines 60]\ncicd-aiops pipelines retry <project> <pipeline> [--dry-run]    # governed write\ncicd-aiops pipelines cancel <project> <pipeline> [--dry-run]   # governed write\n```\n\n## Runners\n\n```bash\ncicd-aiops runners list [--status offline]\ncicd-aiops runners show <runner>\ncicd-aiops runners pause <runner> [--dry-run]     # governed write, undo-recorded\ncicd-aiops runners resume <runner> [--dry-run]    # governed write, undo-recorded\n```\n\n## Artifacts\n\n```bash\ncicd-aiops artifacts list <project>\ncicd-aiops artifacts delete <project> [--older-than-days 30] [--dry-run]\n# risk=high: requires CICD_AUDIT_APPROVED_BY (+ CICD_AUDIT_RATIONALE)\n```\n\n## Flagship RCAs\n\n```bash\ncicd-aiops rca pipelines <project> [--limit 10]   # classify failed pipelines\ncicd-aiops rca runners                            # offline/stale/saturation\ncicd-aiops rca storage [--old-days 30]            # bloat + reclaimable bytes\ncicd-aiops rca stale <project> [--mr-days 14] [--branch-days 90]\n```\n\n## Secrets\n\n```bash\ncicd-aiops secret set <target>      # store a token (encrypted)\ncicd-aiops secret list              # names only, never values\ncicd-aiops secret remove <target>\ncicd-aiops secret migrate           # legacy .env → encrypted store\n```\n\n## MCP\n\n```bash\ncicd-aiops mcp                      # start the MCP server (stdio)\n```\n\n## Environment variables\n\n| Var | Purpose |\n|---|---|\n| `CICD_AIOPS_HOME` | relocate config/audit/undo/secrets (default `~/.cicd-aiops`) |\n| `CICD_AIOPS_CONFIG` | explicit config.yaml path for the MCP server |\n| `CICD_AIOPS_MASTER_PASSWORD` | unlock secrets.enc non-interactively |\n| `CICD_AUDIT_APPROVED_BY` / `CICD_AUDIT_RATIONALE` | optional audit annotations (who/why) — recorded, never required |\n| `CICD_MAX_TOOL_CALLS` / `CICD_MAX_TOOL_SECONDS` | budget caps |\n| `CICD_RUNAWAY_MAX` / `CICD_RUNAWAY_WINDOW_SEC` | runaway breaker |\n| `CICD_<TARGET>_SECRET` | legacy plaintext token fallback (deprecated) |"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":2205,"uniquenessScore":39,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T07:30:40.929Z","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-10T07:30:40.929Z","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:44:35.865Z","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"}]}}}