Skip to content

stores

stores

Declare data models and storage backends for a machine. The stores section gives any machine the ability to define structured data resources, connect to databases (SQL, vector, or other), and manage data through Ash Framework resources. Resources compile to Ash modules at runtime; users never see generated Elixir code.

stores replaces the older “domain machine” concept. A machine with stores and no steps is the equivalent of a domain machine. A machine with stores and steps can both define data and operate on it.

When to use

Use stores when your machine needs to:

  • Persist structured data (users, orders, tickets, etc.)
  • Define a data model with relationships, constraints, and actions
  • Connect to an existing database
  • Store and search vector embeddings (for RAG, similarity search, etc.)
  • Share a data model with other machines via from: imports

Omit stores for machines that only transform data in-flight or call external APIs. Not every machine needs its own data model.

Syntax

stores
store <name>
source: <backend>
resource <name>
<field> as <type>, <modifiers>
timestamps
<relationship>
<identity>
<action>
<policy>
<vectors>

Store configuration

ConfigRequiredDescription
sourceYesStorage backend: managed, none, postgres, sqlite, external

Source types

SourceDescription
managedMashin creates and manages the tables. Default for new stores.
noneTypes only, no backing storage. Useful for shared data contracts.
postgresConnect to an existing PostgreSQL database.
sqliteConnect to an existing SQLite database.
externalUser-managed database (Mashin does not create tables).

Resource fields

Each resource declares fields using the standard as type syntax:

resource ticket
subject as text, is required
priority as text, default: "medium"
resolved as boolean, default: false
created_by as text
timestamps

The timestamps keyword adds inserted_at and updated_at fields automatically.

Field types

All standard Mashin types are available: text/string, number, integer, decimal, boolean, list, map, any, plus uuid for identifiers.

Relationships

resource team
name as text, is required
resource ticket
subject as text, is required
belongs_to team: team
timestamps
resource comment
body as text, is required
belongs_to ticket: ticket
timestamps
RelationshipDescription
has_many <name>: <resource>One-to-many relationship
belongs_to <name>: <resource>Many-to-one relationship
has_one <name>: <resource>One-to-one relationship

Identity constraints

identity unique_email: [email]
identity unique_slug: [org_id, slug]

Actions

Ash actions define the CRUD interface for a resource. Each action type supports different options:

create register
accept: [name, email, role]
read by_email
argument email: text
filter: email == ^email
read active
filter: active == true
update change_role
accept: [role]
destroy deactivate
Action typeDescription
create <name>Insert a new record. accept: lists writable fields.
read <name>Query records. argument for parameters, filter for conditions.
update <name>Modify existing records. accept: lists updatable fields.
destroy <name>Delete records.

Authorization policies

policy action_type(read)
authorize_if always()
policy action_type(create)
authorize_if actor_attribute_equals("role", "admin")

Add vector storage and semantic search capability to a resource:

resource document
title as text, is required
content as text, is required
timestamps
vectors
source: qdrant
embedding_model: "nomic-embed-text"
chunking: semantic
ConfigDescription
sourceVector database backend (currently: qdrant)
embedding_modelModel used to generate embeddings
chunkingChunking strategy: semantic, paragraph, fixed

Store composition

Import another machine’s store to use its resources:

stores
store tickets, from: "@myorg/ticket-tracker"

This makes the imported machine’s resources available in the current machine’s steps.

Examples

Simple data model

machine user_directory
stores
store users
source: managed
resource user
name as text, is required
email as text, is required
role as text, default: "member"
active as boolean, default: true
timestamps
identity unique_email: [email]
create register
accept: [name, email, role]
read by_email
argument email: text
filter: email == ^email
read active_users
filter: active == true
update change_role
accept: [role]
destroy remove

Machine with both stores and steps

machine ticket_system
accepts
subject as text, is required
body as text, is required
responds with
ticket_id as text
status as text
stores
store data
source: managed
resource ticket
subject as text, is required
body as text, is required
team as text
status as text, default: "open"
timestamps
create submit
accept: [subject, body, team, status]
implements
ask classify, using: "anthropic:claude-haiku-4"
with task "Classify this ticket: ${input.subject}"
returns
team as text
compute result
{ticket_id: "new", status: "open", team: steps.classify.team}

RAG-enabled store

machine knowledge_base
stores
store docs
source: managed
resource article
title as text, is required
content as text, is required
category as text
timestamps
vectors
source: qdrant
embedding_model: "nomic-embed-text"
chunking: semantic
create add_article
accept: [title, content, category]
read search
argument query: text

Implementation status

The stores syntax is designed and the parser handles it, but the full runtime pipeline (compiling store definitions to Ash resources at runtime via Code.compile_string) is in progress. Schema evolution (ALTER TABLE support) and the resource-to-Qdrant bridge are planned.

Canonical ordering

stores appears between responds with and implements:

machine name
...
accepts ...
responds with ...
stores ... <-- here (section 4)
defines ...
implements ...

Governance

Store actions (create, read, update, destroy) are governed the same way as any other effect. A machine must have appropriate database capabilities (db_read, db_write) declared in its ensures > permissions > allowed to list. Every store action executed through a step is mediated by the governance interpreter and recorded in the behavioral ledger.

Translations

LanguageKeyword
Englishstores
Spanishalmacena
Frenchstocke
Germanspeichert
Japanese格納
Chinese存储
Korean저장

See also

  • implements - Steps that use store resources
  • ensures - Permission declarations for database access
  • accepts - Input contract for machines that wrap store operations