pub(crate) fn starter_skill_id(trigger: &str) -> UuidExpand description
Deterministic row id for a starter skill, derived from its trigger.
A bare name match is not a safe way to recognize “the same skill” across
stores in general — managed_upsert_unique enforces name uniqueness only
WITHIN one owner (a bundle, or the global tier), so two different bundles
can each legitimately hold a private skill called the same thing with
different content (SPEC_DURABLE_BINDINGS_2026_09_10.md §5.3). Collapsing
on name alone would discard one payload and cross-link edits between two
owners that never agreed to share a row.
The ambiguity does not apply to a SEEDED global row specifically: it is owned by nobody, so two stores minting one under the same key are, by construction, minting the same resource. Giving that case a stable id up front means a later cross-store reconciliation does not need the name-matching heuristic at all for anything this function produced — only for genuinely user-created rows, which is the case that heuristic was actually built for.
trigger, not name or content: name is display text a maintainer
could reword without changing what skill this is, and content gets
wording fixes over time — neither should mint a new identity. trigger
is the stable slash-command slug already surfaced to the user
(docs/CLAUDE.md’s own “Available Skills” list uses it as the anchor),
so a change to it is already understood elsewhere in the codebase as
meaning “this is a different skill.”
The namespace is itself derived via Uuid::new_v5 from a fixed, documented
seed string rather than a hand-picked random constant, so the value here
is reproducible and auditable from this source file alone rather than an
opaque UUID nobody can regenerate if this file is ever lost.