Skill Suitcasedocs

03Model · Safety

Inspect, stage, then mutate.

Skill Suitcase separates three decisions. Inspect state without mutation. Stage or record planned work for review. Mutate only through the approval boundary the selected command enforces.

The three phases

1 Inspect import · validate · targets · plan · status · diff · --dry-run modes · upstream check · upstream fetch --dry-runRead-only commands explain current state. They never create install roots, runtime homes, receipts, symlinks, or catalog files.
2 Stage pack --output "$OUT" · buildPlanLock (library API)Stage an immutable bundle beneath an explicit output directory, or build a deterministic plan lock, then review the ordinary filesystem and Git changes.
3 Mutate apply · targeted --apply commands · receipt-backed rollbackLive mutation requires the explicit, command-specific boundary below. Transactional workflows restore pre-operation state when an operation fails.

Approval inputs

apply requires exactly one of --lock or --artifact, and the two inputs make different promises. Lock mode reassesses the current plan and file hashes against the deterministic lock. Artifact mode validates the bundle manifest, but ordinary missing or behind writes are rebuilt from current catalog source; artifact file hashes gate only the dirty-behind exception.

Boundary

An older staged artifact is not byte-for-byte authorization for every later write. Re-run pack immediately before an artifact apply and inspect the current diff. Neither approval input binds the resolved install root, CLI path overrides, or copy-versus-symlink mode; approve those at apply time.

apply is transactional, refuses unmanaged targets, preserves executable file modes, and updates the target receipt with a record for every managed skill. --mode symlink links selected current catalog source into the target and records that mode explicitly.

Mutation boundaries

The CLI enforces exactly these boundaries, one per command:

CommandEnforced boundaryMutation scope
applyexactly one plan lock or staged artifactselected writable target and receipt
trackexplicit invocation; target must exactly match catalog sourcereceipt only
reconcile --apply--apply plus explicitly named skillsreceiptless mismatched target replaced from catalog
repair --apply--apply plus explicitly named skillsdirty receipt-owned copy restored from catalog
prune --applyexplicit skills plus exact plan ID from dry-runobsolete receipt-owned installs
rollbackexplicit receipt pathreceipt-backed state eligible for rollback
promote --apply--apply plus an explicit target skill pathnew target skill copied to catalog and linked back
import-target --apply--apply plus explicitly named skillsintentional receipt-owned target edit copied to catalog
upstream import --apply--apply plus exactly one named skillselected catalog source and upstream lock only

Commands validate containment, ownership, current filesystem state, and relevant hashes before destructive work. They do not auto-commit catalog changes, and drift is never inferred approval.

Receipts

The receipt at .skill-suitcase-receipt.json is the target-side ownership record, schema calvinnwq.skills.receipt.v0. A managed install record captures the skill, target path, source path and provenance, install mode, relative destination, version and content hashes, installed-file hashes, and rollback metadata when available. Flat legacy records without destination remain valid; categorized Hermes ownership requires <category>/<skill>.

Receipt updates use atomic replacement and a receipt-local transaction lock, so concurrent workflows cannot silently discard one another's records. A receipt proves what Skill Suitcase recorded; commands still compare it with the current catalog and filesystem before mutation. Safety-sensitive workflows may refuse a legacy .skills-sync.json receipt rather than migrating ownership implicitly.

Categorized Hermes boundary

hermes-external-skills-root materializes assigned skills beneath one Skill Suitcase-owned external root while leaving <home>/skills untouched. One receipt at the external root owns every categorized destination.

Preconditions

The root must already exist, be registered in Hermes skills.external_dirs, and not overlap the local skills tree or an earlier external root. Local, earlier external, and owned-root skill identities must not shadow a plan, planned identities must be unique, and category symlinks are refused. Skill Suitcase validates these conditions before live target work and revalidates containment during mutation and rollback.

The status enum

status classifies each catalog-planned target entry. These seven values are the complete enum; read-only is target metadata, not a status value.

currentfor copy installs, receipt-owned files match the receipt and its version and hash match catalog source; preserved extras outside installedFiles do not make the skill dirty. Symlink installs point at the selected catalog source and sourcePolicy.exclude is empty; the stored receipt version and hash are not revalidated on that path
missingthe planned target is absent
versionthe installed receipt version differs from current SKILL.md frontmatter
behindreceipt-owned target is unchanged but the catalog moved ahead
dirtylive receipt-owned target drifted; stop and inspect before any mutation
blockedmanifest or target policy prevents the install
unknownstatus could not be proven; only the receiptless mismatched-directory case routes to reconcile

Provider fallback inventory without a catalog assignment appears with statusCount: 0 and no status entries. What to do for each state is on the troubleshooting page.

Never without approval

Approval required

Never run live apply, track, reconcile --apply, repair --apply, prune --apply, rollback, promote --apply, import-target --apply, or upstream import --apply against a real catalog or runtime home without explicit approval for the source, target, and mode.

The normative contract behind this page is SPEC.md; per-command preconditions live in the CLI reference.