Machine Anatomy
A machine is the fundamental unit in mashin. Every .mashin file contains one machine with a clear structure: what it is, what it takes, what it returns, how it works, and what rules it follows. This structure is not arbitrary. It reads from top to bottom as a complete specification of intelligence.
The five layers
Every machine follows a canonical ordering. Think of it as five layers, each building on the one before it:
| Layer | Sections | Purpose |
|---|---|---|
| Identity | has, uses | What the machine is and what it depends on |
| Contract | accepts, responds with | What goes in and what comes out |
| Specification | achieves, ensures | What it aims for and what rules govern it |
| Implementation | implements | The actual behavior: steps, flows, state |
| Verification | verifies | Tests that prove it works |
Here is a complete machine that uses all five layers:
machine email_classifier "Email Classifier"
accepts subject as text, is required body as text, is required sender as text
responds with priority as text category as text
achieves goal classify_accurately succeeds when "priority and category are always set" never "classify an empty email"
implements ask classify, using: "anthropic:claude-sonnet-4-6" with role "You are an email triage specialist." with task "Classify this email by priority and category.\n\nSubject: ${input.subject}\nBody: ${input.body}" returns priority as text category as text assuming priority: "medium" category: "general"
ensures permissions allowed to llm_call
verifies test "billing email" assuming classify { priority: "high", category: "billing" } given { subject: "Invoice overdue", body: "Your payment is 30 days past due." } expect { priority: "high", category: "billing" }Section by section
accepts
Defines the input contract. Each field has a name, a type, and optional modifiers. The runtime validates inputs before any step runs.
accepts name as text, is required age as integer, min: 0 role as text, default: "member", choices: ["member", "admin"]responds with
Defines the output contract. Callers know the exact shape of what they will receive.
responds with greeting as text processed_at as numberachieves
Declares the goal of the machine. The succeeds when, never, and for example clauses serve as both documentation and test scaffolding.
implements
Where the work happens. Contains steps (the actions the machine performs), flows (grouping for multi-path execution), state, and runtime configuration. Most machines have a single linear sequence of steps here.
ensures
Governance declarations. What the machine is and is not allowed to do. See the Governance guide for details.
verifies
Tests that run against the machine. The assuming clause mocks external steps so tests are fast, deterministic, and free.
Naming
Machine names are bare identifiers in snake_case. An optional display name in quotes follows:
machine ticket_router "Support Ticket Router"The identifier is the code-level name used in references and file names. The display name is for UI and documentation.
Try it
Create a file called greeter.mashin and write the simplest possible machine:
machine greeter
accepts name as text, is required
responds with greeting as text
implements compute greet {greeting: "Hello, " + input.name + "!"}This machine has no governance section because compute steps are pure by construction. They cannot perform I/O, so no permissions are needed.
Next steps
- Your First Ask Step - Add LLM reasoning to a machine
- Inputs and Outputs - Field types, validation, and constraints
- accepts reference - Full specification
- implements reference - Everything inside the behavior section