Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 59 additions & 15 deletions adoption/skills/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,28 @@ that the measurement rejects leaves through a dated record as under
[Retire and remove](#retire-and-remove). `agent-browser` is held for the
browser-tool measurement (since 2026-10-03).

Verify each pin from a blobless clone of its source repository
(`git clone --filter=blob:none --no-checkout <repository>`, then
`git rev-parse <ref>:<path>` and `git show <ref>:<path>/SKILL.md`), not with
per-file API calls. A newer repository commit alone does not establish a better
workflow: retain an unchanged skill tree at its existing pin, and re-pin only
after reviewing a change to the skill's own tree (`git rev-parse origin/HEAD:<path>`
differs from `tree_sha`). A registry listing's installed flag may cover only its
own directory; it does not inspect every native skill root. Plugins and built-in
skills also consume context, outside this manifest's description budget.
The accepted October 6 round-two lifecycle supersedes the historical unchanged-ref
preference: guidance follows upstream HEAD and every verified move retains its prior
canonical identity. `install_skills.py --record` resolves the public commit and binds
its skill-directory tree to the actual installed tree. When HEAD no longer matches,
an earlier immutable ref is a fallback only after its own source tree matches the
installed content. A newer ref is recorded identity, not evidence of improved fit.
Compare source, URL, path, ref, tree and SKILL.md digest together: identical bytes at
a fork do not inherit the earlier origin, license or audit evidence. Unverified rows
preserve the earlier entry and remain unresolved; no ref is guessed. See the
[recording and live-budget decision](../../docs/decisions/2026-10-06-skill-recording-and-live-catalog-budgets.md).
Its cap-retirement proposal is superseded by the
[repository-cap amendment](../../docs/decisions/2026-10-06-skill-recording-cap-amendment.md):
retain the repository ceiling alongside the separate native catalog evidence.

Tool-coupled skills follow their binary release. The status check compares retained
binary-release metadata and reports an advisory upstream restore/update proposal;
missing release evidence is unknown. It adds no deny rule or automatic host restore.
Vendor-generated HF records the pinned generator and exact emitted SKILL.md bytes
with `tree_sha: null`; its mirror stays separate comparison provenance. That
exception does not authorize null trees for other sources or project/worker installs.
A registry listing's installed flag may cover only its own directory. Plugins and
built-in skills also consume the actual client catalog budget.

## Install and inspect

