record the Git source commit in MCP open_skill receipts
On candidate commit 59390b7, a successful MCP open_skill call that passes its expected_sha256 and expected_bundle_sha256 checks now returns structuredContent.receipt.source_commit. For a skill from a Git source, it is the 40-character lowercase HEAD SHA of that source's cache checkout at load time. For agent directories, plugin marketplaces and extra local directories it is null, and no Git command runs for them. For a Git source whose commit cannot be proven, it is also null and the server logs one 'skills-anywhere: source commit unavailable for <name>: <reason>' warning. That covers Git missing or failing, a timeout, or a work tree with no .git of its own or one outside the cache. The load still returns unchanged content in that case. Git runs without a shell and with GIT_* variables removed. Discovery stops at the cache directory, so the commit of an enclosing repository is never reported. Rejected loads throw their existing errors before any Git lookup. The advertised outputSchema declares source_commit. The schema string stays skills-anywhere-load-1. These are unchanged: loadReceipt(), LoadReceipt, OpenedSkill, the exported openSkill(), dsh provider and tool receipts, skill:// resources and rendered text. Controller-run checks on 59390b7: an acceptance-before run failed 3/3 feature tests because the receipt had only 11 fields. After the change, pnpm run build passed. tests/test_feature_ea6b51801ed9.test.ts passed. pnpm run check passed, and its log shows 24 test files and 245 tests passing. pnpm run showcase:build and pnpm run showcase:check also passed.
Use it
Prerequisites: Node.js with npx, and git. All data below is a synthetic demo. This sequence is a manual example and the controller did not run it.
mkdir -p my-skills-repo/my-skill
cat > my-skills-repo/my-skill/SKILL.md <<'EOF'
---
name: my-skill
description: Synthetic demo skill
---
Demo instructions v1.
EOF
git -C my-skills-repo init -q -b main
git -C my-skills-repo add -A
git -C my-skills-repo -c user.name=demo -c user.email=demo@example.invalid commit -qm v1
export DSH_HOME="$PWD/demo-dsh"
npx dsh-skills-anywhere add ./my-skills-repo
npx dsh-skills-anywhere sync
open_demo() {
(printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"0"}}}' '{"jsonrpc":"2.0","method":"notifications/initialized"}' '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"open_skill","arguments":{"name":"my-skill"}}}'; sleep 3) | npx dsh-skills-anywhere mcp
}
open_demo
git -C my-skills-repo rev-parse HEAD
The id 2 response's structuredContent.receipt.source_commit should match the printed SHA. Next, edit SKILL.md, commit v2, run sync and call open_demo again: source_commit shows the new HEAD. Then run git -C my-skills-repo reset --hard HEAD~1, sync again and call open_demo: the v1 SHA comes back. Skills from agent directories show source_commit null.Scope
Scope: this adds one nullable field to MCP open_skill receipts only. The exported openSkill() and dsh receipts do not include it. There is no expected_commit argument, no check that the lock file agrees with the checkout, and no change to sync or clone. The field names only the cache checkout HEAD. Uncommitted edits in the cache are covered by skill_sha256 and bundle_sha256, not by this field. It does not verify signed commits, authenticate authors or prove instruction compliance. Each successful Git-source load starts one Git process with a 5-second bound. Strict consumers that reject unknown keys will see one new key. Evidence: the passing tests use synthetic local file repositories in temporary directories. They do not cover remote hosts, every Git version or every platform. The usage sequence above was written by hand and was not executed by the controller. The controller ran the existing showcase browser regression checks (desktop/mobile iframe, keyboard tabs, offline and others) and they passed. This feature has no UI, and no screenshots were reviewed.
Upgrade and rollback
Upgrade: install the version that contains commit 59390b7. Lock files, sources files, caches and saved receipts are read unchanged, and new MCP open_skill receipts gain source_commit. Rollback: reinstall the previous version. Receipts saved with source_commit stay valid JSON with the same schema string, and older consumers ignore the extra key. Nothing is migrated or deleted in either direction.