Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/scripts/action-security-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
action_file="$repo_root/action.yml"
test_root="$(mktemp -d "${TMPDIR:-/tmp}/skill-provenance-action-test.XXXXXX")"
trap 'rm -rf "$test_root"' EXIT

input_reference_count="$(grep -Ec '\$\{\{[[:space:]]*inputs\.bundle-path[[:space:]]*\}\}' "$action_file" || true)"
if [[ "$input_reference_count" -ne 1 ]]; then
echo "FAIL: bundle-path must have exactly one expression reference, in the environment mapping" >&2
exit 1
fi

if ! grep -Eq '^[[:space:]]*BUNDLE_PATH:[[:space:]]+\$\{\{[[:space:]]*inputs\.bundle-path[[:space:]]*\}\}[[:space:]]*$' "$action_file"; then
echo "FAIL: bundle-path is not transported through the BUNDLE_PATH environment variable" >&2
exit 1
fi

if ! grep -Eq '^[[:space:]]*run:.*"\$BUNDLE_PATH"' "$action_file"; then
echo "FAIL: the validation command does not pass BUNDLE_PATH as a quoted argument" >&2
exit 1
fi

mkdir -p "$test_root/path with spaces"
cp -R "$repo_root/skill-provenance" "$test_root/path with spaces/bundle"
env GITHUB_ACTION_PATH="$repo_root" \
BUNDLE_PATH="$test_root/path with spaces/bundle" \
bash -c '"$GITHUB_ACTION_PATH/skill-provenance/validate.sh" "$BUNDLE_PATH"' >/dev/null

sentinel="$test_root/injected"
adversarial_path="\"; touch $sentinel; #"
if env GITHUB_ACTION_PATH="$repo_root" \
BUNDLE_PATH="$adversarial_path" \
bash -c '"$GITHUB_ACTION_PATH/skill-provenance/validate.sh" "$BUNDLE_PATH"' >/dev/null 2>&1; then
echo "FAIL: adversarial bundle path unexpectedly validated" >&2
exit 1
fi
if [ -e "$sentinel" ]; then
echo "FAIL: bundle-path shell payload executed" >&2
exit 1
fi

echo "Action input transport is shell-safe"
66 changes: 66 additions & 0 deletions .github/scripts/test-validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
# Focused regression tests for validate.sh manifest hash handling.

set -euo pipefail

ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
VALIDATOR="$ROOT_DIR/skill-provenance/validate.sh"
TEST_DIR="$(mktemp -d "${TMPDIR:-/tmp}/skill-provenance-validate-test.XXXXXX")"
trap 'rm -rf "$TEST_DIR"' EXIT

if command -v shasum >/dev/null 2>&1; then
hash_file() { shasum -a 256 "$1" | awk '{print $1}'; }
else
hash_file() { sha256sum "$1" | awk '{print $1}'; }
fi

write_manifest() {
printf 'bundle: test\nfiles:\n - path: payload.txt\n role: reference\n%s\n' "$1" > "$TEST_DIR/MANIFEST.yaml"
}

expect_pass() {
if ! "$@" >/dev/null 2>&1; then
echo "FAIL: expected success: $*" >&2
exit 1
fi
}

expect_fail() {
if "$@" >/dev/null 2>&1; then
echo "FAIL: expected failure: $*" >&2
exit 1
fi
}

printf 'payload\n' > "$TEST_DIR/payload.txt"
valid_hash="$(hash_file "$TEST_DIR/payload.txt")"

write_manifest " hash: sha256:$valid_hash"
expect_pass "$VALIDATOR" "$TEST_DIR"

write_manifest " hash: null"
expect_pass "$VALIDATOR" "$TEST_DIR"
rm "$TEST_DIR/payload.txt"
expect_fail "$VALIDATOR" "$TEST_DIR"
printf 'payload\n' > "$TEST_DIR/payload.txt"
rm "$TEST_DIR/payload.txt"
expect_fail "$VALIDATOR" "$TEST_DIR"
printf 'payload\n' > "$TEST_DIR/payload.txt"

for hash_line in \
"" \
" hash: sha256:not-a-hash" \
" hash: sha256:${valid_hash%?}" \
" hash: md5:$valid_hash"; do
write_manifest "$hash_line"
expect_fail "$VALIDATOR" "$TEST_DIR"
expect_pass "$VALIDATOR" --update "$TEST_DIR"
expect_pass "$VALIDATOR" "$TEST_DIR"
done

