{
  "schema": "snappy-card/1",
  "skill": "snappy-watchtower",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "Standing error monitors, and the probes that lie. Read `SKILL.md` for the full",
  "verbs": [],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [],
  "checks": {
    "pass": 26,
    "fail": 8,
    "defer": 27,
    "line": "26 of 34 checks pass",
    "failing": [
      {
        "id": 4,
        "rule": "Near-neighbour descriptions cross-reference each other",
        "says": "near neighbours not named: snappy-client-feisst, snappy-runner, snappy-specwatch"
      },
      {
        "id": 5,
        "rule": "Description is valid, third-person, and says what plus when",
        "says": "first/second person"
      },
      {
        "id": 7,
        "rule": "Promised and declared verbs have no set difference",
        "says": "promised-only=[contract]; loader-missing=[]"
      },
      {
        "id": 9,
        "rule": "Time-sensitive prose is isolated under Old patterns",
        "says": "1 time-sensitive instruction line(s) outside Old patterns"
      },
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path"
      },
      {
        "id": 40,
        "rule": "Metadata, skill body, and resources follow three-level budgets",
        "says": "metadata ~215 tokens; body ~3365 tokens"
      },
      {
        "id": 55,
        "rule": "Eval scenarios are multi-call with ground truth",
        "says": "eval manifest missing"
      },
      {
        "id": 57,
        "rule": "Eval manifest contains a disjoint holdout",
        "says": "0 disjoint holdout scenario(s)"
      }
    ]
  },
  "coverage": null,
  "spec": null,
  "evals": null,
  "files": [
    "AGENTS.md",
    "SKILL.md",
    "api.ts",
    "refusals.test.ts"
  ],
  "total_size": 28475,
  "checksum": "sha256:ddbb037f582166deedbaab11475ef2f7e189ba88e5c97c5361a5dabb6779fb08",
  "built_at": "2026-09-09T22:11:26.787Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-watchtower",
      "version": "0.0.0",
      "description": "Standing error monitors and the probes that lie: arm live typecheck, build, and test monitors at session start, plus the dated list of git, Vitest, install, deploy, twin-tree, and probe traps where a green result meant nothing, each with the exact command that avoids it. Use when Robert says: /snappy-watchtower, \\\"set up the monitor with the feedback from errors\\\", \\\"the monitor is helping, keep the live loop going\\\", \\\"200 doesn't mean an agent system is working\\\", \\\"is it working\\\", \\\"is it actually working now\\\", \\\"it says green but it is broken\\\", \\\"keep the building/typechecking over there\\\", \\\"explain your monitor to the other team\\\". Triggers on: watchtower, monitor, typecheck watch, green but broken, probe trap, standing monitor. NOT the overnight orchestration itself (see snappy-nightshift). NOT app-level dogfooding (see snappy-resident)."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-watchtower/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {},
    "components": {
      "schemas": {
        "SnappyRefusal": {
          "type": "object",
          "required": [
            "outcome",
            "code",
            "message"
          ],
          "properties": {
            "outcome": {
              "type": "string",
              "const": "refused"
            },
            "code": {
              "type": "string",
              "description": "A row of the closed refusal table."
            },
            "message": {
              "type": "string"
            },
            "fix": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}