Marfa is extensible. Apps register their own types, edges, and extension namespaces. These conventions are how the core set looks, and following them keeps custom work readable alongside it. Some are advisory style; others are server-enforced at registration. Each rule below is marked.Documentation Index
Fetch the complete documentation index at: https://docs.myme.so/llms.txt
Use this file to discover all available pages before exploring further.
Edges
Name edges so that “source [edge] target” reads as an English sentence. (Style.)| Edge | Reads as |
|---|---|
parent-of | X is parent of Y |
authored-by | X was authored by Y |
in-thread | X is in thread Y |
references | X references Y |
attached-to | X is attached to Y |
derived-from | X is derived from Y |
references, supersedes) take a direct object and don’t need a preposition. Everything else does. Dropping to bare nouns (parent, thread) loses direction — “X parent Y” is ambiguous — so keep the preposition.
Use kebab-case for multi-word names. Dot-namespace custom edges under your app or publisher: app.shops-for, readwise.highlights.
Cardinality
Pick the tightest one that fits. Ask: can the source really have many of these? Can the target? Tighter cardinalities are enforced at edge-creation time and surface data-model mistakes early.Cascade
Default toorphan. Use cascade only when the target genuinely cannot exist without the source — the only core edge that cascades is parent-of, because a child has no meaning without its parent. For almost everything else, deleting one endpoint should leave the other in place.
See Edges for the full core set and their declared constraints.
Types
Use the right namespace. (Server-enforced.) Custom types live under one of:app.<app-name>.<type>— types published by a registered app.user.<type>— personal types in your space.<publisher>.<type>— types published under a publisher handle.
core, system, app, user, marfa — cannot be claimed as publisher handles. core.* and system.* are platform-only at registration. See Namespaces for the full grammar.
Sibling is the default; inherit only when it earns its place. (Style, with server-checked compatible-with.) A custom type is usually its own shape, optionally declaring compatible-with: core.<type>. Inherit only when every ancestor field is semantically required for your type. Children cannot redefine ancestor fields — a bad inheritance choice is hard to recover from. See Types → Sibling vs child.
Singular nouns. (Style.) note, not notes. One item, one name.
Subtypes earn their place. (Style.) A subtype is justified when its instances share a convergent shape the parent doesn’t carry, consumer apps can query or render it differently, and the differentiating fields aren’t already on the parent. Otherwise prefer a sibling. See Authoring types for the full rubric.
See Types for the registration flow and inheritance rules.
Property names
snake_case (Style.) For type fields, edge properties, and extension keys. That matches the core set (due_at, starts_at, display_hints, enum_values). Consistent casing makes filters, display hints, and SDK codegen predictable across custom and core types.
Don’t prefix properties with the container they live in. A field on the in-thread edge is position, not edge_position. Context already tells the reader where it lives.
Markdown body
If a type declares a markdown body field, the rendered profile is CommonMark + GFM (Style.) — no wikilinks, no Obsidian-style extensions, no custom syntax. Every client renders this profile, and anything outside it won’t survive the round-trip. This is the reasoncore.note.body and similar fields stay portable across clients. Custom types with markdown bodies should stick to the same profile.
Extensions
Namespace extensions under your app or publisher:<your-app>.* or <your-handle>.*. (Style.) Put per-app annotations — sync state, reading progress, per-app metadata — in extensions rather than inflating a custom type with fields only one app uses.
Sync cursors, agent-local cache state, and other per-machine bookkeeping are not extensions. They live on the agent’s own disk and don’t attach to any item.
See Extensions for the namespace grammar and permission model.
Handles
Publishers identify themselves with a handle.- Format. (Server-enforced.) Lowercase alphanumeric and hyphens. No leading or trailing hyphens. No consecutive hyphens. Length 3–32 characters.
- Reserved. (Server-enforced.) The reserved roots
core,system,app,user, andmarfacannot be claimed. A list of structural words (admin,api,support, etc.) is reserved against squatting.
Scalars
A few cross-cutting conventions for primitive values across the platform:- IDs. UUIDv7. Server-generated.
- Times. ISO 8601 with offset (
2026-04-12T14:30:00Zor with explicit+00:00). - Tags. Lowercase, kebab-case.
- Languages. BCP 47 codes (
en,en-GB). - MIME types. Standard IANA tokens.
- Type identifiers. Dotted, lowercase, snake_case segments. No forward slashes.