printf 'bundle: test\nfiles:\n - path: payload.txt\n role: reference\n hash: sha256:%s\n hash: sha256:%s\n' \
"$valid_hash" "$valid_hash" > "$TEST_DIR/MANIFEST.yaml"
expect_fail "$VALIDATOR" "$TEST_DIR"
expect_fail "$VALIDATOR" --update "$TEST_DIR"

echo "validate.sh hash-state regression tests passed"
6 changes: 6 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ jobs:

- name: Verify release surfaces
run: ./.github/scripts/release-surface-check.sh

- name: Verify action input transport
run: ./.github/scripts/action-security-check.sh

- name: Test validator hash states
run: ./.github/scripts/test-validate.sh
1 change: 1 addition & 0 deletions AGENTIC_SURFACES.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ the action.
| `.github/workflows/validate.yml` | CI checker for manifest validation, derived package builds, and release-surface drift checks. | Release-confidence automation. Passing CI supports review but does not certify safety, author identity, or runtime behavior. |
| `action.yml` | GitHub Actions Marketplace metadata and composite action wrapper for `skill-provenance/validate.sh`. | Code-executing CI entrypoint. It validates a bundle manifest in the workflow workspace but does not certify trust or safety. |
| `.github/scripts/release-surface-check.sh` | CI and local release-surface drift checker for eval counts, GuideCheck sidecar metadata, and `.skill` ZIP freshness. | Code-executing release-confidence automation. It verifies declared release surfaces against local files but is not a trust anchor or safety certification. |
| `.github/scripts/action-security-check.sh` and `.github/scripts/test-validate.sh` | Regression checks for composite-action input transport and validator hash-state behavior. | Code-executing test helpers. They exercise bounded local fixtures and do not certify unrelated runtime safety. |
| `skill-provenance.skill` | Claude Settings ZIP wrapper around the canonical bundle. | Release artifact. Verify against release provenance before installing. |
## Maintenance rule
When adding or changing an assistant-facing surface, update this file if
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ skill-provenance/ ← Canonical source bundle (DO NOT rename)
├── README.md ← Human-facing user guide (has internal version header)
├── MANIFEST.yaml ← File inventory: roles, versions, SHA-256 hashes
├── CHANGELOG.md ← Recent in-bundle change history (last 5 entries)
├── evals.json ← 30 core evaluation scenarios
├── evals-distribution.json ← 16 supplemental distribution evals
├── evals.json ← 33 core evaluation scenarios
├── evals-distribution.json ← 17 supplemental distribution evals
├── validate.sh ← Bash script for local hash verification
└── package.sh ← Bash script for derived strict/ClawHub outputs
action.yml ← GitHub Actions Marketplace wrapper for validate.sh
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ The in-bundle file at `skill-provenance/CHANGELOG.md` is the active changelog
that travels with the skill bundle and keeps only the five most recent entries
to limit package weight. Older history remains here in the repo root.

## 5.0.0 - 2026-07-10
- skill-provenance/validate.sh: Made manifest verification fail closed on
missing, malformed, or duplicate hash fields; added explicit
`hash: null` opt-outs; repaired missing or malformed hashes in update
mode; and kept inventory checks active for opted-out files.
- action.yml: Transported caller-controlled `bundle-path` through an
environment variable instead of interpolating it into Bash source.
- .github/scripts/action-security-check.sh,
.github/scripts/test-validate.sh, .github/workflows/validate.yml: Added
and enabled regression coverage for action input transport and validator
hash-state behavior.
- skill-provenance/SKILL.md and skill-provenance/README.md: Defined and
documented the explicit hash contract and breaking fail-closed behavior.
- skill-provenance/evals.json: Added 3 core security and recovery evals.
- skill-provenance/evals-distribution.json: Added a composite-action shell
safety eval. Coverage is now 33 core and 17 supplemental, 50 total.
- skill-provenance/MANIFEST.yaml and skill-provenance/CHANGELOG.md: Bumped
the canonical bundle to 5.0.0, advanced per-file versions, updated the
rolling history, and refreshed inventory metadata.
- README.md, AGENTS.md, CLAUDE.md, AGENTIC_SURFACES.md, and index.html:
Updated eval counts, executable-surface disclosure, release version, and
public modified date.
- skill-provenance.skill: Rebuilt the Claude Settings ZIP from the
canonical 5.0.0 bundle.

