TfP Docs

SkillVersion schema

Generated from the canonical schema schemas/skill-version.schema.json by scripts/generate-schema-docs.mjs — do not edit this page by hand.

Canonical (Stage 3A, owner-approved 2026-09-01). One immutable snapshot of an exact Agent Skills-compatible package directory (agentskills.io). TfP validates the package against the open specification, snapshots the exact contents into its own immutable store, and records upstream provenance when the package was imported — so a ProblemRevision pin is reproducible even if the upstream source disappears or changes. Registry version identity is TfP's sequential version_number, independent of any version string inside the package's own metadata (which is preserved unchanged inside the package). name/description/license/compatibility are the Agent Skills frontmatter fields extracted verbatim for indexing; the package itself remains the source of truth, and no TfP-specific fields exist inside it. Package contents are retrieved through MCP Resources (tfp://skill-versions/{id}/{+path}); storage location is internal implementation detail and not part of this contract.

Schema version: 0.2.0 · $id: https://tokensforprogress.org/schemas/skill-version.schema.json

Fields

id

Type: string · Required: yes · Mutable: no · Pattern: ^skv_[0-9a-z]{10,32}$

Stable opaque identifier — the value ProblemRevision.skill_refs pins.

Example: "skv_01jf90m8e2pz"

skill_id

Type: string · Required: yes · Mutable: no · Pattern: ^skl_[0-9a-z]{10,32}$

The Skill this version belongs to.

Example: "skl_01jf95aa1lean"

version_number

Type: integer · Required: yes · Mutable: no

TfP's sequential registry version (1, 2, 3, …), unique within the Skill — the same pattern as ProblemRevision.revision_number. Independent of any upstream version string the package author used.

Example: 2

content_hash

Type: string · Required: yes · Mutable: no · Pattern: ^sha256:[0-9a-f]{64}$

Deterministic digest of the package TREE, independent of any archive/transport/storage representation. Algorithm: accept regular files only; normalize each relative path to safe POSIX form (rejecting absolute paths, .. traversal, duplicates after normalization, symlinks/special entries); compute the SHA-256 of each file's raw bytes; sort entries lexicographically by normalized path; serialize the canonical manifest as a compact JSON array (no whitespace) of objects with keys exactly in the order {"path":…,"sha256":…,"size":…}; content_hash = 'sha256:' + SHA-256 of that manifest's UTF-8 bytes. Independent implementations over the same directory produce the same digest.

Example: "sha256:9f2c1a7d0b7e4c1c9d1c0b3a5e8f2d4c6b8a0e2f4d6c8b0a2e4f6d8c0b2a4e6f"

source_uri

Type: string \| null · Required: no · Mutable: no

Upstream origin for an imported package (e.g. a public repository URL), or null for a package published directly to TfP. Provenance only — never a runtime dependency.

Example: "https://github.com/example/repo"

source_revision

Type: string \| null · Required: no · Mutable: no

Exact upstream revision the snapshot was taken from (e.g. a git commit SHA), when imported.

Example: "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b"

source_path

Type: string \| null · Required: no · Mutable: no

Path of the package within the upstream source, when imported.

Example: "skills/technology-transfer"

name

Type: string · Required: yes · Mutable: no · Pattern: ^[a-z0-9]+(-[a-z0-9]+)*$

The Agent Skills name identifier extracted from SKILL.md frontmatter, exactly as the open specification defines it: 1–64 chars, lowercase letters/digits/hyphens, no leading/trailing/consecutive hyphens. A package identifier, not a display title. May differ from the TfP Skill.slug (e.g. when importing colliding upstream packages).

Example: "lean-mathlib-proving"

description

Type: string · Required: yes · Mutable: no

The Agent Skills description extracted from SKILL.md frontmatter (1–1024 chars per the specification); used for listings and search.

Example: "Conventions, tactics, and pitfalls for contributing verified proofs to Mathlib."

license

Type: string \| null · Required: no · Mutable: no

The upstream Agent Skills license frontmatter string, when present: a license name or a reference to a bundled license file. For imported packages this is the upstream license.

Example: "MIT"

compatibility

Type: string \| null · Required: no · Mutable: no

The Agent Skills compatibility frontmatter string (1–500 chars), when present.

Example: null

created_by_user_id

Type: string · Required: yes · Mutable: no · Pattern: ^usr_[0-9a-z]{10,32}$

Who registered this version on TfP (the publisher/importer — not necessarily the upstream author; see source provenance).

Example: "usr_01jf8xw3tempo"

created_at

Type: string · Required: yes · Mutable: no

RFC 3339 UTC timestamp of registration.

Example: "2026-09-01T10:00:00Z"

yanked_at

Type: string \| null · Required: no · Mutable: yes

Set if this version was yanked (e.g. it contains an error). A yanked version stops being recommended for new pins, but existing ProblemRevision pins keep resolving — immutability of published work is never broken.

Example: null

JSON Schema source

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tokensforprogress.org/schemas/skill-version.schema.json",
  "title": "SkillVersion",
  "description": "Canonical (Stage 3A, owner-approved 2026-09-01). One immutable snapshot of an exact Agent Skills-compatible package directory (agentskills.io). TfP validates the package against the open specification, snapshots the exact contents into its own immutable store, and records upstream provenance when the package was imported — so a ProblemRevision pin is reproducible even if the upstream source disappears or changes. Registry version identity is TfP's sequential version_number, independent of any version string inside the package's own metadata (which is preserved unchanged inside the package). name/description/license/compatibility are the Agent Skills frontmatter fields extracted verbatim for indexing; the package itself remains the source of truth, and no TfP-specific fields exist inside it. Package contents are retrieved through MCP Resources (tfp://skill-versions/{id}/{+path}); storage location is internal implementation detail and not part of this contract.",
  "x-tfp-version": "0.2.0",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "id",
    "skill_id",
    "version_number",
    "content_hash",
    "name",
    "description",
    "created_by_user_id",
    "created_at"
  ],
  "properties": {
    "id": {
      "type": "string",
      "pattern": "^skv_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "Stable opaque identifier — the value ProblemRevision.skill_refs pins.",
      "examples": [
        "skv_01jf90m8e2pz"
      ]
    },
    "skill_id": {
      "type": "string",
      "pattern": "^skl_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "The Skill this version belongs to.",
      "examples": [
        "skl_01jf95aa1lean"
      ]
    },
    "version_number": {
      "type": "integer",
      "minimum": 1,
      "x-mutable": false,
      "description": "TfP's sequential registry version (1, 2, 3, …), unique within the Skill — the same pattern as ProblemRevision.revision_number. Independent of any upstream version string the package author used.",
      "examples": [
        2
      ]
    },
    "content_hash": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$",
      "x-mutable": false,
      "description": "Deterministic digest of the package TREE, independent of any archive/transport/storage representation. Algorithm: accept regular files only; normalize each relative path to safe POSIX form (rejecting absolute paths, `..` traversal, duplicates after normalization, symlinks/special entries); compute the SHA-256 of each file's raw bytes; sort entries lexicographically by normalized path; serialize the canonical manifest as a compact JSON array (no whitespace) of objects with keys exactly in the order {\"path\":…,\"sha256\":…,\"size\":…}; content_hash = 'sha256:' + SHA-256 of that manifest's UTF-8 bytes. Independent implementations over the same directory produce the same digest.",
      "examples": [
        "sha256:9f2c1a7d0b7e4c1c9d1c0b3a5e8f2d4c6b8a0e2f4d6c8b0a2e4f6d8c0b2a4e6f"
      ]
    },
    "source_uri": {
      "type": [
        "string",
        "null"
      ],
      "x-mutable": false,
      "description": "Upstream origin for an imported package (e.g. a public repository URL), or null for a package published directly to TfP. Provenance only — never a runtime dependency.",
      "examples": [
        "https://github.com/example/repo"
      ]
    },
    "source_revision": {
      "type": [
        "string",
        "null"
      ],
      "x-mutable": false,
      "description": "Exact upstream revision the snapshot was taken from (e.g. a git commit SHA), when imported.",
      "examples": [
        "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b"
      ]
    },
    "source_path": {
      "type": [
        "string",
        "null"
      ],
      "x-mutable": false,
      "description": "Path of the package within the upstream source, when imported.",
      "examples": [
        "skills/technology-transfer"
      ]
    },
    "name": {
      "type": "string",
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
      "minLength": 1,
      "maxLength": 64,
      "x-mutable": false,
      "description": "The Agent Skills `name` identifier extracted from SKILL.md frontmatter, exactly as the open specification defines it: 1–64 chars, lowercase letters/digits/hyphens, no leading/trailing/consecutive hyphens. A package identifier, not a display title. May differ from the TfP Skill.slug (e.g. when importing colliding upstream packages).",
      "examples": [
        "lean-mathlib-proving"
      ]
    },
    "description": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1024,
      "x-mutable": false,
      "description": "The Agent Skills `description` extracted from SKILL.md frontmatter (1–1024 chars per the specification); used for listings and search.",
      "examples": [
        "Conventions, tactics, and pitfalls for contributing verified proofs to Mathlib."
      ]
    },
    "license": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 120,
      "x-mutable": false,
      "description": "The upstream Agent Skills `license` frontmatter string, when present: a license name or a reference to a bundled license file. For imported packages this is the upstream license.",
      "examples": [
        "MIT"
      ]
    },
    "compatibility": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "x-mutable": false,
      "description": "The Agent Skills `compatibility` frontmatter string (1–500 chars), when present.",
      "examples": [
        null
      ]
    },
    "created_by_user_id": {
      "type": "string",
      "pattern": "^usr_[0-9a-z]{10,32}$",
      "x-mutable": false,
      "description": "Who registered this version on TfP (the publisher/importer — not necessarily the upstream author; see source provenance).",
      "examples": [
        "usr_01jf8xw3tempo"
      ]
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "x-mutable": false,
      "description": "RFC 3339 UTC timestamp of registration.",
      "examples": [
        "2026-09-01T10:00:00Z"
      ]
    },
    "yanked_at": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "x-mutable": true,
      "description": "Set if this version was yanked (e.g. it contains an error). A yanked version stops being recommended for new pins, but existing ProblemRevision pins keep resolving — immutability of published work is never broken.",
      "examples": [
        null
      ]
    }
  }
}