T-M8AL-name-and-field-spec-validation
State: planning/proposed · Impact: high · Complexity: small
Every name and description in the experience is validated only on the Rust side, at publish or
read time — the wizard and rename dialog accept anything and echo nothing back. A user who types
an uppercase or over-long name learns it is invalid only after the file already exists with a
silently-slugged name, or not at all until a build refuses it. This task moves the Agent Skills
spec’s name and description rules to the input, and closes a length disagreement between the
two Rust validators along the way.
| Location | Role today |
|---|---|
solutions/agent-pants/crates/agent-adapt-core/src/discover.rs#validate_name | Checks a name is 1–63 chars of a-z0-9-, no edge/doubled hyphen; message says “1–63” though the spec caps at 64 |
packages/rust/agent-adapt/src/naming.rs | SKILL_NAME_MAX_LEN = 64; slugify_skill_name truncates to 64 and refuses an empty slug |
solutions/agent-pants/crates/agent-adapt-core/src/discover.rs | description.chars().count() > 1024 is refused (line ~836), naming the field and the overrun |
solutions/determined/crates/determined-agent-skills/src/lib.rs#derive_create | Slugifies via agent_adapt’s slugify (not slugify_skill_name) and refuses only an empty slug; no length or charset echo back to the caller |
solutions/determined/experiences/agent-pants/app/components/ApNewComponentWizard.vue | fields.name is a plain v-model text input (DFieldRow label="Name"); the only client check is fields.value.name.trim() === '' → “Needs a name.” |
solutions/determined/experiences/agent-pants/app/components/ApRenameDialog.vue | newName is a plain ref bound to DInput; validation is “type something different from the current name”, no slug echo, no charset or length check |
solutions/determined/experiences/agent-pants/app/components/SkillFieldsForm.vue | description field (s('description')) has no character counter and no 1024 cap |
solutions/determined/experiences/agent-pants/app/utils/fieldSpec.ts | FIELD_SPECS carries label/help/kinds per field; no validation rule |
solutions/agent-pants/docs/vault/research/agent-skills-conformance.md | Names the 63-vs-64 disagreement and the missing client validation as open findings |
Proposed
Section titled “Proposed”A shared TS validator, app/utils/skillSpec.ts, mirrors the spec exactly:
^[a-z0-9]+(-[a-z0-9]+)*$ for name (1–64 chars), description 1–1024 chars,
compatibility 1–500 chars, metadata a string-to-string map. ApNewComponentWizard.vue
normalizes the name as the user types — live slug echo, refuses an invalid result — and
ApRenameDialog.vue does the same for its newName field. SkillFieldsForm.vue’s description
field shows a live character counter and refuses past 1024. On the Rust side,
discover.rs#validate_name and agent-adapt’s SKILL_NAME_MAX_LEN agree on 64, backed by a
test that pins the shared limit.
Approach
Section titled “Approach”- Decide and fix the 63-vs-64 disagreement: raise
validate_name’s cap to 64 (value.len() <= 64) and its message, matchingSKILL_NAME_MAX_LEN; add a test asserting a 64-char name passes and a 65-char name is refused by both validators. - Write
app/utils/skillSpec.ts: a pure functionvalidateSkillName(input): { slug: string } | { error: string }mirroringvalidate_name’s charset/length/hyphen rule, plusvalidateDescription,validateCompatibility,validateMetadata. - Wire
ApNewComponentWizard.vue’s name field throughskillSpec.ts: show the live slug as the user types (a muted preview line under the input, matching how the plugin key preview already works at line ~836), and disable Next/Create on an invalid result with the validator’s message. - Wire
ApRenameDialog.vue’snewNamethe same way: live slug preview, refuse an invalid result before the preview fetch fires. - Add a character counter and 1024 cap to
SkillFieldsForm.vue’s description field, reading the cap fromskillSpec.tsrather than a hardcoded number. - Add fixtures from the spec’s invalid examples (empty, uppercase, edge hyphen, doubled hyphen,
over-length) as a
skillSpec.test.tstable test.
| Area | Note |
|---|---|
solutions/agent-pants/crates/agent-adapt-core/src/discover.rs | validate_name cap 63 → 64; message text; a boundary test |
solutions/determined/experiences/agent-pants/app/utils/skillSpec.ts | Shared name/description/compatibility/metadata validator mirroring the spec |
solutions/determined/experiences/agent-pants/app/utils/skillSpec.test.ts | Table test over the spec’s invalid examples plus boundary cases |
solutions/determined/experiences/agent-pants/app/components/ApNewComponentWizard.vue | Live slug echo and inline refusal on the name field |
solutions/determined/experiences/agent-pants/app/components/ApRenameDialog.vue | Live slug echo and inline refusal on newName |
solutions/determined/experiences/agent-pants/app/components/SkillFieldsForm.vue | Description character counter and 1024 cap |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: Typing
My Skill!, an uppercase name, or a 70-character name into the wizard’s Name field shows a live slug or an inline refusal before Create is pressed; the same holds forApRenameDialog.vue’s field. - AC-2:
SkillFieldsForm.vue’s description field shows a running character count and refuses to accept a 1025th character. - AC-3:
discover.rs#validate_nameandagent-adapt::naming::SKILL_NAME_MAX_LENboth cap at 64, asserted by a shared-limit test in each crate. - AC-4:
skillSpec.test.tspasses against every invalid example in the spec’snamegrammar (empty, uppercase, edge hyphen, doubled hyphen, over-64) and the description/compatibility boundaries (0, 1, 1024, 1025, 500, 501 characters). - AC-5:
moon run experience-agent-pants:checkpasses.
Out of scope
Section titled “Out of scope”license,compatibility, andmetadataas modelled fields onSkill/SkillContent— T-GLK0-spec-fields-and-skills-ref-oracle.- Running
skills-ref validateover rendered output — also T-GLK0-spec-fields-and-skills-ref-oracle. - The empty-slug collapse hazard (G6) and peer-resource path escape (G8) from
agent-skills-conformance.md— neither is this task’s scope.
Dependencies
Section titled “Dependencies”- none
Discovery context
Section titled “Discovery context”From the user’s Agent Manager planning request of 2026-09-07, “Spec adherence today” section:
naming and validation is the first of eight brain-dump areas. Findings sourced from
solutions/agent-pants/docs/vault/research/agent-skills-conformance.md’s name/description
rows and the 63-vs-64 disagreement it documents between discover.rs#validate_name and
agent-adapt’s SKILL_NAME_MAX_LEN. Spec facts from
agentskills.io/specification, fetched 2026-09-07: name
required, 1–64, a-z0-9-, no edge or doubled hyphen; description required, 1–1024.