{
  "schema": "snappy-card/1",
  "skill": "snappy-corpus",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "You are working inside Robert's content engine. Every published artifact (carousel, blog, DM, sales asset) must ultimately trace back to something Robert actually said in a Krisp transcript. This loader covers the rules. Read SKILL.md only if you need the full architecture rationale.",
  "verbs": [
    {
      "name": "list",
      "args": [
        "year?",
        "month?"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-corpus/api.ts list"
    },
    {
      "name": "read",
      "args": [
        "path",
        "offset?"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-corpus/api.ts read <path>"
    },
    {
      "name": "search",
      "args": [
        "query"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-corpus/api.ts search \"<query>\""
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [
    "snappy-course"
  ],
  "checks": {
    "pass": 41,
    "fail": 6,
    "defer": 14,
    "line": "41 of 47 checks pass",
    "failing": [
      {
        "id": 4,
        "rule": "Near-neighbour descriptions cross-reference each other",
        "says": "near neighbours not named: snappy-client-feisst, snappy-specwatch"
      },
      {
        "id": 5,
        "rule": "Description is valid, third-person, and says what plus when",
        "says": "first/second person"
      },
      {
        "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 ~173 tokens; body ~1961 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.test.ts",
    "api.ts",
    "contract.test.ts",
    "scripts/make-summaries.py",
    "scripts/persist-batch.py"
  ],
  "total_size": 34206,
  "checksum": "sha256:a6b7974db5e4a90efc3a8daa88f73f8efcede323b1b4c0fe96455f6db09cb3c0",
  "built_at": "2026-09-09T22:08:30.053Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-corpus",
      "version": "0.0.0",
      "description": "The Krisp transcript corpus + nugget mining pipeline: import calls into the corpus, find quotes, stories, objections, and frames, check nugget reuse; where every Snappy idea, quote, and frame ultimately comes from. Use when Robert says: /snappy-corpus, 'what else did we miss from the transcript', 'rebuild the laws file from the transcript', 'it has too many old quotes, use them as data to derive the best decision', 'read the project and the krisp meetings and help me prepare', 'find a quote from a call about X', 'mine the transcripts for nuggets'. NOT single-meeting lookup or action items (see snappy-krisp, snappy-transcripts). NOT technical-framework extraction (see snappy-mine)."
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-corpus/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/list": {
        "get": {
          "operationId": "snappy_corpus_list",
          "summary": "snappy-corpus list",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "year",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "Four-digit year to list; omit for every year",
                "x-snappy-position": 0
              }
            },
            {
              "name": "month",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "Month number 1-12; omit for the whole year",
                "x-snappy-position": 1
              }
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "How many transcripts to return, newest first. The count is the FLAG --limit, never a positional word; default 20, ceiling 200",
                "default": 20,
                "minimum": 1,
                "maximum": 200,
                "x-snappy-flag": "--limit"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/read": {
        "get": {
          "operationId": "snappy_corpus_read",
          "summary": "snappy-corpus read",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "path",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Corpus file path to read",
                "x-snappy-position": 0
              }
            },
            {
              "name": "offset",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "First line to return, zero-based",
                "default": 0,
                "x-snappy-position": 1
              }
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "How many lines to return; the count is the FLAG --limit, never the third word",
                "default": 200,
                "maximum": 2000,
                "x-snappy-flag": "--limit"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/search": {
        "get": {
          "operationId": "snappy_corpus_search",
          "summary": "snappy-corpus search",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": false
          },
          "parameters": [
            {
              "name": "query",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Text searched for across the corpus",
                "x-snappy-position": 0
              }
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "How many matches to return. The count is the FLAG --limit, never a positional word; default 20, ceiling 200",
                "default": 20,
                "minimum": 1,
                "maximum": 200,
                "x-snappy-flag": "--limit"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      }
    },
    "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"
            }
          }
        }
      }
    }
  }
}