Expand All @@ -110,6 +123,27 @@ python3 scripts/skills_status.py --skills-bin "$SKILLS_BIN" --json
"$SKILLS_BIN" list -g --json
```

Installation may use the selected upstream's supported route; Tier A observes the
public lock, folders and plugin caches, and Tier B reconciles verified identities in
an owned worktree. The October 6 configuration changes have their own review and
host-apply authorization; these commands do not apply client settings or hooks:

```sh
python3 tools/adoption/install_skills.py --record --dry-run --json
python3 tools/adoption/install_skills.py --record --json
python3 scripts/skills_status.py --metadata-only --ledger <state>/skills/ledger.jsonl --json
```

The metadata-only status reads bounded regular files with required no-follow and
nonblocking descriptor flags. It preserves canonical Claude directory aliases into
the explicit shared roots; unknown external targets, final-file symlinks and FIFOs
are not read or hashed. Missing or stale ledger coverage is reported. Neither status
nor the recorder starts a fresh model session. Full budget evidence uses explicitly
retained native listing/catalog inputs; absent inputs are unknown, not passed.
Coverage matches the current canonical `state_key` and SKILL.md digest, so a visit to
another native profile cannot replace or remove the first profile's identity.
Legacy ledger rows without that supported binding stay unbound rather than proving coverage.

The existing installer checks the CLI pin, calls upstream `skills add` with each
immutable tree URL and only the selected clients, then verifies or rolls back a
failed installation. It disables telemetry and the add-time audit request. A
Expand Down Expand Up @@ -260,7 +294,11 @@ for current qualification limits.
characters when the window is unknown. Each description is cut at 1,024
characters. The template sets 6,000 tokens.
- **Manifest.** `budget.claude_on_description_chars` stays within
`trial.on_description_char_cap`, and `budget.codex_enabled_description_chars`
`budget.claude_on_cap` and `trial.on_description_char_cap`. The repository
ceiling remains 10,500 characters under the
[cap amendment](../../docs/decisions/2026-10-06-skill-recording-cap-amendment.md);
a passing sum does not establish fresh native listing visibility.
`budget.codex_enabled_description_chars`
counts every Codex-enabled description; the manifest tests recompute both.
`budget.codex_catalog_description_chars` counts the descriptions Codex shows the
model, leaving out `upstream_allow_implicit_invocation: false` skills;
Expand Down Expand Up @@ -302,11 +340,17 @@ manifest skills, so remove a retired skill's installed folder instead. Remove it
runtime-worker `reuse_ref` entry and coverage selections while retaining dated
evidence.

For removal, the host batch runs upstream `"$SKILLS_BIN" remove NAME -g -y` from a
shell outside a Claude session, since the settings template denies the CLI's
remove commands in a session (see [Install and inspect](#install-and-inspect)).
Then inspect the canonical folder, lock and client links. Omit `-g` in an owned
disposable project.
For an approved global retirement, use `install_skills.py --retire NAME --skills-bin
"$SKILLS_BIN" --json`. It invokes upstream `skills remove NAME -g -y -a claude-code
codex`, then confirms absence from the canonical folder, Claude alias, global lock
and native legacy `$CODEX_HOME/skills/NAME` root before changing the manifest. It
does not inspect or delete unrelated bundled `.system/NAME`. A zero native exit with
any retained global copy is reported as a limit and leaves the selected entry intact.
`--dry-run` makes a proposal only; `excluded[].last_pin` keeps the full prior source.
The HF generated form's removal is explicitly unsupported by this adapter rather
than replaced with a custom file remover. Project retirement remains a separate
owned native operation. Configuration and hook activation changes require their
own reviewed host-apply step; these commands do not apply that configuration.
Removing a shared selected skill affects its client aliases; update its selection
before claiming the host still matches the manifest. Retain useful evidence and
delete only the owned temporary installation. Rollback and cleanup are operations
Expand Down
55 changes: 51 additions & 4 deletions adoption/skills/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"started": "2026-09-25",
"window_days": 30,
"review_after": "2026-10-25",
"on_description_char_cap": 10500,
"prune_rule": "A trial skill installed for at least window_days with zero invocations in the last window_days is a prune candidate: the review keeps it or removes it through a dated decision record. Zero use no longer demotes a listing: under the user's 2026-09-30 directive every model-invocable skill stays listed so the model can invoke it. Kept verdict winners change status only through a verdict re-record, and their listing only through a dated decision record.",
"confound": "name-only and user-invocable-only listings depress proactive invocation; compare only within a listing state.",
"measurement": {
Expand Down Expand Up @@ -670,13 +669,61 @@
"claude-code"
],
"copy": true
},
{
"name": "hf-cli",
"source_type": "native_generated",
"source": "huggingface/huggingface_hub",
"url": "https://github.com/huggingface/huggingface_hub/blob/bd4a76030582d118e28dc9ad6c7a5911ea76176b/src/huggingface_hub/cli/skills.py",
"ref": "bd4a76030582d118e28dc9ad6c7a5911ea76176b",
"path": "src/huggingface_hub/cli/skills.py",
"tree_sha": null,
"skill_md_sha256": "5fa67d3f5b5e071d026c13a029544220f077d9651ed96f5e4ed546981e2c19c5",
"skill_md_bytes": 33972,
"description_chars": 1008,
"upstream_disable_model_invocation": false,
"license": "Apache-2.0",
"official": true,
"audits": {
"gen_agent_trust_hub": "Unknown",
"socket": "Unknown",
"snyk": "Unknown",
"url": "https://skills.sh/huggingface/skills/hf-cli",
"checked_at": "2026-10-06"
},
"status": "kept",
"gap": "Record the vendor-generated skill already installed by the command center. Task: model-hub. Generator and mirror bytes are distinct provenance; no new host installation or paired quality claim.",
"task": "model-hub",
"claude_listing": "on",
"codex_enabled": true,
"added": "2026-10-06",
"pin_policy": {"kind": "tool-coupled", "binary": "hf", "release_tag": "v2.1.1", "advisory": true},
"generator": {
"package": "huggingface_hub",
"version": "2.1.1",
"release_tag": "v2.1.1",
"install": ["hf", "skills", "add", "--global"],
"update": ["hf", "skills", "update", "hf-cli", "--global"],
"preview": ["hf", "skills", "preview"],
"managed_marker": ".hf-skill-manifest.json",
"managed_marker_format": "empty-presence-marker"
},
"mirror": {
"source": "huggingface/skills",
"ref": "ca0325bb20b2d0a1b2efa893670c4c72f79e707b",
"path": "skills/hf-cli",
"tree_sha": "6f293e30d665bc0447a46af7831e386f3ab84bdb",
"skill_md_sha256": "91dddd0303b2a3c5b6a38aa240d29cb2c93b118c98a6aafe46461df8f7a163bb",
"skill_md_bytes": 33973,
"relationship": "mirror bytes equal generated installed bytes plus one final LF; never an installed-tree identity"
}
}
],
"budget": {
"claude_on_description_chars": 9484,
"claude_on_description_chars": 10492,
"claude_on_cap": 10500,
"codex_enabled_description_chars": 9165,
"codex_catalog_description_chars": 9165,
"codex_enabled_description_chars": 10173,
"codex_catalog_description_chars": 10173,
"codex_configured_budget_tokens": 6000,
"codex_fallback_budget_chars": 8000,
"description_chars_method": "Unicode code points of the SKILL.md frontmatter description parsed with PyYAML, surrounding whitespace stripped (2026-09-26; semgrep, codeql and sarif-parsing corrected from 709, 753 and 375).",
Expand Down
6 changes: 3 additions & 3 deletions adoption/templates/codex.config.template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ default_subagent_reasoning_effort = "max"
# 272,000-token window of gpt-6.1-sol and gpt-6-astra in models-manager/models.json) and at 8,000 characters only when
# the window is unknown; a set value is capped at 10,000 tokens (codex-rs/ext/skills/src/render.rs L19-22 and L126-152
# at rust-v0.159.2, L17-20 and L123-149 at rust-v0.157.1; the key is core/config.schema.json L4122-4127 at
# rust-v0.159.2). The manifest's 24 catalog-visible skills render to about 11,100 bytes with a 28-character skills
# root, which render.rs charges at about 2,790 tokens (each line and its newline at ceil(bytes / 4), L154-160 and L25),
# so a fixed 6,000 leaves room for Codex's five .system skills and plugin skills on any model a child runs
# rust-v0.159.2). The manifest's 25 catalog-visible skills count 26 entries minus Claude-only skill-creator,
# including the held browser. This is declared eligibility, not fresh host visibility; scripts/skills_status.py
# checks retained native catalogs at ceil(UTF-8 bytes / 4). A fixed 6,000 is the configured budget, not proof
# (docs/decisions/2026-09-30-skills-llm-native-listing.md). Per-skill [[skills.config]] disables of manifest skills
# stay out of this template: tools/adoption/install_skills.py --print-codex-config prints the manifest's, each keyed by
# the installed SKILL.md path (adoption/skills/lifecycle.md). The one rule below turns off Codex's bundled
Expand Down
Loading
Loading