## 4.13.1 - 2026-06-23
- action.yml: Added a root GitHub Actions Marketplace composite action
wrapper that runs `skill-provenance/validate.sh` against a configurable
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ A metaskill for version tracking across Agent Skills sessions, surfaces, and pla
- `skill-provenance/SKILL.md` -- the skill definition (what agents read)
- `skill-provenance/MANIFEST.yaml` -- file inventory with roles, versions, SHA-256 hashes
- `skill-provenance/CHANGELOG.md` -- rolling recent history (last 5 entries)
- `skill-provenance/evals.json` -- 30 core evaluation scenarios
- `skill-provenance/evals-distribution.json` -- 16 supplemental distribution evals
- `skill-provenance/evals.json` -- 33 core evaluation scenarios
- `skill-provenance/evals-distribution.json` -- 17 supplemental distribution evals
- `skill-provenance/validate.sh` -- local hash verification script
- `skill-provenance/package.sh` -- derived copy generator (strict/ClawHub)
- `action.yml` -- GitHub Actions Marketplace wrapper for bundle validation
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ tells you whether a specific copy matches. Together they answer both
.claude-plugin/plugin.json <- Claude Code plugin manifest
action.yml <- GitHub Actions Marketplace wrapper
.github/scripts/release-surface-check.sh <- Release-surface drift check
.github/scripts/action-security-check.sh <- Composite-action input safety regression
.github/scripts/test-validate.sh <- Validator hash-state regression suite
skills/open/SKILL.md <- /skill-provenance:open (verify bundle on session start)
skills/validate/SKILL.md <- /skill-provenance:validate (hash/inventory check only)
skills/close/SKILL.md <- /skill-provenance:close (update versions on session end)
Expand All @@ -283,8 +285,8 @@ skill-provenance/ <- Canonical source bundle (metadata mode)
README.md <- User guide: workflows, worked example, troubleshooting
MANIFEST.yaml <- File inventory with roles, versions, hashes
CHANGELOG.md <- Recent in-bundle history (last 5 entries)
evals.json <- 30 core evaluation scenarios
evals-distribution.json <- 16 supplemental packaging/deployment/integrity evals
evals.json <- 33 core evaluation scenarios
evals-distribution.json <- 17 supplemental packaging/deployment/integrity evals
validate.sh <- Local hash verification script
package.sh <- Zero-dependency helper for derived copies
CHANGELOG.md <- Full append-only repo history
Expand All @@ -297,8 +299,8 @@ The directory is the canonical cross-platform source bundle. The `.skill` file i

## Evals

46 evaluation scenarios across two files: 30 core workflow evals in
[evals.json](skill-provenance/evals.json) and 16 supplemental
50 evaluation scenarios across two files: 33 core workflow evals in
[evals.json](skill-provenance/evals.json) and 17 supplemental
distribution/package/integrity evals in
[evals-distribution.json](skill-provenance/evals-distribution.json).

