user-entity-does-not-own-token accepted "either can be right" without naming what makes an entity the right home. The documentation now requires an already-established entity that genuinely owns the authentication state, so the case can pass while the docs regress to "user entity exists, therefore token entity". Ask for the ownership condition, and say that the entity existing or profile data being reused is not enough. SKILL.md was at 498 of the 500-line limit, which leaves no room for the next sentence anyone writes. Three passages give back seven lines without losing a rule: The widgets callout closed with three lines saying the layer is not being removed and existing projects may keep it. layer-structure.md:155 says the same and carries the slice rules and an example with it, so one line and a pointer do here. The paragraph above it listed where each kind of UI block goes in full sentences; the same routing reads as one. Rule 4-2 explained why a single segment index can hurt: bundle size, tree-shaking, dev server startup. The rule is which index to give a folder and where the boundary then sits, and layer-structure.md is already cited for the shape. SKILL.md is now 491 lines.
Skill evaluation cases
cases.json records the placement answers this skill is supposed to produce.
The validator keeps the file honest; a person or a harness grades the answers.
Why this exists
The other checks in this repository verify that the documents are well formed: the body stays under the line limit, every reference path resolves, no reference is orphaned. None of them verify the thing the skill is for, which is whether an agent reading it places code correctly.
That gap is not theoretical. Several rules in this skill were changed because two passages decided the same question on different grounds, and nothing in CI noticed. A case list is the cheapest way to catch the next one.
Running the cases
There is no semantic grader in CI, because comparing an answer to expect
needs a model or a person. Run them by hand, or wire cases.json into
whatever harness you already use.
- Start an agent session with only this skill installed.
- Send one
promptverbatim. Do not add context; the point is to see what the skill alone produces. - Compare the answer to
expect. Judge the placement, not the wording. - On a mismatch, read the file named in
sourceand check whether the rule is absent, ambiguous, contradicted elsewhere, or whether the case itself no longer describes the behavior the skill intends. Fix whichever one is wrong. Never editexpectjust to match what the model said.
Start a fresh session per case. A previous answer in the same conversation will steer the next one.
Adding a case
Add an object to cases with all six fields:
| Field | Meaning |
|---|---|
id |
kebab-case, unique |
prompt |
what the user types, verbatim |
expect |
the placement, plus what must not happen if that matters |
why |
what regression this case guards against |
source |
repo-relative path to the primary file that decides it |
rule |
the passage that decides it, as ;-separated fragments; name a passage from another file too when the decision leans on one |
source names one file, the one to open first on a mismatch, even where
the decision is settled by more than one passage. It must point at a file
that exists, and node .github/scripts/validate-skills.mjs enforces that,
so no case can cite a file that has been deleted.
The validator also resolves every fragment of rule against the skill's
documents, so a renamed heading or renumbered section fails the build
instead of leaving a case pointing at nothing. A fragment resolves against
source unless it names another file (SKILL.md, auth-and-api.md), and
it must contain at least one of:
- a numbered reference such as
Section 2, Step 3,Rule 4-2,Strategy D,Snapshot 1, orQuestion 2 - a phrase in single or double quotes that appears verbatim in the file
- the text of a heading or bold label in the file, such as
Decision tree
Section N and Rule N-M always mean a numbered heading in SKILL.md.
Free prose after a numbered reference is allowed and not checked, so
Section 6 anti-pattern on the user entity is fine.
Write a case when it guards a mistake that is actually likely: a rule two readings could defend, a regression that has already happened once, or a convention from outside FSD that an agent will reach for anyway. Several cases here are the third kind, where the rule is plain and the pull toward breaking it is what needs holding down.
Keep a case on one architectural decision where you can. A prompt that checks several independent placements fails as one result, and then the failure does not say which rule broke. Split it instead.
A case that restates an obvious rule without guarding a realistic mistake costs a run and catches nothing.