Shared-Skills-Sync Skill
Sync eligible Hermes skills to a shared git repo safely.
Publish and pull Hermes skills between a profile directory (e.g.
~/.hermes/skills) and a shared git repository. It is deliberately boring:
it inventories every skill with checksums, excludes private runtime state and
detected credential shapes during publication, checks a configured branch prefix,
refuses conflicting files by default, and records provenance for imports. Operators
must independently verify exact assigned-branch ownership and audit import content. It never force-pushes and never touches a network on its own — pushing
is the operator's explicit step.
It does not email, post, or create PRs, and it does not modify profiles other than the one you point it at.
When to Use
- Publishing the eligible skills of a profile into a shared repo (or back).
- Building a checksummed inventory of a profile to see exactly what would be published and what is excluded.
- Importing a single skill from a shared repo into a local profile with a provenance record.
Don't use for: creating skills (use the authoring workflow), PR/review lifecycle, or force-pushing history.
Fleet onboarding
See the new-agent runbook in repository main
for the complete branch/authentication/import/publish workflow. When this skill is
installed outside the checkout, use https://github.com/jknash/hermes-shared-skills/blob/main/docs/NEW-AGENT-RUNBOOK.md.
Important implementation limits: --branch checks a prefix, not exact ownership;
verify symbolic-ref equality separately. Publish conflict reports can exit zero.
The import source argument must be the checkout skills/ directory. Imports
need operator preflight for private state, name collisions, traversal, symlinks and
all file types; the helper is not a security sandbox. Never use broad overwrite
flags or trust an unaudited whole-profile inventory.
Prerequisites
git(>= 2.x). All operations are local to the repository; no token or network is required by this skill.- A profile directory containing skills at
<profile>/<category>/<skill>/SKILL.md(categories optional). - For
publish, verify the target checkout's branch equals your owner-assigned branch exactly. Pass that value to--branch; its prefix check alone is insufficient.
Quick Reference
Use terminal for these commands, with the review checkpoints in Procedure.
These are separate operations, not a block to run unattended.
set -euo pipefail
# Replace these with your owner-assigned branch and verified local paths.
OWNED_BRANCH='hermes-your-assigned-agent-id'
REPO='/path/to/repo'
PROFILE_SKILLS='/path/to/active-profile/skills'
test "$OWNED_BRANCH" != 'hermes-your-assigned-agent-id'
test "$(git -C "$REPO" symbolic-ref --short HEAD)" = "$OWNED_BRANCH"
SYNC="$REPO/skills/software-development/shared-skills-sync/scripts/sync.py"
# Inventory, then review every exclusion and proposed file.
python3 -B "$SYNC" inventory "$PROFILE_SKILLS"
python3 -B "$SYNC" publish "$PROFILE_SKILLS" "$REPO" --branch "$OWNED_BRANCH" --dry-run
# Only after the reviewed plan has no conflicts or unexplained exclusions:
python3 -B "$SYNC" publish "$PROFILE_SKILLS" "$REPO" --branch "$OWNED_BRANCH"
# Separate import example; requires pinned-source and missing-only preflight.
python3 -B "$SYNC" import-skill /path/to/pinned-checkout/skills cat/name "$PROFILE_SKILLS"
Procedure
- Inventory first. Run the
inventorysubcommand against the profile. Confirm theskill_count,file_count, and eachexcludedentry (private runtime state such as.usage.json,.curator_state,.curator_ledger.jsonl,.bundled_manifest,.usage.json.lock, or a secret-detected file). Completion: every excluded file is understood; no real credential is in the publish set. - Verify branch ownership. Resolve
git symbolic-ref --short HEADin the target checkout and require exact equality with the owner-assigned$OWNED_BRANCH. Pass that value to--branch. The engine only checks a prefix; it cannot establish ownership or reject all similarly named foreign branches. Completion: exact equality verified, clean checkout, assigned owner confirmed. - Dry-run the publish. Run
publish --dry-run. It prints the plan (add/update/unchanged/conflictcounts) and every exclusion without writing. Completion: noconflictyou would not want to act on. - Publish for real. Re-run without
--dry-run. By default differing target files are conflicts and are left untouched; only use--allow-overwritewhen you explicitly intend to clobber. Completion: theapplied/unchanged/conflictsline matches the dry-run, and no excluded file was written. - Commit reviewed paths locally. Stage only explicitly reviewed skill paths,
inspect the staged diff (including new files), then commit. Do not use a blanket
git add -A. The skill never pushes. Completion: clean checkout on the exact assigned branch; required independent review before explicit non-force push.
Pitfalls
-
Read the security model first.
references/security-privacy.mddocuments exactly what is excluded (private runtime state, secret-detected files), the placeholder rule, branch-ownership and conflict semantics. -
Placeholders are not secrets. A doc example like
ghp_+ 20 repeated characters orsk-+ repeated characters is a placeholder and is not flagged; a varied 20+ char body is flagged. This is why the scanner checks the token body, not just the prefix. -
Conflicts are refusal, not overwrite. A target file that differs from the source is left exactly as-is and reported;
--allow-overwriteis the only way to replace it, and it is off by default. -
Excluded files are never written, even with
--allow-overwrite. Secret and private-runtime files are hard-excluded at inventory time. -
Categories are preserved. A skill's
<category>/<name>path is kept verbatim on both publish and import.
Verification
python3 -B -m unittest discover -s tests -p 'test_sync.py' -v
All tests must pass, including: idempotence (a second publish writes 0 files),
exclusions (private state and a secret-bearing file are reported and never
written), branch ownership (main / foreign / detached HEAD refused, owned
hermes-* allowed), supporting files (references/ and templates/ are written),
and conflict refusal (a differing target file is not overwritten).
Supporting files: this skill's supporting files are held in the docsite at
docs/15-skills/_support/software-development/shared-skills-sync/— fetch them fresh fromjknash/docsitemain alongside this page. Source:jknash/hermes-shared-skills· branchhermes-jkdev001@1d0d545c3970·skills/software-development/shared-skills-sync/· view source · Imported 2026-10-03. Supporting files (references, scripts) remain in the source repository.
version 0.1.0 · author Justin Knash (jknash), Hermes Agent · license MIT.
Published by Muse · 2026-10-03.