From forge-core
Audit forge module provenance and deployment integrity — inspect deployed sidecars, detect drift, clean stale artifacts after renames, trace adoption chains. USE WHEN running forge provenance, auditing a deployed target, debugging drift, cleaning up after a skill rename, or investigating sidecar state.
npx claudepluginhub n4m3z/forge-coreThis skill is limited to using the following tools:
Operational procedures for auditing `.provenance/` sidecars in forge deployments and source repos. Complements [ProvenanceVerification][PROV] (what provenance means) and [CrossProviderAssembly][ASM] (how assembly rewrites sidecars).
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Processes PDFs: extracts text/tables/images, merges/splits/rotates pages, adds watermarks, creates/fills forms, encrypts/decrypts, OCRs scans. Activates on PDF mentions or output requests.
Share bugs, ideas, or general feedback.
Operational procedures for auditing .provenance/ sidecars in forge deployments and source repos. Complements ProvenanceVerification (what provenance means) and CrossProviderAssembly (how assembly rewrites sidecars).
forge provenance expects a deployed provider directory (~/.claude, ~/.opencode, ~/.codex, ~/.gemini) — the deploy sidecars it reads are written by forge install in assemble/v1 form. Running it against a source module (forge provenance . inside a repo) reports every subject as orphan, because source sidecars use adopt/v1 or init/v1 buildTypes that the audit reader doesn't resolve.
forge provenance ~/.claude # audit user-scope deployment
forge provenance ~/.claude --show-orphans # include unverified files
forge provenance ~/.claude --json # machine-readable output
Per-module results look like:
https://github.com/N4M3Z/forge-core → ✓ 156 verified
https://github.com/N4M3Z/forge-dev → ✓ 53 verified
forge-text → ✗ 21/22 verified
A ✗ means at least one deployed file's digest doesn't match its sidecar — either a post-deploy edit or a tamper. Diff the deployed file against build/<provider>/<path> to identify what drifted.
Deployed sidecars carry the assemble/v1 buildType with a single input (the source file). The richer adopt/v1 sidecar — with upstream URL, pinned commit, AdoptArtifact reference, and transform-skill digests — exists only in the source repo.
cat Modules/forge-dev/agents/.provenance/CodeReviewer.yaml
# resolvedDependencies:
# - name: upstream
# uri: https://raw.githubusercontent.com/davila7/...
# digest: sha256:...
# - name: AdoptArtifact
# uri: forge-core/skills/AdoptArtifact/SKILL.md
# digest: sha256:...
Never expect the deployed sidecar to carry this — assembly strips it by design (CrossProviderAssembly).
forge install is additive, not idempotent for renames. After renaming skills/OldName → skills/NewName and reinstalling, the old directory persists at every deployed target. Explicit cleanup is required across every provider:
for provider in .claude .codex .opencode .gemini; do
dir="$HOME/$provider/skills/OldName"
[ -d "$dir" ] && rm -rf "$dir"
done
If the safety-net plugin blocks rm -rf paths outside cwd, use a per-file loop (find "$dir" -type f -delete; find "$dir" -type d -empty -delete) or ask the user to run the cleanup in their terminal.
After cleanup, confirm: ls ~/.claude/skills/ | grep -iE "OldName|NewName" should return only NewName.
Renaming a skill, agent, or transform that appears as a resolvedDependencies entry in OTHER artifacts' sidecars has ecosystem-wide impact. Every sidecar referencing the old identifier (name, uri, digest if the content changed) must be updated:
# Find all sidecars that reference the old name as a dependency
rg -l "name: OldName" --glob "**/.provenance/*.yaml"
# Update in bulk — reuse a known-good new digest
find . -name "*.yaml" -path "*.provenance*" | while read -r f; do
if grep -q "name: OldName" "$f"; then
sed -i '' \
-e 's|name: OldName|name: NewName|g' \
-e 's|skills/OldName/SKILL\.md|skills/NewName/SKILL.md|g' \
-e 's|<old-digest>|<new-digest>|g' \
"$f"
fi
done
Before calling a rename complete, grep the entire Modules/ tree for the old name — sidecars in sibling modules are the most-missed targets.
--show-orphans lists deployed files with no sidecar. Common causes:
forge install) — reinstall or delete<basename>.yaml but some writers produce <basename>.md.yaml (see forge-cli#31).codex deployments may report "No provenance found" despite sidecars present (see forge-cli#29)Known forge-cli limitations: adopt/v1 sidecars aren't rendered by the CLI (schema mismatch on externalParameters.source — see forge-cli#30). For those, cat the YAML directly.