mirror of
https://github.com/NVIDIA/skills.git
synced 2026-09-14 15:41:50 +08:00
b554b1be31
Consumers that mirror skills have no way to learn a mirrored skill changed. The catalog has no releases or tags, metadata.json carries no version or digest, and the README's Version column is markdown and per-component. Detecting that 4 of 30 mirrored skills moved means walking 343 directories and diffing them. Add versions.json at repo root: one entry per skill with a content digest, the last catalog commit touching it, and that commit's date. A consumer stores the digests it mirrored and compares on refresh. The digest comes from each skill's signed manifest, not from the upstream sha the sync observed. When content changes without a signature refresh the sync reverts the skill and the old content stays published; keying on skill.oms.sig describes what is published, so a reverted update never surfaces as an update. Coverage is 343/343 and every manifest's subject name matches its directory. Sorting the file list before hashing keeps the digest stable across a re-sign that shuffles manifest order. A NUL between name and digest stops two different file lists serializing identically. Removals are gated: if a skill disappears from a regeneration the generator refuses to write unless --allow-removals is passed. A generated file staying schema-valid with one fewer entry is how cuopt-multi-objective-exploration silently vanished from metadata.json on 2026-08-03. Kept separate from metadata.json deliberately. That file is taxonomy, changes rarely, and is partly AI-enriched; this is mechanical and changes hourly. Separating them stops taxonomy churning on every sync, keeps a provenance bug away from the marketplace index, and keeps AI out of the path for data that has nothing to do with it. The check job's checkout gains fetch-depth: 0 — the commit fields read git log per skill directory, which a shallow clone cannot answer. 22 unit tests cover digest stability, order independence, separator collisions, removal detection and schema closure. Refs #491 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Moshe Abramovitch <moshea@nvidia.com>
57 lines
2.0 KiB
JSON
57 lines
2.0 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://developer.nvidia.com/schemas/versions.schema.json",
|
|
"title": "versions.json",
|
|
"description": "Per-skill content provenance for consumers that mirror catalog skills. Generated by .github/scripts/generate_versions.py from committed catalog state.",
|
|
"$comment": "SPDX-License-Identifier: Apache-2.0. Copyright (c) 2026 NVIDIA Corporation.",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["$schema", "skills"],
|
|
"properties": {
|
|
"$schema": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"description": "URI of this schema."
|
|
},
|
|
"skills": {
|
|
"type": "array",
|
|
"description": "Every published skill, sorted by name.",
|
|
"items": { "$ref": "#/$defs/skill" }
|
|
}
|
|
},
|
|
"$defs": {
|
|
"skill": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "path", "content_digest", "last_commit", "last_modified"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"description": "Catalog directory name, unique across the catalog."
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"pattern": "^skills/[^/]+$",
|
|
"description": "Repository-relative path to the skill directory."
|
|
},
|
|
"content_digest": {
|
|
"type": "string",
|
|
"pattern": "^sha256:[0-9a-f]{64}$",
|
|
"description": "Digest over the skill's signed file list. Changes if and only if published content changes. Compare against a previously mirrored value to detect updates."
|
|
},
|
|
"last_commit": {
|
|
"type": "string",
|
|
"pattern": "^[0-9a-f]{40}$",
|
|
"description": "Most recent catalog commit touching this skill directory."
|
|
},
|
|
"last_modified": {
|
|
"type": "string",
|
|
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
"description": "Commit date of last_commit, ISO 8601 date."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|