| name | typedown-expert |
| description | Expert guidance on writing correct Typedown code, focusing on syntax, best practices, and common pitfalls. |
Typedown Expert
This skill provides expert knowledge for writing Typedown files (.td). Typedown is a Consensus Modeling Language that embeds Pydantic models and Pytest logic into Markdown.
Core Syntax Rules
-
File Structure:
- Typedown files are valid Markdown files.
- They consist of natural language text interleaved with special Code Blocks.
- Crucial: Every
.td file MUST start with a Level 1 Heading (# Title) and a brief textual description. Never start with a code block.
-
Model Blocks (model:<Name>):
- Used to define Pydantic models.
- One Model Per Block: Do NOT define multiple classes in a single block. Each class gets its own
model:ClassName block.
- No Imports in Block: Do NOT import
typing or pydantic inside the block unless it's a specific, non-standard import. The environment pre-loads standard types.
- Class Name Match: The class defined MUST match the block argument (e.g.,
class User inside ```model:User).
-
Config Blocks (config):
- Used for global configuration and exports.
- Location: Strictly restricted to
config.td files only. Do NOT use config blocks in regular .td files.
- Exposure: All symbols defined in
config are automatically exposed to the directory scope and inherited by subdirectories.
-
Entity Blocks & Identifiers:
- Every Entity MUST have a unique identity.
- Syntax:
entity <Type>: <ID>
- The ID:
- The string after the colon is the entity identifier.
- Styles: Can be a simple name (
alice) or a slug (user-alice-v1).
- Content: Valid YAML matching the Pydantic model.
- Reference Rule: When referencing other entities within an entity block, you MUST use the
[[ID]] (Wiki Link) syntax.
- References (
[[...]]):
- Typedown supports two reference forms:
- ID Reference:
[[id]]
- Lookup by name in the current scope or global index.
- Examples:
[[alice]], [[users/alice]]
- Hash Reference:
[[sha256:...]]
- Match content hash exactly for immutable references.
- Used for version locking and history tracking.
- Evolution Semantics (
former):
When tracking object changes over time:
- Syntax:
former: [[<Identifier>]]
- Rule: You MUST use the reference syntax
[[]] for the former field.
- Rule: Prefer using Content Hash for
former pointers to ensure historical stability. Globally unique IDs are also acceptable.
- Spec Blocks (
spec):
- Used for validation logic.
- Contains Python functions decorating with
@target.
The Typedown Mindset: Consensus Modeling
Typedown is not just a syntax; it is a rigorous method for converting loose natural language into strict systemic consensus. When using Typedown, follow this 5-step cognitive process:
1. Entity Discovery (Identification)
Scan the unstructured text or requirement to identify Key Entities. Immediately instantiate them using entity blocks to fix their existence.
- Action: Create
entity:<Type> blocks with YAML content.
- Goal: Turn "User Alice" into data.
2. Schema Abstraction (Structure)
Analyze the entity blocks you just created. Abstract their common structure into Pydantic models (model).
- Action: Define
model:<Type> blocks.
- Context: Place shared models in a parent
config.td or common.td and export them if they are used across multiple files.
3. Constraint Engineering (Logic)
Analyze the business rules governing these entities. Enforce them using three layers of defense:
- Layer 1 (Field Types): Use strict types (e.g.,
EmailStr, PositiveInt).
- Layer 2 (Validators): Use Pydantic
@field_validator or @model_validator for self-contained consistency.
- Layer 3 (Specs): Use
spec blocks with @target tags for cross-entity or graph-level validation (e.g., "A specific user must exist in the admin group").
4. Reference & Learning (Research)
If you are unsure about advanced syntax (e.g., how to use former for versioning or tags for filtering):
- Action: Create a
_reference directory (it is git-ignored).
- Action: Clone the official repo:
git clone https://github.com/IndenScale/typedown.git _reference/typedown.
- Action: Read
docs/ or cookbook/01_getting_started/ in the reference to ground your knowledge.
5. Verification (Feedback)
Never assume your code is correct. Always verify with the compiler.
- Action: Run
uvx typedown check <path> immediately after editing.
- Action: Treat warnings as errors.
Example: The Modeling Loop
class ComplianceStandard(str, Enum):
ISO_27001 = "ISO-27001"
SOC2 = "SOC2"
class Server(BaseModel):
hostname: str
compliance: List[ComplianceStandard]
@model_validator(mode='after')
def check_security(self):
if ComplianceStandard.ISO_27001 in self.compliance:
# Enforce some logic...
pass
return self
hostname: "alpha-01"
compliance:
- "ISO-27001"