noteflowai/dsh-skills-anywhere · 0.18.0 · 2026-10-02

require a reviewed Git source commit when opening a skill over MCP

MCP open_skill accepts a new optional input, expected_source_commit. Set it to the receipt.source_commit value from an earlier load, and the skill is delivered only while the Git-source checkout HEAD is still that commit. When the field is supplied, the checks run in this order: format (40 lowercase hex characters, enforced by the input schema), Git-source origin, the existing expected_sha256 and expected_bundle_sha256 checks (wording unchanged), a provable commit from the existing sourceCommit() probe, and an exact match. Any failure returns isError true with an actionable message and no instruction text or receipt. A mismatch names both the expected and the found commit. A rejected digest still runs no Git command. Calls that omit the field behave as before. tools/list shows the field as optional. Results from the controller's runs on commit 6a40534. These are the controller's executions, not mine. With the new test file run against the base code, 4 of its 6 tests failed: the moved-checkout, unprovable-commit, malformed-pin/non-Git and tools/list tests. The 2 tests that check unchanged existing behavior passed. On the candidate, every check passed: pnpm run build, the feature test (6 tests), pnpm run check (25 test files, 251 tests), pnpm run showcase:build and pnpm run showcase:check. The prior review finding is addressed. As the logged test source shows, the malformed-pin test reads the resolved callTool result directly and asserts both isError true and the schema message (must be a full 40-character lowercase Git commit). It no longer wraps the call in a try/catch that would turn thrown errors into isError.

Use it

Prerequisites: git, Node and pnpm, this package built with pnpm run build, and an MCP client connected to the skills-anywhere MCP server.

1. Create a synthetic sample Git source (demo data only):
mkdir -p /tmp/demo-skills/robot-reel-review && cd /tmp/demo-skills && git init -q && printf -- '---\nname: robot-reel-review\ndescription: Synthetic demo skill\n---\n\nReview the robot reel.\n' > robot-reel-review/SKILL.md && git add -A && git -c user.name=demo -c user.email=demo@example.com commit -qm initial

2. Manual step: register /tmp/demo-skills as a Git source using the source configuration described in README.md, then let the server sync it into its source cache. The config syntax is not repeated here.

3. Over MCP, call open_skill with {"name": "robot-reel-review"} and record structuredContent.receipt.source_commit, a 40-character lowercase hex value.

4. On later loads, call open_skill with {"name": "robot-reel-review", "expected_source_commit": "<that value>"}. The result is the same content, and receipt.source_commit equals the pin.

5. Commit a change in /tmp/demo-skills and sync it into the cache. Repeat the pinned call. The result has isError true and reads: Git source commit changed for "robot-reel-review": expected <old>, found <new>; review the change before updating expected_source_commit.

6. After you review the new revision, replace the pin with the found commit.

See docs/VERIFIED-LOADS.md, section on requiring the reviewed source commit.

Scope

Scope: the standalone MCP open_skill tool, for skills from configured Git sources only. The dsh provider skill tool, skill:// resources and the CLI are unchanged. What the pin proves: it proves the checkout HEAD, not the absence of uncommitted or untracked files. Combine it with expected_bundle_sha256 to cover directory contents. Files can still change after a load. Not included: automatic re-sync, rollback, and signature or author verification. Test coverage: the feature tests use synthetic local Git repositories and an in-process MCP client. They confirm that malformed pins come back as an isError result with this repository's pinned MCP SDK. Other SDK versions or clients were not exercised, and no branded client application was tested. Clients that cache tool schemas may need to reconnect before they see the new field. UI and browser evidence: this feature has no UI. The controller's showcase:check run passed the existing showcase browser regression checks (desktop/mobile, keyboard tabs, offline and others). Those checks cover the showcase site, not this feature, and no visual review of this feature applies. Passing tests do not establish behavior beyond the tested cases.

Upgrade and rollback

Upgrade: this is an additive, optional input. Existing calls, receipts, lock files and cache layout are unchanged, so no migration is needed. Rollback: stop sending expected_source_commit or downgrade the package. Pinned calls sent to an older server are not enforced, because the field is not in that schema, so do not rely on the pin after a downgrade. Adopting a new revision: review it, then update the pin to the commit named in the mismatch error or to the receipt.source_commit from a fresh unpinned load.

Source commit: c01105101d80a43b04189cded81f54726129d25d