Skip to content

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.

LocationRole today
solutions/agent-pants/crates/agent-adapt-core/src/discover.rs#validate_nameChecks 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.rsSKILL_NAME_MAX_LEN = 64; slugify_skill_name truncates to 64 and refuses an empty slug
solutions/agent-pants/crates/agent-adapt-core/src/discover.rsdescription.chars().count() > 1024 is refused (line ~836), naming the field and the overrun
solutions/determined/crates/determined-agent-skills/src/lib.rs#derive_createSlugifies 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.vuefields.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.vuenewName 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.vuedescription field (s('description')) has no character counter and no 1024 cap
solutions/determined/experiences/agent-pants/app/utils/fieldSpec.tsFIELD_SPECS carries label/help/kinds per field; no validation rule
solutions/agent-pants/docs/vault/research/agent-skills-conformance.mdNames the 63-vs-64 disagreement and the missing client validation as open findings

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.

  1. Decide and fix the 63-vs-64 disagreement: raise validate_name’s cap to 64 (value.len() <= 64) and its message, matching SKILL_NAME_MAX_LEN; add a test asserting a 64-char name passes and a 65-char name is refused by both validators.
  2. Write app/utils/skillSpec.ts: a pure function validateSkillName(input): { slug: string } | { error: string } mirroring validate_name’s charset/length/hyphen rule, plus validateDescription, validateCompatibility, validateMetadata.
  3. Wire ApNewComponentWizard.vue’s name field through skillSpec.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.
  4. Wire ApRenameDialog.vue’s newName the same way: live slug preview, refuse an invalid result before the preview fetch fires.
  5. Add a character counter and 1024 cap to SkillFieldsForm.vue’s description field, reading the cap from skillSpec.ts rather than a hardcoded number.
  6. Add fixtures from the spec’s invalid examples (empty, uppercase, edge hyphen, doubled hyphen, over-length) as a skillSpec.test.ts table test.
AreaNote
solutions/agent-pants/crates/agent-adapt-core/src/discover.rsvalidate_name cap 63 → 64; message text; a boundary test
solutions/determined/experiences/agent-pants/app/utils/skillSpec.tsShared name/description/compatibility/metadata validator mirroring the spec
solutions/determined/experiences/agent-pants/app/utils/skillSpec.test.tsTable test over the spec’s invalid examples plus boundary cases
solutions/determined/experiences/agent-pants/app/components/ApNewComponentWizard.vueLive slug echo and inline refusal on the name field
solutions/determined/experiences/agent-pants/app/components/ApRenameDialog.vueLive slug echo and inline refusal on newName
solutions/determined/experiences/agent-pants/app/components/SkillFieldsForm.vueDescription character counter and 1024 cap
  • 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 for ApRenameDialog.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_name and agent-adapt::naming::SKILL_NAME_MAX_LEN both cap at 64, asserted by a shared-limit test in each crate.
  • AC-4: skillSpec.test.ts passes against every invalid example in the spec’s name grammar (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:check passes.
  • none

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.


← Back to Tasks