Expand Down
4 changes: 3 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ runs:
steps:
- name: Validate Skill Provenance manifest
shell: bash
run: '"$GITHUB_ACTION_PATH/skill-provenance/validate.sh" "${{ inputs.bundle-path }}"'
env:
BUNDLE_PATH: ${{ inputs.bundle-path }}
run: '"$GITHUB_ACTION_PATH/skill-provenance/validate.sh" "$BUNDLE_PATH"'
12 changes: 6 additions & 6 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<meta property="og:site_name" content="Skill Provenance">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2026-01-31T00:00:00Z">
<meta property="article:modified_time" content="2026-06-23T00:00:00Z">
<meta property="article:modified_time" content="2026-07-10T00:00:00Z">
<meta property="article:author" content="Sam Rogers">
<meta property="article:publisher" content="https://paice.work/">
<meta property="article:section" content="Agent Skills">
Expand All @@ -47,7 +47,7 @@
"headline": "Skill Provenance - Portable provenance for Agent Skills",
"description": "Portable provenance, integrity, and drift control for Agent Skills across local folders, registries, platform uploads, and multi-agent sessions.",
"datePublished": "2026-01-31",
"dateModified": "2026-06-23",
"dateModified": "2026-07-10",
"author": {
"@type": "Person",
"name": "Sam Rogers",
Expand Down Expand Up @@ -524,9 +524,9 @@ <h1>Skill Provenance</h1>
<span class="sep">&middot;</span>
Published <time datetime="2026-01-31">January 31, 2026</time>
<span class="sep">&middot;</span>
Updated <time datetime="2026-06-23">June 23, 2026</time>
Updated <time datetime="2026-07-10">July 10, 2026</time>
<span class="sep">&middot;</span>
<span class="version">v4.13.0</span>
<span class="version">v5.0.0</span>
<span class="sep">&middot;</span>
<a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="license noopener">CC&nbsp;BY&nbsp;4.0</a>
</p>
Expand Down Expand Up @@ -738,7 +738,7 @@ <h3>Manual (any platform)</h3>
<div class="label"><a href="https://clawhub.ai/snapsynapse/skill-provenance" target="_blank" rel="noopener">ClawHub</a> installs</div>
</div>
<div class="signal">
<div class="number warm">46</div>
<div class="number warm">50</div>
<div class="label">evaluation scenarios</div>
</div>
<div class="signal">
Expand All @@ -757,7 +757,7 @@ <h3>Manual (any platform)</h3>
<div class="container">
<div class="footer-grid">
<div class="footer-meta">
<p>Skill Provenance v4.13.0 &middot; <a href="https://github.com/snapsynapse/skill-provenance/blob/main/LICENSE" target="_blank" rel="noopener license">MIT</a></p>
<p>Skill Provenance v5.0.0 &middot; <a href="https://github.com/snapsynapse/skill-provenance/blob/main/LICENSE" target="_blank" rel="noopener license">MIT</a></p>
<p>A <a href="https://paice.work/" target="_blank" rel="noopener">PAICE.work</a> project.</p>
<p style="margin-top: 0.5rem;">See also: <a href="https://knowledge-as-code.com/" target="_blank" rel="noopener">Knowledge as Code</a> &middot; <a href="https://gracefulboundaries.dev/" target="_blank" rel="noopener">Graceful Boundaries</a></p>
</div>
Expand Down
Binary file modified skill-provenance.skill
Binary file not shown.
30 changes: 17 additions & 13 deletions skill-provenance/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ travels with the package.
Full release history lives in the source repository's top-level
`CHANGELOG.md`.

## 5.0.0 - 2026-07-10
- validate.sh: Changed verification to fail closed on missing, malformed,
or duplicate hash fields; added explicit `hash: null` opt-outs; made
update mode repair missing or malformed hashes; and retained inventory
presence checks for opted-out files.
- SKILL.md: Defined the explicit hash contract and fail-closed validation
behavior.
- README.md: Documented explicit null opt-outs, update repair, and the
breaking change from implicit hash omission.
- evals.json: Added 3 core scenarios for fail-closed verification,
explicit null semantics, and update repair. Core eval count is now 33.
- evals-distribution.json: Added a GitHub Action input-safety scenario.
Supplemental eval count is now 17; total eval count is now 50.
- MANIFEST.yaml: Bumped the bundle to 5.0.0, updated file versions and
inventory notes, and refreshed hashes.
- CHANGELOG.md: Added this entry and retained the newest 5 releases.

## 4.13.0 - 2026-06-23
- SKILL.md: Added optional `origin` metadata guidance for derived,
installed, registry, settings, or platform-export copies whose selected
Expand Down Expand Up @@ -57,17 +74,4 @@ Full release history lives in the source repository's top-level
- MANIFEST.yaml: Bumped bundle to 4.10.1, updated bundle_date, advanced
README.md and CHANGELOG.md per-file versions, and refreshed hashes.

## 4.10.0 — 2026-05-19
- SKILL.md: Added validate-only protocol guidance and clarified how
Skill Provenance complements source, registry, package-manager, and
platform versioning.
- README.md: Reframed the guide around portable author-side provenance,
added a "Why this still exists" section, documented the validate command,
added complementary-tool guidance, and clarified the trust model.
- evals.json: Added 4 core evals covering validate-only behavior,
complementary-tool positioning, integrity versus trust-anchor language,
and derived-copy validation.
- MANIFEST.yaml: Bumped bundle to 4.10.0, updated bundle_date, advanced
changed file versions, refreshed hashes, and updated eval inventory notes.

Older entries archived in the source repository's top-level CHANGELOG.md.
Loading
Loading