Matrix Declaration
What a matrix is, how to declare one, and how to organize your workspace.
A matrix is a codified operating model for a business domain. It declares what a domain knows (ontology), what rules it enforces (constraints), what it can do (actions), and how it connects to external systems (services). This guide walks you through creating matrix declarations for different scenarios, explains how to think about scoping and organizing them, and shows how the declaration shapes everything else in your matrix.
Your First matrix.ttl
Every matrix starts with a declaration file. Here's a complete, minimal example for a task management domain:
@base <https://example.org/spec/tasks#> .
@prefix rars-mtx: <https://poliglot.io/rars/spec/matrix#> .
@prefix rars-iam: <https://poliglot.io/rars/spec/iam#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix tasks: <https://example.org/spec/tasks#> .
tasks:
a rars-mtx:Matrix ;
rars-mtx:name "tasks" ;
rars-mtx:description "Task management operating model. Tracks tasks, assignments, priorities, and status transitions across projects." ;
rars-mtx:proprietor tasks:TaskAgent ;
rars-mtx:repositoryUrl "https://github.com/example/my-project"^^xsd:anyURI .
tasks:TaskAgent
a rars-iam:Agent ;
rdfs:label "Task Agent" ;
skos:definition "Security principal for task management operations." .Let's break down the decisions in this file.
The Base URI
@base <https://example.org/spec/tasks#> .This becomes the permanent identity of your matrix and the namespace for everything you define. Choose it carefully: it appears in every resource URI, every cross-reference, and every provenance record. Changing it later is a breaking change for anything that depends on your matrix.
Use a URI you control. The domain should be yours, the path should be descriptive, and the fragment identifier (#) means local names can be appended directly (e.g., tasks:Task expands to https://example.org/spec/tasks#Task).
The Description
rars-mtx:description "Task management operating model. Tracks tasks, assignments, priorities, and status transitions across projects." .This is not just metadata. RARS reads the description to understand what your domain does when deciding whether to activate it. Write it for an AI audience: clear, specific, no marketing language.
Compare these:
- Bad: "A powerful task management solution for teams." (RARS learns nothing actionable)
- OK: "Task management operating model." (minimal, but functional)
- Good: "Task management operating model. Tracks tasks, assignments, priorities, and status transitions across projects." (RARS knows exactly what concepts this matrix covers)
The Agent
Every matrix has an agent, declared as its proprietor. This is the security principal under which the matrix's operations execute. When RARS invokes an action from your matrix, it does so as this agent. When provenance records are created, they attribute observations to this agent.
tasks:TaskAgent
a rars-iam:Agent ;
rdfs:label "Task Agent" ;
skos:definition "Security principal for task management operations." .The label and definition show up in escalation requests and audit logs. If a user sees "Task Agent requests permission to read customer records", they should understand exactly what they're granting access to. Name it after the domain, not the implementation.
The agent itself is just an identity. Roles and permissions are assigned separately (see Security).
Real-World Examples
A CRM Matrix
A CRM domain has a broader scope than tasks. It owns customers, contacts, deals, and pipeline stages:
@base <https://acme.com/spec/crm#> .
@prefix rars-mtx: <https://poliglot.io/rars/spec/matrix#> .
@prefix rars-iam: <https://poliglot.io/rars/spec/iam#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix crm: <https://acme.com/spec/crm#> .
crm:
a rars-mtx:Matrix ;
rars-mtx:name "crm" ;
rars-mtx:description "Customer relationship management. Manages customer accounts, contacts, deals, pipeline stages, and activity history. Integrates with Salesforce for account synchronization." ;
rars-mtx:proprietor crm:CRMAgent ;
rars-mtx:repositoryUrl "https://github.com/acme/matrices"^^xsd:anyURI .
crm:CRMAgent
a rars-iam:Agent ;
rdfs:label "CRM Agent" ;
skos:definition "Manages customer relationships, synchronizes with Salesforce, and tracks deal progression." .Notice the description mentions the Salesforce integration. When RARS needs to look up a customer in Salesforce, this description helps it identify the right matrix to activate.
A Shared Vocabulary Matrix
Some concepts are shared across domains. Rather than duplicating "Project" or "Employee" in every matrix, define a shared vocabulary:
@base <https://acme.com/spec/common#> .
@prefix rars-mtx: <https://poliglot.io/rars/spec/matrix#> .
@prefix rars-iam: <https://poliglot.io/rars/spec/iam#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix common: <https://acme.com/spec/common#> .
common:
a rars-mtx:Matrix ;
rars-mtx:name "common" ;
rars-mtx:description "Shared organizational vocabulary. Defines employees, departments, projects, and organizational hierarchy used across all domain matrices." ;
rars-mtx:proprietor common:CommonAgent .
common:CommonAgent
a rars-iam:Agent ;
rdfs:label "Common Vocabulary Agent" ;
skos:definition "Manages shared organizational concepts referenced by domain-specific matrices." .This matrix has no actions, no service integrations, no secrets. It's purely definitional. Other matrices import it to reference its classes:
# In the tasks matrix:
tasks: rars-mtx:imports <https://acme.com/spec/common#> .A Vendor Integration Matrix
A matrix that wraps a third-party service for internal operations (e.g., Stripe for financial management):
@base <https://acme.com/spec/finance#> .
@prefix rars-mtx: <https://poliglot.io/rars/spec/matrix#> .
@prefix rars-iam: <https://poliglot.io/rars/spec/iam#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix finance: <https://acme.com/spec/finance#> .
finance:
a rars-mtx:Matrix ;
rars-mtx:name "finance" ;
rars-mtx:description "Financial operations and accounting. Tracks invoices, reconciles payments, manages subscription billing, and synchronizes revenue data with Stripe for reporting and auditing." ;
rars-mtx:proprietor finance:FinanceAgent ;
rars-mtx:imports <https://acme.com/spec/common#> .
finance:FinanceAgent
a rars-iam:Agent ;
rdfs:label "Finance Agent" ;
skos:definition "Manages financial records, reconciles billing data with Stripe, and tracks revenue and subscription status for internal reporting." .This matrix imports common because it references shared concepts like customers and projects. It owns the Stripe integration, the financial ontology, and the accounting actions. Other matrices never talk to Stripe directly; they go through this matrix's actions to look up invoice status, reconcile payments, or pull revenue reports.
Scoping a Matrix
The most important design decision is what goes into a single matrix vs. what becomes a separate one. This directly affects how RARS loads capabilities at runtime.
When a conversation needs capabilities from a domain, RARS activates the relevant matrix. A well-scoped matrix means RARS loads only what's needed. A monolithic matrix that covers too many concerns forces RARS to load everything even when only a fraction is relevant.
Patterns That Work
One domain, one matrix. Tasks, customers, billing, inventory: each gets its own matrix with its own agent, its own ontology, and its own actions. They compose through imports and cross-references.
Shared concepts in a shared matrix. If multiple domains reference "Employee" or "Project", extract those into a shared vocabulary matrix. This prevents definition drift where each domain has its own slightly different version of the same concept.
Integration logic lives with the domain it serves. A matrix that manages tasks and connects to Jira should own both the task ontology and the Jira service integration. Don't split the integration into a separate matrix unless multiple domains need independent Jira access.
Patterns to Avoid
The mega-matrix. One matrix with 50 classes, 30 actions, and 5 service integrations. RARS loads all of it whenever any part is needed. Split it along domain boundaries.
The micro-matrix. A matrix per class. Sometimes this is a correct approach for central or highly complex classes, but typically this is too granular. RARS spends more time activating matrices than doing work. Group related concepts that always appear together.
Cross-cutting integration matrices. A "services" matrix that owns all external API connections. This creates a bottleneck: every domain depends on it, and changes to one integration risk breaking others. Let each domain own its own integrations.
The Test
Ask: "Can this matrix operate independently?" If two sets of concepts always activate together and never make sense apart, they're one matrix. If they can operate independently, they should be separate.
File Organization
A typical matrix has this file structure:
tasks/
matrix.ttl # Declaration, imports, agent
ontology.ttl # Classes, properties, individuals
shapes.ttl # Constraints (SHACL)
actions.ttl # Action definitions and handlers
mappings.ttl # RML response mappings
secrets.ttl # Secret declarations
iam.ttl # Roles and access policiesNot every matrix needs every file. A shared vocabulary matrix might have just matrix.ttl, ontology.ttl, and shapes.ttl. A full service integration matrix will need all of them.
The file names are conventions, not requirements. Poliglot merges all .ttl files in your matrix directory into a single graph during assembly. You could put everything in one file if you wanted to, but splitting by concern makes diffs readable and code review practical.
See Also
- Domain Modeling: designing your ontology
- Constraints and Validation: defining what valid data looks like
- Security: assigning roles and policies to your agent