downloadable-asset-engineering
Builds and releases self-contained downloadable ZIP assets (skill packs, template kits, example projects, small local tools) so the released bytes, not just the source folder, are proven to work: dete
SKILL.mdskills/dev/downloadable-asset-engineering/SKILL.md
GitHubDownloadable Asset Engineering
Ship a ZIP that works for a stranger, and prove it from the bytes you publish.
source folder != staged package != released ZIP != extracted install
Test each layer on its own. Passing one never proves the next.
Inputs to pin down first
Write these as a short contract before building (ask for anything missing):
- Archive name and top-level folder name (for example
acme-skill-pack-1.2.0.zip/acme-skill-pack/). - Required file tree and where the version number lives.
- How it is installed (copy a folder, unzip into
~/.claude/skills/, npm, etc.). - The promise: what a user can do after installing. Anything not promised is out of scope.
- Data: only public, fictional or explicitly authorised content goes inside.
Steps
- Write the checks before the asset is "done". For anything executable (validators, builders), add one behavioural test, watch it fail for the right reason, implement, rerun, repeat. Good first tests: missing required file, malformed frontmatter, unsafe archive path, two builds identical.
- Make it standalone. Every template, schema, example and script the promise depends on is inside the ZIP. No hidden dependency on a paid service, private repo, credential or network call unless the promise says so.
- Package validator (write one per asset, keep it stdlib-only): required
tree, frontmatter fields, unique names, every referenced local path exists,
UTF-8, no symlinks, no machine paths (
/Users/,/home/<name>,C:\Users), no secret-looking strings. Report file and category only, never the value. - Build deterministically:
The builder sorts entries, fixes timestamps and permissions, dropspython scripts/build_zip.py ./my-kit dist/my-kit-1.0.0.zip --top my-kit python scripts/build_zip.py ./my-kit /tmp/rebuild.zip --top my-kit cmp dist/my-kit-1.0.0.zip /tmp/rebuild.zip && echo reproducible.git, caches,.DS_Store,.env*, old zips and symlinks, and writesMANIFEST.jsonplusSHA256SUMSinside the archive (neither lists itself). - Verify the released bytes:
Checks traversal, absolute paths, symlinks, duplicate and case-colliding names, single top folder, manifest and checksum agreement, then extracts and re-hashes.python scripts/verify_zip.py dist/my-kit-1.0.0.zip --sha256 <digest from build> --extract-to /tmp/fresh - Use the extracted copy, not the source. In
/tmp/fresh: rerun the package validator, run the included sample, follow the README install steps word for word on a clean path. - Host tests, reported separately. If the asset runs inside Claude Code, Claude.ai or another app, test and record each of these on its own: discovered/listed, explicit invocation works, automatic selection works, safe behaviour on missing or bad input, end-to-end output. A skill showing up in a list does not prove it runs.
- Write the release evidence using the template in
references/release-testing-and-evidence.md.
Evidence labels (use only these)
- PASS: the command reached the behaviour and the assertions held.
- EXPECTED FAIL: a deliberately bad fixture was rejected for the intended reason.
- BLOCKED: a prerequisite (auth, licence, host outage) stopped the test before the behaviour.
- NOT RUN: no execution evidence.
Never upgrade BLOCKED or NOT RUN to PASS. Finish every independent layer anyway and state the remaining gap at the top of the handoff.
Decision rules
- Two builds differ: find the nondeterministic input (timestamps in generated
files, unsorted globbing, a manifest written into the source) and fix it. Do
not publish until
cmpis silent. - Any file over ~5 MB: question it. Media in a first release needs a reason and a metadata scrub.
- The sample output is a golden file: it shows the expected shape, not proof that today's model produced it. Label it that way.
- A secret or personal detail found by the scan: remove it from the source, rebuild, re-verify. If it was ever published, treat it as leaked and rotate it.
Output
Deliver: the ZIP, its SHA-256 (published next to the download), and
RELEASE-EVIDENCE.md. Example summary line for the handoff:
my-kit-1.0.0.zip 18,432 bytes sha256 3f9a...c21e 14 entries
Reproducible: PASS (2 builds identical) Archive safety: PASS
Extracted sample: PASS Claude Code discovery: PASS Auto-selection: BLOCKED (no host auth)
Pitfalls
- Calling "zip created" a release check.
- Validating the source sample but never the extracted copy.
- Builder machine paths leaking into docs or generated outputs.
- Leaving caches, debug output or old archives inside the ZIP.
- SHA-256 proves integrity against a trusted digest, not who made the file.