Packaging and Versioning

Your matrix as operations-as-code.

Terraform codifies your technical infrastructure. A matrix package codifies your business operations. The same principles apply: you define your operating model as code, version it with semantic versioning, validate it before deployment, and deploy it to your workspace. Changes are tracked, rollbacks are possible, and every deployment is reproducible.

This guide covers how to think about packaging and versioning your matrices. For the full package format reference, see Package FormatPackage Format. This guide covers how to think about packaging and versioning your matrices.

The Package

A package is a versioned, installable unit containing one or more matrices. It's what rars build produces and rars install ships to your workspace.

At its simplest, a package contains a single matrix:

# poliglot.yml
version: "1"

package:
  name: "task-management"
  version: "1.0.0"
  engineVersion: "1"

matrix:
  tasks:
    path: "."
    spec:
      - ./spec
    outputDir: ./.matrix

The name and version identify the package in your workspace. The engineVersion targets a major version of the RARS runtime (RARS auto-applies minor and patch updates within that major version).

The Build

rars build transforms your spec files into an installable package:

  1. Parse: reads your poliglot.yml and locates all spec directories
  2. Merge: combines all spec files per matrix into a single assembly graph
  3. Package: produces a versioned archive with a manifest, the merged assembly, and any bundled artifacts

The build step handles local packaging. The full validation pipeline (namespace enforcement, import resolution, dependency merging, inference, SHACL shape validation) runs server-side during installation. This is where Poliglot validates your package against the workspace's current state and the full specification. If validation fails, the installation is rejected with detailed error messages and the workspace is unchanged.

The output is a package archive containing:

package.tgz
├── manifest.json           # Package metadata and matrix listing
├── tasks/
│   ├── assembly.ttl        # Merged RDF graph
│   └── artifacts/          # Bundled non-RDF resources (if any)

Installing

rars install uploads the package to your workspace. Poliglot validates the package against the workspace's current state, resolves imports, and installs the matrices.

rars build --config poliglot.yml
rars install --config poliglot.yml --workspace my-workspace

Installation is atomic. Either all matrices in the package install successfully, or none do. If validation fails during installation (a missing import, a namespace conflict, a shape violation), the workspace is unchanged.

After deployment, new contexts in the workspace can activate the installed matrices. Existing contexts that are already running continue using the previous version until they're restarted. There's no disruption to active sessions.

Semantic Versioning

Packages follow semantic versioning. The version in your poliglot.yml communicates the nature of changes to your workspace:

Patch (1.0.0 to 1.0.1): bug fixes, annotation improvements, adding optional properties. Nothing breaks for consumers.

Minor (1.0.0 to 1.1.0): new classes, properties, actions, or individuals. Backwards-compatible. Consumers can adopt new features at their own pace.

Major (1.0.0 to 2.0.0): removed or renamed URIs, changed property domains/ranges, tightened constraints. Breaking change. Consumers must update.

Remember that URIs are part of your contract (see Modeling Your Domain). Renaming a class or removing an action is a major version change because other matrices may reference those URIs.

For breaking changes, the recommended approach: mark resources as deprecated with clear messaging, give consumers two or three release cycles to migrate, then remove in the next major version.

Multi-Matrix Packages

A package can contain multiple matrices when they're logically related and should be versioned together:

version: "1"

package:
  name: "hr-suite"
  version: "2.1.0"
  engineVersion: "1"

matrix:
  people:
    path: "./people"
    spec:
      - ./spec
    outputDir: ./.matrix

  onboarding:
    path: "./onboarding"
    spec:
      - ./spec
    outputDir: ./.matrix

  payroll:
    path: "./payroll"
    spec:
      - ./spec
    outputDir: ./.matrix

All matrices in a package are deployed atomically. They share the package version. If you need to version matrices independently, package them separately.

Multi-matrix packages make sense when matrices import each other and need coordinated releases. If the matrices are independent business domains that happen to be maintained by the same team, separate packages give you more deployment flexibility.

Bundling Artifacts

Matrices can include non-RDF resources alongside the specification: prompt templates, configuration files, images, compiled UI components. These are artifacts, bundled in the artifacts/ directory of each matrix.

Artifacts are declared in your spec and resolved at runtime:

tasks:TaskPromptTemplate
    a rars-build:Artifact ;
    rars-build:path "prompts/task-planning.md" ;
    rars-build:format rars-cnt:TextMarkdown ;
    rdfs:label "Task Planning Prompt" .

Include artifact directories in your poliglot.yml:

matrix:
  tasks:
    path: "."
    spec:
      - ./spec
    artifacts:
      - ./spec/artifacts
    outputDir: ./.matrix

Artifacts have size limits: 10MB compressed per matrix bundle, 5MB per individual file, 1000 files maximum. Keep artifacts focused. Large datasets or media should live in external storage, not in the package.

Namespace Discipline

Every resource defined in a matrix must use URIs within the matrix's namespace. This is enforced at build time. You can reference resources from imported matrices, but you can't define or modify resources that belong to another matrix's namespace.

# Valid: subject in your namespace
tasks:MyAction a rars-act:Action .

# Valid: referencing an imported type
tasks:MyThing a imported:SomeClass .

# Invalid: defining a resource in another namespace
imported:SomeClass rdfs:label "Hijacked" .

This enforcement is what makes matrices composable. Each matrix owns its namespace, and no other matrix can tamper with it. You can install third-party matrices with confidence that they can't modify your resources.

The Development Cycle

The typical workflow mirrors software development:

  1. Author: write or modify your spec files
  2. Build: rars build merges and packages
  3. Test: deploy to a development workspace, verify behavior in a context
  4. Release: bump the version, deploy to production workspace
  5. Iterate: repeat

For teams, this integrates with standard CI/CD workflows. The build step runs in your pipeline, the deploy step targets your staging or production workspace. The package archive is an immutable artifact that can be promoted through environments.

Summary

  • Packages are operations-as-code: versioned, validated, deployable units of your business operating model
  • Validation runs on deployment: Poliglot validates your package against the full specification and workspace state server-side
  • Semantic versioning communicates change: patch, minor, and major versions tell consumers what to expect
  • Deployment is atomic: all matrices install or none do, no partial state
  • Active sessions are unaffected: existing contexts continue on the previous version
  • Artifacts bundle non-RDF resources: prompts, configs, and UI components travel with the matrix
  • Namespaces enforce ownership: each matrix owns its URIs, no tampering from other matrices

On this page