| name | content-filename-from-title |
| description | Turns a prose title into a short, single-word, URL-friendly filename for published content (docs, tour parts, blog slugs, guide pages). Use when adding a new entry to a manifest that exposes public filenames (e.g. tour.json parts, docs/*.md for GH Pages), when renaming an existing one, or when a user asks "what should I name this file?" |
content-filename-from-title
Produce a single-word, lowercase, ASCII-only filename (no extension,
no hyphens, no digits) that best represents the content of a titled
page. The filename goes into a config manifest — `tour.json`
part entries, `docs/` frontmatter, or similar — where it becomes the
public URL segment for that page.
## Why this skill exists
Public URLs age badly when filenames carry implementation detail
(walkthrough-part-1.html), numbering (part-3-thing.html), or
cluttering punctuation (url-%E2%86%94-purl-conversion.html). A
title-word filename (anatomy.html, parsing.html, conversion.html)
is short, speakable on a call, typeable, and doesn't need to change
when the surrounding ordering does.
Claude must apply the same reasoning every time, or the fleet of
filenames will drift stylistically across contributors and across
sessions. This skill captures the reasoning as a deterministic
procedure so the output is reproducible.
Where it fits in the repo
tour.json — the parts[].filename field is the URL segment
the page is published under at socketdev.github.io/socket-packageurl-js/<filename>.html.
docs/*.md — the file stem becomes the URL segment when docs are
stitched into the GH Pages flow (see docs/pages-design-system.md
for the surrounding design system).
- Any future blog or guide manifest added to this repo.
A build-time validator in scripts/tour.mts enforces the
shape ([a-z]+) and uniqueness; this skill decides the
choice (which word).
## Hard constraints (validator-enforced)
- ASCII lowercase letters only: matches
^[a-z]+$.
- No digits (
part2 — FORBIDDEN)
- No hyphens (
url-conversion — FORBIDDEN)
- No underscores, dots, slashes, or unicode
- Unique across all entries in the manifest. If the word you picked
is already taken, pick another that's still content-bearing.
- Single word. Compound phrases (
buildingandstringifying) are
FORBIDDEN — pick the stronger of the two nouns instead.
Soft constraints (style)
- Typeable. A user on a call should be able to say "go to the
anatomy page" and the listener can type it correctly without
spelling.
- Stable. The word should still make sense if the surrounding
ordering changes.
part-one is unstable (it renames when content
is reordered); anatomy is stable.
- Content-bearing, not generic.
page, doc, content, item
are FORBIDDEN. Pick a word that would still be meaningful if you
only saw it in a URL with no context.
## Decision procedure
Apply these rules in order. Stop at the first rule that produces a
clean single word.
Step 1 — Inventory the nouns in the title
Write out every noun and nominalized action (gerund, -ion, -ance).
Discard every filler word (articles, prepositions, conjunctions, "of",
"and", "&"). Discard every word that appears in 2+ other titles of the
same manifest (those are qualifiers, not distinguishers).
Why: a filename needs to distinguish this page from its
siblings. A word that isn't unique within the set can never be
load-bearing.
Step 2 — Among remaining candidates, pick the distinguishing noun
If one noun is unique to this title and the others are not, that noun
wins.
Example: "URL ↔ PURL Conversion" has three nouns (URL,
PURL, Conversion). URL and PURL appear in multiple titles;
Conversion is unique to this one. → conversion.
Step 3 — If several nouns are candidates, pick the superset
If the title lists multiple concepts that are facets of one bigger
concept, pick the bigger one.
Example: "Validation, Errors & Results" — errors and
Result<T,E> are outputs of validation. → validation.
Step 4 — If the title is "verb on a subject", pick the verb's nominal form
Gerund (-ing) if the activity itself is the topic; -ion / -ance
if the state or result is the topic.
Example: "Parsing & Normalization" — normalization is a
substep of parsing. The activity is the topic. → parsing.
Step 5 — If the title is a plain subject noun, use it directly
If the title is already a single content noun (Ecosystems), that's
the filename. Just lowercase it.
Step 6 — Check hard constraints, then pick an alternative if needed
Now validate the chosen word against the hard constraints:
- Does it match
^[a-z]+$? If not, reshape: URL ↔ PURL → consider
nominals like conversion, not urltopurl.
- Is it unique across the manifest? If not, go back to Step 2 and
pick the next-best candidate.
- Is it content-bearing? If it's generic (
items, details), go
back to Step 3 — you probably picked too abstract a word.
Step 7 — Sanity check
Read your picks as a list. Does it feel like a coherent table of
contents? If one word feels off-tempo (too long, too clinical, too
cute), adjust. Internal consistency matters — don't mix
gerunds + nouns + adjectives.
## Worked examples — the 8 tour parts
These are the filenames currently in tour.json at the time
this skill was written. Each shows the rule that produced the choice.
Anatomy of a PURL
anatomy
Nouns: `Anatomy`, `PURL`. `PURL` appears in 3 other titles (parts 2, 5),
so it's a qualifier, not a distinguisher. `Anatomy` is unique. → `anatomy`.
Rule applied: Step 2 (distinguishing noun).
Building & Stringifying PURLs
building
Nouns / gerunds: `Building`, `Stringifying`, `PURLs`. `PURLs` is a
qualifier. Stringifying is a substep of building (serialize is the
last step of building). → `building`.
Rule applied: Step 3 (superset) + Step 4 (gerund).
Parsing & Normalization
parsing
Nouns: `Parsing`, `Normalization`. Normalization is a substep of
parsing. The activity is the topic. → `parsing`.
Rule applied: Step 4 (gerund form).
Validation, Errors & Results
validation
Nouns: `Validation`, `Errors`, `Results`. Errors and Result are
the outputs/facets of validation. → `validation`.
Rule applied: Step 3 (superset).
URL ↔ PURL Conversion
conversion
Nouns: `URL`, `PURL`, `Conversion`. `URL` and `PURL` are the domain
(appears in multiple titles). `Conversion` is unique.
→ `conversion`. Rule applied: Step 2 (distinguishing noun).
Ecosystems
ecosystems
Title is already a single content noun. Lowercase it.
Rule applied: Step 5 (plain subject noun).
Comparison, Matching & Existence
comparison
Nouns: `Comparison`, `Matching`, `Existence`. Matching is a flavor of
comparison (wildcard comparison). Existence is adjacent but weaker.
→ `comparison`. Rule applied: Step 3 (superset).
Security Primitives & VERS
security
Nouns: `Security`, `Primitives`, `VERS`. In this curriculum VERS is
scoped under security (injection + freeze + VERS-as-safety-boundary).
→ `security`. Rule applied: Step 3 (superset).
Counter-examples — choices the procedure rejects
Anatomy of a PURL
purl
`PURL` appears in multiple titles → fails Step 1 (not
distinguishing). Also fails uniqueness against any other part that
might want `purl`.
Building & Stringifying PURLs
buildingandstringifying
Compound phrase — violates the "single word" hard constraint. The
procedure always picks one over merging.
URL ↔ PURL Conversion
url-to-purl
Contains a hyphen → fails the `[a-z]+` hard constraint. The validator
would reject this at build time; the skill catches it earlier at
Step 6.
Ecosystems
page6
Numeric, generic, unstable to reordering, not content-bearing. Fails
hard constraints (digits) and soft constraints (stability,
content-bearing).
## Checklist before committing a filename
Copy this into your working notes when adding/renaming a manifest
entry:
Filename choice: _______________
- [ ] Matches ^[a-z]+$ (lowercase ASCII letters only)
- [ ] Unique across every other entry in the manifest
- [ ] Content-bearing (not 'page', 'item', 'content', etc.)
- [ ] Stable under reordering (no 'part1', 'first', etc.)
- [ ] Typeable from hearing it spoken
- [ ] Feels consistent with neighbor filenames' style (all gerunds?
all plain nouns? all -ion forms? one style across the set)
If any checkbox fails, return to the decision procedure and pick
again.
## When NOT to use this skill
- The filename is internal (e.g. a build artifact under
dist/,
an intermediate JSON in .cache/). Internal paths don't need to be
pretty — use whatever the code naturally emits.
- The filename is code-shaped, not content-shaped. TypeScript
source files follow the convention of the ecosystem (kebab-case,
matching export names). This skill is for content filenames only.
- The manifest exposes a hash or date-based identifier (e.g.
a release slug, a git-sha-addressable blob). Use the hash; it's
already optimal.
- [reference.md](./reference.md) — extended reference: edge cases,
manifest types beyond `tour.json`, acronym / proper-noun handling,
decision history for the 8 current filenames, rejected candidates,
regex/validator quick-checks.
- `CLAUDE.md` § ERROR MESSAGES — the error-shape the filename
validator uses when it rejects a bad filename.
- `docs/pages-design-system.md` — the surrounding design system for
pages that use these filenames.
- `scripts/tour.mts` → `validatePartFilenames()` — the
validator implementation that enforces the hard constraints.
- `tour.json` — the current live manifest applying this skill.