Skill Manager — Improvements Roadmap
Status: #4 delivered; #3 removed (simplification 4.5, 2026-06-20) — heuristic content scan and acknowledge gate cut; #2 withdrawn (simplification 4.3, 2026-06-20) — skills are local-folder-import only, no live Git source to update against; #1 (discovery) was delivered then withdrawn (simplification 4.8, 2026-06-20) — no content ecosystem. FRs and acceptance scenarios for the shipped items live in spec.md; the trust-layer decision is ADR-027. Derived from the competitive-landscape research in docs/research/agent-skills.md (Report #3 in docs/research/README.md). The research ranks Coffer ahead on cross-agent delivery and SSRF-hardened ingest, and behind on four points. This roadmap turns those four points into sequenced, PR-sized work on top of the shipped 005 skill manager.
The Chinese mirror is improvements-roadmap.zh.md.
Sequencing
#4 frontmatter alignment → ~~#3 trust layer (L2)~~ → ~~#2 update detection / pinning~~ → #1 discovery
(small, prerequisite) (removed, simplif. 4.5) (withdrawn, simplification 4.3) (large, reuses #4)Dependency rationale:
- #4 first — recognizing the
allowed-toolsfrontmatter field provides the validation foundation that downstream items build on. - #1 last — browse-and-install must carry #4's validation before discovery rides on top of it.
Each item is one branch / one PR, spec-first: update spec.md/spec.zh.md, data-model.md, contracts/api.openapi.yaml, then implement with tests, then make verify.
#4 — agentskills.io frontmatter alignment (this PR)
Gap. SkillFrontmatter enforced only name + description presence; description had no length cap (the standard says ≤1024), and optional standard fields (license, experimental allowed-tools) were silently dropped under extra="allow".
Change. Cap description at 1024 chars (hard 422, same path as the existing name-too-long failure); recognize and retain license and allowed-tools (lenient coercion: list or delimited string → normalized list; malformed → tolerated as absent). Spec: FR-004 amended, FR-027 added, two acceptance scenarios. name keeps its documented superset of the standard charset (underscore tolerated) for backward-compatibility.
Out of scope (deferred to #2/verify). Enforcing the standard's "name == parent directory" rule for in-store skills — Coffer normalizes the master folder to <name> on write, so this only bites a verify-time consistency check, which belongs with #2.
#3 — Trust layer, level L2 (heuristic scan + warn)
Removed (simplification 4.5, 2026-06-20). The heuristic content scan (FR-028) and the acknowledge-to-enable gate (FR-029) are cut. Design retained for history.
The research's #1 highest-leverage gap, and on-mission for a vault. Boundary: Coffer delivers skills but never runs them, so it cannot enforce allowed-tools at runtime (the host agent does). Coffer's "trust" is gate-at-ingest/enable plus making risk legible. Records a new ADR.
- L1 inventory + provenance. Enumerate scripts/executables (extension + shebang + exec bit) with path/size/sha256; read declared
allowed-tools; surface ingest time,version_hash(already stored). - L2 heuristic scan. Pure
scan_skill_folder(folder) -> list[Finding](severity,rule_id,file,line?,message). Rules: dangerous shell (curl … | sh,eval, base64→exec,rm -rf, sudo, writes outside the folder), network egress, suspected exfil (~/.ssh,~/.aws, env dumps piped out),allowed-toolsvs. observed behavior mismatch (best-effort), obfuscation (long base64/hex blobs). - Non-blocking. Ingest/enable proceed; a verdict ≥ high marks the skill "needs acknowledgment" and binding/enable requires an explicit ack (
POST /skills/{name}/acknowledge-risk, audited). Scan runs at import, adopt, and in-place file edits; results persist onSkillConfig(scan_verdict,findings_count,last_scanned_at,ruleset_version). - Surfaces. Detail-page findings, list badge,
SKILL_SCANNED/SKILL_RISK_ACKNOWLEDGEDaudit events, CLIcoffer skill scan <name>.
#2 — Update detection + pinning
Withdrawn (2026-06-20, simplification 4.3). Update detection + pinning are removed: skills are local-folder-import only, with no live Git source to diff against. Design retained for history.
update_ops.apply_update already compares the SKILL.md hash, but only as a pull-and-apply. Add:
check_for_updates(ref)— re-fetch the source (shallow, viasource_fetcher), validate, compute the candidate hash, compare without applying; returnUpdateStatus {available, current_hash, available_hash, rename_detected}.- Cache fields on
SkillConfig(update_available,last_update_check_at,available_version_hash) for a list badge. - Pinning: a branch
source.reffollows; a tag/sha is pinned.pin_to_resolvedrewritessource.refto the current commit sha; pinned skills don't nag. - On-demand only (button /
coffer skill check-updates); no periodic poll in v1 (local-first). Folds in the verify-time name==dir check from #4. - Surfaces:
POST /skills/{name}/check-update, list field, CLI, UI badge.
#1 — Discovery (browse-and-install)
Withdrawn (2026-06-20, simplification 4.8). This item shipped in PR #116 and was reverted: a built-in catalog has no content ecosystem to browse. The design below is retained for history only.
Currently requires a known git URL; rivals offer browse-and-install catalogs.
CatalogSourceport. v1: a curated static catalog (bundled JSON or a pinned index URL) of{name, description, git URL, ref, publisher}; optionally known registries (anthropics/skills, vercel-labs/skills, agentskills.io API if stable). Remote index fetch is allowed (local-first ≠ no remote calls), kept opt-in / refreshable.- Install reuses the git-fetch ingest path (SSRF guard + validate + #4 validation), so discovery rides on #4. Cross-references #2 for "newer version available".
- Surfaces:
GET /catalog/skills,POST /catalog/refresh, UI catalog page, CLIcoffer skill search.
Positioning (non-code)
Lead with the differentiator the research highlights: "one library, every agent, no per-surface re-upload, auto-follow with exclusions." Update docs-site/guide/skills.md and the README as the roadmap delivers.