About the project
Audited skills. One depot. Every agent.
Inspiration
The project started with a smaller question than "how should I manage AI skills": which copy is the real one?
I was reading MagicSkills (Narwhal-Lab, Peking University, MIT), which models skills as packages organized into a pooled library, per-agent collections, and a generated index. Its documentation names the failure mode precisely: you copy a skill to a second machine, edit one of the copies, and now "the skill" refers to two different files. MagicSkills answers that with a registry and an install/upload flow — a reasonable answer when you own the whole pipeline.
But a UGREEN NAS is not a registry. It is a share: the place where a household or a small team already keeps the files they half-agree about. I found that reframing more interesting than the original one. On a NAS, a skill is just a file, and files are exactly what a NAS is excellent at holding and poor at curating. Nothing in a folder listing tells you that one package is stale, that another is byte-identical to a third, or that both claim the same name.
That gap — storage without judgement — is what Skill Depot is built to close. Not a smarter assistant that reads your files, but a deterministic gate that decides what is allowed into the depot and what each agent receives from it.
What I learned
A Skill is a contract, not a program. The Uliya developer package makes this concrete: a SKILL.md with declared sections, a capability catalog, and a static checker that never executes anything. My first instinct was to write code. The correct instinct was to write rules precise enough that a runtime could not misinterpret them.
Determinism beats judgement for this class of problem. Deciding whether two packages are the same is not a language task; it is a comparison. I deliberately kept an LLM out of the audit path. The model resolves intent and writes the report; the classification is arithmetic on bytes.
Constraints are design tools. The 500-word limit on the ten answers looked like an obstacle and turned out to be an editor. My first draft was 574 words and said less than the final 469.
How I built it
The build ran in five passes: read MagicSkills and extract what was conceptual versus what was code; map every intended action against the official capability catalog (version 2.0.0) before writing a single instruction; write SKILL.md plus seven references covering audit rules, index format, workflows, approvals, limitations, tests, and disclosures; run the static checker; then produce the submission package and this proposal.
Identity. Two packages are the same skill when their entry files hash identically:
$$ p \equiv q \;\Longleftrightarrow\; H(\mathrm{entry}(p)) = H(\mathrm{entry}(q)) $$
This is an equivalence relation, so an audited library partitions into classes:
$$ L \;=\; C_1 \sqcup C_2 \sqcup \dots \sqcup C_k $$
and the bytes reclaimable by keeping one copy per class are
$$ S \;=\; \sum_{i=1}^{k} \bigl(|C_i| - 1\bigr)\, s_i , $$
where $s_i$ is the package size. Where MagicSkills deduplicated on resolved paths, Skill Depot compares content and then separates exact duplicate, diverged copy, and name collision — the last of which must block, not merge.
Composition. A collection for agent $a$ is a subset $K_a \subseteq L$ that admits at most one package per name:
$$ \forall n:\;\; \bigl|{\,x \in K_a \;:\; \mathrm{name}(x) = n\,}\bigr| \;\le\; 1 . $$
This is the constraint that makes a generated index trustworthy: an agent reading it can never be pointed at two candidates for one capability.
Cost. Audit is two linear passes — stat everything, then hash the candidates:
$$ T(n) \;=\; \alpha n \;+\; \beta \sum_{i=1}^{n} s_i , $$
with the second term usually dominating because skill packages are small but their directory trees are not.
Orchestration. The parent Skill resolves intent and confirms writes but never invokes a CLI itself. Filesystem, file-manager, and workflow actions belong to file-agent; index writing belongs to knowledge-agent. Reads (find, ls, stat, cat, md5sum, scan-dedupe) need no approval; every state-changing action is gated — gateway for mkdir, cpmv, share-mkdir, restore, tag-add, workflow for save-text and batch-move. Results resolve to one of five states: completed, failed, cancelled, waiting_user, waiting_approval.
Challenges
The capability boundary. My first design had the parent Skill calling cli.invoke directly. The kit's ownership model forbids that, and it is right to: a single Skill holding every write permission is exactly the shared-library-becomes-code-distribution-channel problem I was trying to avoid. Restructuring into two specialist agents with explicit evidence for each capability took longer than writing the audit rules.
Duplicate detection that actually classifies. Path-based dedupe is fine inside one registry and useless across a share, where the same content sits under three spellings and two different skills share one name. Getting the three-class model right — and deciding that collisions block rather than resolve — changed the resulting index format twice.
The proposal pipeline. No pandoc, no headless Chromium, and WebKit's print path failed in this environment. I wrote a small Swift + CoreText renderer fed by JSON generated from the Markdown source. It produced a clean two-page PDF, then broke my word count: text extraction returned fi ligatures, so "files" counted as a different token than the source. Disabling ligatures at the attributed-string level fixed extraction.
Resisting the flattering claim. The Skill passes its static checker with zero findings, and that is a real result — but it is not evidence that anything works on a NAS. Nothing here has run on UGREEN hardware. Writing "unverified" into a proposal is uncomfortable; writing around it would have been worse, and would have made the finalist test plan meaningless.
Naming. The working name, nas-skill-library, described a category. "Skill Depot" describes a place, which is what the thing actually is — a depot with a gate, not a shelf anyone can write to.
Log in or sign up for Devpost to join the conversation.