- name
- card
- description
- Portable tokens of capability, identity, and access
- allowed-tools
- ["read_file","write_file","list_dir"]
- tier
- 1
- protocol
- TRADING-CARD
- related
- ["skill","prototype","room","character","party","soul-chat","adventure","multi-presence","advertisement","return-stack"]
- tags
- ["moollm","gamification","capabilities","portable","actor"]
- templates
- [{"file":"CARD.yml.tmpl","purpose":"Individual card template"},{"file":"COLLECTION.yml.tmpl","purpose":"Card collection template"}]
# Card
> **Portable tokens of capability, identity, and access.**
Cards are templates. Put them "in play" in a [room](../room/) to activate them.
> [!TIP]
> **Hero-stories.** Actors. Safe pointers to wisdom. No risks of impersonation, just tribute, storytelling, skill sharing and composing.
---
## The Card Pun Stack โ What A CARD Is
"Card" elegantly puns across a stack of well-proven computing concepts. MOOLLM's CARD sits at the intersection of all of them, and borrows from each. Take the richness as intentional:
| Lineage | What it contributes | How it shows up in `CARD.yml` |
|---|---|---|
| ๐ด **HyperCard** (Bill Atkinson, 1987) | A card as a **self-contained navigable unit** with fields, buttons, scripts โ a little interactive object you can page through, link to, and stack. "Everything is a card." | `card:` identity, `navigation:`, `advertisements:` that surface actions the way HyperCard buttons did |
| ๐พ **Type Library / IDL / ActiveX / OLE Control** (Microsoft, 1990s) | **Dispatch metadata** describing an object's interface: its methods, properties, events, IDs. Binary in COM; human-readable YAML for us. | `methods:`, `state:`, `k_lines:` (our stand-in for UUIDs), `inherits:` (analog to COM aggregation) |
| ๐ญ **Actor** (Hewitt 1973; Agha 1986) | A **message-receiving autonomous entity** with its own state, responding to messages by sending messages or changing state. Concurrency is inherent. | The whole card is an actor signature; advertisements describe the messages this actor handles |
| ๐งต **Thread / Process** | A **unit of control** with its own identity, lifecycle, and dispatchable surface. | Cards are dispatchable in parallel; `state:` is the actor-thread's local memory |
| ๐ฌ **Message Dispatching Surface** (Smalltalk/Self/Objective-C) | The OO insight: methods aren't called, **messages are sent**, and the receiver decides what to do. Late binding, polymorphism, duck typing. | `methods:` โ functions; they're the messages this card responds to. DOP delegation composes dispatch across parent cards. |
| ๐ **Trading / Playing Card** | **Portable token of identity and capability** โ you collect them, play them, trade them. Front = identity/rarity; back = mechanical rules. | `rarity:`, `tier:`, `emoji:`, `tagline:`, the whole collectible ethos (hero-stories, soul-chat) |
| ๐ฏ **Business Card / Index Card** | **Sniffable surface.** Hand it to someone, they know who you are, how to reach you, what you do. | `tagline:`, `description:`, the entire "sniffable interface" framing |
A CARD is **all of these at once** โ that's the design, not accident. When you encounter a `CARD.yml`, you're looking at:
- an **interface definition** (like IDL) describing a dispatchable surface,
- a **HyperCard** you can navigate to, activate, and page through,
- an **actor signature** describing a message-receiving entity with local state,
- a **type library entry** in a distributed, human-readable, zero-ceremony registry (the filesystem itself),
- a **collectible token** with rarity, identity, and portability, and
- a **business card** you can hand to a reader (human or LLM) to say "this is what I am and what I do."
The richness is load-bearing. Every time you write `methods:`, `advertisements:`, `k_lines:`, or `inherits:`, you're simultaneously:
- declaring an interface (IDL-style),
- describing an actor's message-handling surface (Hewitt-style),
- exposing navigation/activation triggers (HyperCard-style),
- publishing metadata that tooling and LLMs can sniff without execution (TypeLib-style),
- presenting a portable token of identity (trading-card-style).
This is why a CARD-only directory (no `SKILL.md`) is already a first-class dispatchable object. The CARD isn't documentation for the skill โ it **is** the skill's interface, actor, card, type library, and business card rolled into one YAML file.
> ๐ก *The other meta-skills (`skill`, `prototype`, `schema`, `file-system-object`) each name one aspect of the MOOLLM object system. `card` names the interface-and-actor surface itself โ the CARD is the handle by which everything else is invoked.*
---
## ๐ Index
**Architecture**
- [The Card Pun Stack โ What A CARD Is](#the-card-pun-stack--what-a-card-is)
- [What a CARD carries](#what-a-card-carries) โ the standard keys, defaults, copy-down, projection
- [Card Architecture](#card-architecture) โ The most important section!
- [Recommended Section Order](#recommended-section-order)
- [What Goes Where](#what-goes-where)
- [Advertisements Before Methods](#advertisements-before-methods)
- [Method Placement Rules](#method-placement-rules)
**Card Types**
- [What's a Card?](#whats-a-card)
- [Sidecar Pattern](#sidecar-cardyml-pattern)
- [Card Types](#card-types)
**Mechanics**
- [Activation Records](#activation-records)
- [Card State](#card-state)
- [Collections](#collections)
---
## What a CARD carries
`CARD.yml` is the one file a model reads to learn what an object does
([constitution ยง15](../../kernel/constitution-core.md#15-the-semantic-image-pyramid-concentrated-not-dry-universal)).
The standard is the `schema:` section of [CARD.yml](CARD.yml): every key's shape, default,
meaning and aliases, in the format of
[SCHEMA.md ยง Schema files](../../designs/object-system/SCHEMA.md#schema-files).
### One file, concentrated, not DRY
A card holds the object's advertisements, methods, k-lines, state, Dublin Core, card face,
relations and its own YAML Jazz, all in one file. There is no `ADVERTISEMENTS.yml`,
`METHODS.yml` or `K-LINES.yml` beside it. A directory with several interfaces (`ROOM.yml` and
`CHARACTER.yml`) still has one CARD, and every interface feeds it.
Repeating a key that `SKILL.md`, an interface file or the prototype file already has is the
point, not a defect. Never remove something from a card because a larger file says it; ask
whether it is among the most important things at card size. Lint keeps the copies in
agreement; the fix for a disagreement is updating the copy.
### The keys
| Group | Keys | Defaults when omitted |
|---|---|---|
| Identity, Dublin Core | `id`, `name`, `type`, `tags`, `description`, `credits`, `license` | `id` the directory name; `name` the id in title case; `type` `skill` in `skills/`, else the implied skill of the first interface file; `license` the repo's |
| Card face | `emoji`, `tier`, `rarity`, `tagline`, `t_shirt`, `tools {required, optional}`, `files` | `tier: 2`; `rarity: common`; `tagline` the first sentence of description; `files` the directory listing |
| Behavior | `advertisements` (map of [advertisement](../advertisement/)), `methods` (map of method, [OBJECT.yml](../object/OBJECT.yml)) | empty |
| Activation | `k_lines` | the id in UPPER-DASHES |
| State | `state` | empty |
| Copy-down | `interfaces` | the directory's interface files and the skill's prototype file, nothing copied |
| Relations | `inherits`, `inherited_by`, `related` (`{id, role, when, why}`), `see_also`, `lineage` | `see_also` is SKILL.md and README.md when present |
| Common jazz | `schema`, `examples`, `principles`, `anti_patterns` | `examples` the `examples/` directory |
`type:` is one id; other kinds go in `tags:`. `k_lines:` is a flat list of K-LINE words, run by
the same matcher as an advertisement's `trigger:` words. Situations that call for the card
are advertisement `score_if:` lines, not a separate `invoke_when:` list. `status:` and
`version:` are retired (git knows), and so are `card:` and `skill:` envelopes: cards are
flat.
Readers accept the older spellings listed as `aliases:` in the schema (`one_liner`,
`documentation`, `related_skills`, `activates`, `invoke_when`, `allowed_tools`, ...); writers
emit only the canonical key. Lint reports an alias as a finding.
### Copy-down from interfaces
Interface files stay canonical for instances: `skills/room/ROOM.yml` is what every room
inherits. The card copies down their most important slots and methods so the card level of
the pyramid represents them. A model reading the room card learns that every room answers
LOOK.
```yaml
interfaces:
ROOM.yml: # path relative to the card
role: prototype # prototype: what every instance inherits; interface: one of this directory's
slots: { exits: "map DIRECTION โ path", lighting: "0 pitch black .. 10 full sun; default 6" }
methods: [LOOK, ENTER, EXIT, CONTENTS, ADVERTISE]
methods:
LOOK: { signature: "LOOK (AT [thing])", from: ROOM.yml } # the copy, in the one methods map
```
Copied methods go into `methods:` with `from:`, so everything callable is in one map.
Which UPPERCASE files count as interfaces is decided per file; data files such as
`LAYOUTS.yml` belong in `files:`.
### Defaults keep cards short
Every key documents its default, and the default is the sensible case
([constitution ยง16](../../kernel/constitution-core.md#16-advertisements-push-into-the-auction-compile-graduate-universal)).
An omitted key means its default, so a card states only what is unusual about its object:
no `tier:` means standard, no `score_if:` means always, no `method:` on an advertisement
means the method of the same name, or "load this object and act". A value equal to its
default is removable.
### Projection
Orchestrators filter cards they can't read whole: the advertisements whose triggers match,
the methods a role may invoke, the cards a k-line activation or heat map has warmed. They
rely on these keys and nothing else:
`id`, `name`, `type`, `tags`, `tier`, `k_lines`, `advertisements[*].score`,
`advertisements[*].trigger`, `advertisements[*].score_if`, `methods[*].invoked_by`
That works only on standard shapes: maps keyed by name, numeric scores, lists where lists are
expected, one type id. A card with irregular shapes gets read whole or skipped.
### YAML Jazz rides on structure
Comments carry meaning, and object-specific keys (`types:`, `world_generation:`,
`self_correction:`) stay. Jazz goes on top of the standard keys and never stands in for one.
Where a jazz key means the same as a standard key, rename it to the standard one; a jazz key
that collides with an alias gets renamed too.
---
## Card Architecture
> **KEY INSIGHT: Cards are ACTIVATION TRIGGERS, not activation handlers.**
This is the most important concept in MOOLLM card design.
### The Fundamental Distinction
| | CARD.yml | SKILL.md |
|--|----------|----------|
| **Purpose** | Decide IF this skill applies | Explain HOW to execute |
| **Role** | Activation trigger | Activation handler |
| **Content** | Sniffable interface | Full documentation |
| **Size** | ~150-200 lines | As needed |
| **LLM reads** | First, to decide | Second, if activated |
The CARD asks: "Does this situation call for me?"
The SKILL.md answers: "Here's how to actually do it."
### Recommended Section Order
Order sections for optimal LLM scanning. Flat keys, no `card:` envelope; the full template is
[CARD.yml.tmpl](CARD.yml.tmpl).
```yaml
# 1. Identity and card face (who am I?)
id: my-skill
name: "My Skill"
type: skill
emoji: ๐ฏ
tagline: "One-line pitch"
description: "Brief paragraph"
# 2. Files index (what else should LLM read?)
files:
docs: [SKILL.md]
examples: [examples/]
# 3. K-lines (what words and concepts wake this card?)
k_lines: [MY-SKILL, RELATED-CONCEPT]
# 4. ADVERTISEMENTS โ PRIMARY! Put BEFORE methods!
advertisements:
DO-THE-THING:
score: 90
score_if: "situation that calls for this skill"
# 5. Methods (signatures only, implementations in SKILL.md)
methods:
DO-THING: { signature: "DO-THING [arg]" }
# 6. Copy-down from interface files, then state
interfaces:
MY-SKILL.yml: { role: prototype, methods: [DO-THING] }
state:
field1: 0
# 7. Relations: inherits, related, see_also, lineage
see_also:
- SKILL.md: ["ยง Detailed section"]
```
### Why Advertisements Before Methods?
Advertisements are the **PRIMARY activation signal**:
1. LLM scans top-down looking for "does this apply?"
2. Ads answer that question directly
3. Methods are secondary โ only relevant AFTER activation
4. Front-loading ads speeds up skill selection
```yaml
# GOOD โ Ads first
advertisements:
PET-THE-CAT:
score: 80
score_if: "cat is present"
methods:
PAT: { signature: "PAT [cat]" }
# BAD โ Methods first (LLM has to read past them)
methods:
PAT: { ... long list ... }
SCRITCH: { ... }
# ... many more ...
advertisements: # Too late! LLM already moved on
```
### What Goes Where
#### In CARD.yml (sniffable interface)
```yaml
# YES โ Include these
- Brief description + tagline
- Files index (for one-shot activation)
- K-lines (activation vectors)
- Advertisements (PRIMARY!)
- Method SIGNATURES (one-liners)
- The most important slots and methods of the interface files (copy-down)
- Brief state (field names and defaults)
- see_also pointers
# NO โ Move these to SKILL.md
- Implementation details
- Detailed protocols with sequences
- Dispatch tables
- Dialogue examples
- Full state schemas with types
- Worked examples
```
#### In SKILL.md (full documentation)
```markdown
- ## ๐ Index (link to each section)
- Detailed method implementations
- Protocols with step sequences
- Dispatch tables (actor_verb_target)
- State schemas with types and defaults
- Integration points with other skills
- Mechanics explanations
```
#### In examples/ (worked examples)
```yaml
# Separate files with descriptive names
examples/
ceremony-invocation.yml # Good!
buff-chain-trigger.yml # Good!
example1.yml # Bad โ not descriptive
```
### Method Placement Rules
| Situation | Place In | Example |
|-----------|----------|---------|
| Short signature | CARD methods | `PAT: { signature: "PAT [cat]" }` |
View on GitHub