Skip to main content

file-system-object

The grammar rules that make MOOLLM's file system object-oriented. Plural directory names declare element type; UPPERCASE marker files declare interface exports (COM-style, minus the UUIDs); directories are implementation classes exporting every interface whose marker file sits at their root.

Source facts

Repository
SimHacker/moollm
Last source activity
September 5, 2026 at 23:18
Detected SKILL.md language
English
Stars
60
Forks
5

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
4 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
file-system-object
description
The grammar rules that make MOOLLM's file system object-oriented. Plural directory names declare element type; UPPERCASE marker files declare interface exports (COM-style, minus the UUIDs); directories are implementation classes exporting every interface whose marker file sits at their root.
license
MIT
tier
1
allowed-tools
["read_file","write_file"]
related
["skill","prototype","card","schema","self","com-xpcom","yaml-jazz","room"]
tags
["moollm","meta","grammar","object-oriented","com","self","filesystem","directories","markers"]
credits
["Smalltalk (Alan Kay et al., Xerox PARC, 1970s) — classes, messages, image-as-object","Self (Ungar & Smith, 1987) — prototype delegation; objects without classes","NeWS (James Gosling & David S. H. Rosenthal, Sun, 1986) — PostScript window system with prototype delegation in production","TNT: The NeWS Toolkit (Owen Densmore & David S. H. Rosenthal, Sun) — class hierarchy built on NeWS's prototype foundation; the patent and the conceptual ancestor","COM / XPCOM — multiple interfaces per class; QueryInterface","Ted Nelson — intertwingled systems; every node can link anywhere","MOOLLM — the actually-existing MOOLLM file system, already using this grammar before it was named"]
# File System as Object — Directories, Interfaces, and the UPPERCASE Marker Grammar > **"A directory named `<things>/` is saying: the things in here are of the type `<thing>`. A file named `FOO.md` at a directory's root is saying: this directory exports the FOO interface. The directory IS an implementation class; the UPPERCASE marker files ARE its interface declarations; no UUIDs needed because the filename IS the class name."** This skill formalizes a grammar that **already exists throughout MOOLLM**. Every skill you've read — `skill`, `prototype`, `card`, `schema`, `adventure`, `room`, `character`, `incarnation` — uses these rules implicitly. The other meta-skills USE the grammar; this skill NAMES it so newcomers (human or LLM) can read MOOLLM directory trees fluently without pattern-matching each one from scratch. --- ## The Three Rules ### Rule 1: Plural-named directories declare element type A directory named `<things>/` declares "the things in here are of type `<thing>`." ``` skills/ → each child is (presumably) a skill biomes/ → each child is a biome mechanisms/ → each child is a schema mechanism recipes/ → each file is a recipe gotchas/ → each file is a gotcha runbooks/ → each file is a runbook instances/ → each child is an instance stacks/ → each child is a stack protocols/ → each file is a protocol rooms/ → each child is a room characters/ → each child is a character ``` "Presumably" is doing real work here: the plural name is a **declaration of intent**. To confirm a specific child actually IS of that type, look for its **interface marker file** (see Rule 3). Auxiliary content (templates, indexes, READMEs) can also live in a plural container without being instances — their absence of a marker file is the tell. ### Rule 2: Singular-named directories are instances A directory named `<thing>/` (singular, kebab-case or single word) is an **instance**. The directory name is the instance's identifier. ``` skills/skill/ → instance named "skill" (a specific skill, happens to BE the meta-skill about skills) skills/biome/ → instance named "biome" skills/gcs/ → instance named "gcs" mechanisms/json-schema/ → instance named "json-schema" instances/leela-zion2-dev-0/ → instance named "leela-zion2-dev-0" ``` This reads as: `<plural-container>/<instance-id>/`. ### Rule 3: UPPERCASE marker files declare interface exports A file named `FOO.md` or `FOO.yml` (UPPERCASE filename) at a directory's root declares that the directory **EXPORTS the FOO interface**. ``` skills/gcs/ ├── SKILL.md ← "I export the SKILL interface" ├── CARD.yml ← "I export the CARD interface" ├── GLANCE.yml ← "I export the GLANCE interface" ├── README.md ← "I export the README interface (human landing)" ├── recipes/ ← plural: "I contain recipes" ├── gotchas/ ← plural: "I contain gotchas" └── ... ``` The UPPERCASE convention visually distinguishes **interface declarations** from ordinary content. The presence of the file IS the declaration — no separate registry required. **One directory exports many interfaces.** Just like a COM class implements many interfaces, a MOOLLM skill directory typically exports SKILL + CARD + GLANCE + README + sometimes CHARACTER + EXPORTS + PROTOTYPES — all simultaneously, via multiple marker files. --- ## The COM Analogy This is Henry's framing, which anchors the whole grammar: | COM concept | File-system-object equivalent | |---|---| | Implementation class (C++ / IDL class) | Directory — the `<thing>/` singular name | | Interface declaration (IDL `interface IFoo`) | UPPERCASE marker file — `FOO.md` or `FOO.yml` | | Interface UUID (`IID_IFoo = {01234567-89ab-...}`) | **Not needed** — the filename IS the identifier | | Multiple interfaces per class | Multiple UPPERCASE marker files per directory | | `QueryInterface(IID_IFoo, &ptr)` | `cat <dir>/FOO.md` (or "does this dir export FOO?" = `test -e <dir>/FOO.md`) | | Class factory (`CoCreateInstance`) | Prototype instantiation (see `skill-instantiation-protocol.md`, `delegation-object-protocol.md`) | | Aggregation (one class delegating to another) | DOP prototype chain via `inherits:` or `PROTOTYPES.yml` | | TypeLib registry | `schemapedia/registry.yml` (for schema mechanisms); `skills/biome/biomes/registry.yml` (for biomes) | COM's big wins were: (a) multiple interfaces per implementation, (b) language-neutral contracts, (c) strong versioning via UUIDs. MOOLLM keeps (a) and (b), swaps (c) for **readable UPPERCASE names** because we want humans and LLMs to read the tree, not a binary-stamped registry. COM's big losses were: opaque UUIDs, fiddly registration, reliance on a global registry, Windows-centric tooling. MOOLLM avoids all four by putting the declarations in the filesystem itself. --- ## Why UPPERCASE The UPPERCASE-filename convention (`SKILL.md`, `CARD.yml`, `MECHANISM.yml`, `ALERT.yml`, `PROTOTYPES.yml`) does several things at once: 1. **Visual grep.** In any `ls` output, UPPERCASE files leap out. Structural signposts pop; ordinary content recedes. 2. **Class-vs-content distinction.** Lowercase filenames (`camera-configs.json`, `my-recipe.md`) are content; UPPERCASE is meta — "I am telling you what this directory IS." 3. **Namespace cleanliness.** `foo.md` (lowercase) is a note about foo; `FOO.md` (uppercase) is a declaration that this directory implements FOO. They don't collide, and their roles are clear at a glance. 4. **Future-proof tooling.** A validator script can simply glob for `[A-Z]*.{md,yml}` at a directory root to find all exported interfaces. No manifest file, no parsing. 5. **Big-endian naming.** The UPPERCASE prefix groups structural files together alphabetically at the top of `ls` output. **When NOT to use uppercase.** Normal content, per-instance data (`state.yml`, `history.md`), templates (`RUN.yml.tmpl` — the `.tmpl` is the tell that it's a template, not a declaration), ordinary documentation (`troubleshooting.md`). --- ## Serialization — YAML Preferred, JSON Welcome, Comments Encouraged Interface marker files come in three flavors, each picked on purpose: | Extension | Use when | Why | |---|---|---| | `.yml` | The interface is **data-shaped** (fields, structure, lists). Default choice. | Comments are first-class and **encouraged** (see [`yaml-jazz`](../yaml-jazz/)). The same file can carry structure, semantic hints, lineage notes, and authorial voice simultaneously. | | `.md` | The interface is **narrative** (explains, teaches, guides). | Markdown supports prose + structure + code blocks. `SKILL.md`, `README.md` are the canonical narrative interfaces. | | `.json` | **A downstream tool needs it** (jq pipelines, ajv validators, frontend code reading an API) and no human is expected to author it by hand. | Universal tool support. Smaller parser footprint. But: no comments → strips human intent. | **The rule: YAML is preferred, JSON is welcome, comments are encouraged.** ### When to prefer which - **Authoring by hand?** → YAML. Every time. - **Tool reads it, humans rarely?** → JSON is fine. - **Both?** → YAML is canonical; emit JSON on a hook if needed. - **Narrative / teaching / guiding?** → Markdown. ### Why YAML over JSON for MOOLLM interface declarations YAML gives us three-audiences support (humans, LLMs, machines — see the `yaml-jazz` skill): ```yaml # CARD.yml — this is a comment — it carries semantic information for # humans AND LLMs, even though machines technically ignore it. card: id: example tagline: "The tagline is the elevator pitch." # ↑ Next audience note: rule-of-thumb is one sentence, present tense. ``` Strip the comments and you have the same data. Keep them and you have **intent** alongside the data — why the fields are there, what alternatives we considered, which examples are load-bearing. That's the yaml-jazz difference, and it's why every UPPERCASE marker file in MOOLLM defaults to YAML. ### Canonical patterns observed in MOOLLM | Pattern | Example | Notes | |---|---|---| | Data-shaped interface | `CARD.yml`, `GLANCE.yml`, `MECHANISM.yml`, `ALERT.yml`, `CHARACTER.yml`, `PROTOTYPES.yml`, `EXPORTS.yml` | YAML. Comments throughout. | | Narrative interface | `SKILL.md`, `README.md`, `CHANGELOG.md` | Markdown with YAML frontmatter. | | Generated-for-tool interface | rare in MOOLLM proper; common in build outputs | `.json` next to `.yml` canonical, regenerated on change. | | Template interfaces | `CARD.yml.tmpl`, `SKILL.md.tmpl` | `.tmpl` suffix signals placeholder content; not a real declaration. | If you're introducing a new UPPERCASE interface type and you have to choose: `FOO.yml` is the default. Reach for `.md` if the content is prose-heavy; reach for `.json` only when a tool demands it. ### The yaml-jazz skill is a hard dependency This skill inherits conceptually from [`yaml-jazz`](../yaml-jazz/): "Semantic YAML — comments as data; three audiences." The two skills together give MOOLLM its **authoring grammar**: - `file-system-object` says: directories are classes, UPPERCASE files are interfaces. - `yaml-jazz` says: inside those interface files, comments are first-class semantic carriers. Together they turn an `ls` + `cat` session into a legitimate class browsing experience. --- ## Nesting — Sub-skills and Categorization Following the grammar, a directory can nest further plurals inside itself: ``` skills/biome/ ← singular (instance of skill type) ├── SKILL.md ← exports SKILL interface ├── CARD.yml ← exports CARD interface ├── biomes/ ← plural: "this skill contains biomes" │ ├── registry.yml ← (not UPPERCASE — data, not interface) │ ├── gateways.yml ← (not UPPERCASE — data, not interface) │ ├── convention.yml ← (not UPPERCASE — data, not interface) │ └── families.yml ← (not UPPERCASE — data, not interface) └── templates/ └── BIOME/ ← the template IS named UPPERCASE because it's a TYPE template ├── SKILL.md.tmpl ├── CARD.yml.tmpl └── ... ``` A skill can also contain sub-skills: ``` skills/parent-skill/ ├── SKILL.md ├── CARD.yml └── skills/ ← plural: sub-skills live here └── child-skill/ ├── SKILL.md └── CARD.yml ``` And so on recursively. The grammar holds at any depth. ### Skills as categories When a skill contains a `skills/` subdirectory, the parent skill plays two roles at once: 1. **It's still a skill itself** (via its own `SKILL.md` / `CARD.yml`). 2. **It's also a CATEGORY** for the sub-skills — the parent directory name is the category name; its child skills belong to that category by virtue of their path. ``` skills/gardening/ ← the gardening skill AND the gardening category ├── SKILL.md ← the parent skill's full protocol ├── CARD.yml └── skills/ ← sub-skills (i.e., members of the gardening category) ├── composting/ │ ├── SKILL.md │ └── CARD.yml ├── pruning/ │ ├── SKILL.md │ └── CARD.yml └── seed-starting/ └── SKILL.md ``` No separate "category" concept is needed — **the parent skill IS the category**. A sub-skill participates in the category simply by living under `skills/<parent>/skills/<child>/`. Cross-category sub-skills (a skill that belongs to two categories) are handled by DOP inheritance, not by duplicating directories: `child-skill` lives in one canonical path, and other categories reference it via `inherits:` chains. **When to nest vs flatten.** Put a skill under a parent when: - It's only meaningful inside the parent's context (e.g., `biome`'s `biomes/` stubs — each stub is only a reference biome for this mother skill). - It's a sub-concern of the parent that isn't reused elsewhere yet. Pull it up to a top-level skill (lift it) when: - It becomes reusable across unrelated contexts. - Other skills start wanting to inherit from it. - Its audience broadens beyond users of the parent skill. This is the same PLAY-LEARN-LIFT arc applied to skill hierarchy: sub-skills start nested (low-cost), get promoted when they earn independence. --- ## Skill Lookup and Inheritance Through Tree Containment When one skill references another — via `inherits:`, `related:`, or a prose mention — the reference can take two forms: | Form | Example | When to use | |---|---|---| | **Bare name** | `inherits: [biome]` | Most authoring. Short, Postel-friendly, resolver-driven. | | **Unambiguous path fragment** | `see: moollm/skills/biome/SKILL.md` | When you need to disambiguate, cross-repo-reference, or help a reader find the exact file. | Both are valid. MOOLLM's resolver is expected to accept either and find the right skill, following Postel's robustness principle: **be liberal in what you accept, conservative in what you emit**. When authoring by hand, reach for the unambiguous form when you easily can; reach for the bare name when the context makes it obvious. ### What counts as a skill — duck typing on marker files A directory participates in the MOOLLM object system to the extent its UPPERCASE marker files say it does. There are **three distinct levels of participation**, and a directory can sit at any of them: | Level | Minimum markers | What works | What doesn't | |---|---|---|---| | 📜 **Full skill** | `SKILL.md` + `CARD.yml` (+ usually `GLANCE.yml`, `README.md`) | Everything: dispatch, narrative, semantic-image-pyramid reading, ambient inheritance when contained | — | | 📇 **Dispatchable object** | **`CARD.yml` alone** | Dispatch: **methods, advertisements, k-lines, state, navigation all work**. `queryInterface(dir, 'card')` returns the sniffable interface. Inheritance declared in CARD.yml's `inherits:` chain resolves normally. | No narrative/protocol doc; no `SKILL.md`-level reading-order entry point (GLANCE → CARD → SKILL → README collapses to GLANCE → CARD) | | 🦆 **Scope-declared** | `skills/<name>/` container (or `biomes/<name>/`, `characters/<name>/`, etc.) declares the TYPE of the directory | Type-level discovery works (enumeration recognizes it as of the plural's type); becomes dispatchable the moment a CARD.yml appears | Without CARD or SKILL, there's nothing to dispatch yet — it's a stub, not an error | **A CARD-only directory is a first-class object.** It isn't a "degraded skill" — it's a **lightweight form** for when narrative isn't warranted. A directory with just `CARD.yml` can still: - Be invoked via its `methods:` block - Advertise capabilities via `advertisements:` - Activate k-lines via `k_lines:` - Declare inheritance via `inherits:` (resolver walks the chain the same way) - Participate in DOP delegation - Be the target of `related:` from other skills ``` skills/my-thing/ ← dispatches just fine └── CARD.yml ← this alone carries methods, ads, k-lines, navigation ← queryInterface(., 'card') → CARD.yml ← queryInterface(., 'skill') → null (no SKILL.md — that's OK) ``` This matters because it removes a friction: you don't need to write a 300-line SKILL.md just to make something dispatchable. Write the CARD when you have methods to declare; write the SKILL when you have a protocol to teach. The two files answer different questions (*"what can this DO?"* vs *"how does this WORK?"*), and not every object needs a teaching narrative. > 🦆 **Quack-quack duck typing** — a directory is an object to the degree its marker files quack. `SKILL.md` is the full orchestra; `CARD.yml` is a solid string quartet; `skills/<dir>/` with no markers is a stage with a name on it. All three are legitimate; each does a different amount of work. Any additional UPPERCASE marker file adds another interface: `CHARACTER.yml` makes it incarnation-ready; `MECHANISM.yml` registers it with schemapedia; `ALERT.yml` makes it a branch-as-object alert. The directory exports all of them simultaneously, in classic COM-style multiple-interface fashion. > 🎴 **The CARD is a rich pun.** `CARD.yml` names a surface that is — *simultaneously* — an interface definition (IDL / OLE Control / ActiveX TypeLib), a **HyperCard** (Atkinson-style navigable unit with fields/buttons/scripts), an **actor** (Hewitt-style message-receiver with local state), a **thread** (a dispatchable unit of control), a **message dispatching surface** (Smalltalk/Self-style), and a **portable token** (trading card + business card). The richness is load-bearing; see [`skills/card/SKILL.md` § "The Card Pun Stack"](../card/SKILL.md#the-card-pun-stack--what-a-card-is) for the full lineage. ### The lookup scope — two searches, one upward walk A bare reference like `inherits: [biome]` is resolved by walking **outward** from the referring skill's location. The walk performs **two independent searches** at every level. Both use the same parent-walking loop; they return different things. ``` referring_skill_dir/ ↑ up one level referring_skill_dir's parent/ ↑ up one level ... ``` At each step, check two things: #### Search 1 — scoped `skills/` directory at this level
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub