← Files AkinatorARCHIVED FILE
rules/08-skills-dir-holds-only-skill-directories.md
3.27 KB · Oct 3, 2026 · 06:33 UTC
# Rule 08 - `skills/` holds only skill directories
## Purpose
Both plugin platforms import skills by scanning `skills/` for **subdirectories
containing `SKILL.md`**. A loose file directly under `skills/` is not imported -
and Codex plugin validation rejects the plugin outright with:
> Files directly under `skills/` are not imported as skills. Move this file into
> a skill directory containing `SKILL.md`, or remove it.
The trap is that the loose file is usually a **README index**, which is the right
instinct in a normal repository and the wrong one in a plugin. It looks correct,
it reads correctly, it is linked from the routers - and it silently makes the
package invalid.
Akinator shipped exactly this defect in its first build - a good index, in a
place that made the plugin fail validation:
```
skills/
README.md <- linked from every router, and not imported
akinator/
SKILL.md
```
## Applies to
- **In scope:** the `skills/` directory of this plugin, and of any plugin
Akinator generates or onboards.
- **Out of scope:** a target repository's own `skills/` directory when that repo
is **not** a plugin. There, a README index inside `skills/` is perfectly good,
and `templates/router.md` still recommends it. The constraint is about plugin
packaging, not about knowledge layout.
## Mandatory rules
1. Every entry directly under `skills/` is a directory.
2. Every such directory contains a `SKILL.md`.
3. The skills index for a plugin lives outside `skills/` - in this repository it
is `docs/skills.md` - and the routers link to it there.
## Prohibited patterns
```
skills/
README.md <- not imported; fails Codex validation
index.md <- same
.DS_Store <- same
akinator/
SKILL.md
```
## Correct pattern
```
skills/
akinator/
SKILL.md
akinator-intake/
SKILL.md
docs/
skills.md <- the index lives here, linked from every router
```
## Enforcement
- Mechanism: `tests/test_plugin_structure.py` - `test_skills_dir_holds_only_skill_directories`
asserts nothing but directories sit under `skills/`, and that each one contains
a `SKILL.md`.
- Type: unit test, run with the suite and in CI.
- How it fails: the test names the offending path and points here.
- Last observed passing: 2026-08-26
**Never a git hook** - see `rules/05-no-git-hook-complication.md`.
## Exceptions
None for a plugin. If a file feels like it belongs under `skills/`, it belongs in
one of two places instead:
- Index or narrative about the skills → `docs/skills.md`.
- A supporting file for one skill → inside that skill's own directory, where
both platforms support `scripts/`, `references/` and `examples/` subdirectories.
## Related
- Rules: `rules/02-skills-carry-all-six-parts.md`
- Docs: `docs/skills.md` - where the index moved to
- Docs: `docs/compatibility.md` - the packaging contracts
- Memory: `memory/2026-08-26-codex-plugin-validation-surprises.md`
## Definition of done
- [x] The constraint is stated as a testable proposition.
- [x] The enforcement mechanism exists in the tree and is named by path.
- [x] The mechanism is not a git hook.
- [x] Prohibited and correct patterns are shown.
- [x] The absence of an exception path is deliberate, with the alternatives named.
- [x] The rule is indexed and reflected in every router.
SHA-256: 3f9b912cc2129f4b19a03a962fbc8d219a43f0925f1125e77bb72b7785992b41