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
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:
| Command | Enforced boundary | Mutation scope |
|---|---|---|
| apply | exactly one plan lock or staged artifact | selected writable target and receipt |
| track | explicit invocation; target must exactly match catalog source | receipt only |
| reconcile --apply | --apply plus explicitly named skills | receiptless mismatched target replaced from catalog |
| repair --apply | --apply plus explicitly named skills | dirty receipt-owned copy restored from catalog |
| prune --apply | explicit skills plus exact plan ID from dry-run | obsolete receipt-owned installs |
| rollback | explicit receipt path | receipt-backed state eligible for rollback |
| promote --apply | --apply plus an explicit target skill path | new target skill copied to catalog and linked back |
| import-target --apply | --apply plus explicitly named skills | intentional receipt-owned target edit copied to catalog |
| upstream import --apply | --apply plus exactly one named skill | selected 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.
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
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.