Constraint Visibility in Practice: A Multi-Module Case Study

· SysMARA Team

SysMARA's core claim is Constraint Visibility: every business rule should be discoverable from the system's machine-readable artifacts, without reading source code or human-written documentation. This post is a case study proving that claim with a real multi-module system.

Everything below — every YAML snippet, every CLI output, every generated file — was captured from a live SysMARA v0.7.1 session. You can reproduce it in under 5 minutes.

The system: inventory + orders

We designed a minimal e-commerce backend with meaningful architectural constraints:

  • 2 modules: inventory (product catalog, stock) and orders (order placement, cancellation)
  • 2 entities: product (6 fields) and order (7 fields)
  • 5 capabilities: add_product, update_stock, create_order, cancel_order, list_orders
  • 3 invariants: stock non-negativity, price positivity, order quantity minimum
  • 1 policy: discontinued products cannot be ordered
  • 1 flow: order placement with saga compensation
  • 1 forbidden dependency: inventory must not import from orders

This is small enough to fit in a blog post, but complex enough to demonstrate cross-module constraint enforcement — the exact scenario where "just write it in the README" breaks down.

Step 1: Define the modules

# system/modules.yaml
modules:
  - name: inventory
    description: Product catalog and stock management
    entities:
      - product
    capabilities:
      - add_product
      - update_stock
    allowedDependencies: []
    forbiddenDependencies:
      - orders

  - name: orders
    description: Order management and fulfillment
    entities:
      - order
    capabilities:
      - create_order
      - cancel_order
      - list_orders
    allowedDependencies:
      - inventory
    forbiddenDependencies: []

The key line: forbiddenDependencies: [orders] on the inventory module. This is not a comment or a convention — it is a formal constraint that SysMARA validates on every build.

Step 2: Define invariants as first-class specs

# system/invariants.yaml
invariants:
  - name: stock_cannot_be_negative
    description: Product stock must never go below zero after any operation
    entity: product
    rule: product.stock must be >= 0 after any update
    severity: error
    enforcement: runtime

  - name: price_must_be_positive
    description: Product price must be greater than zero
    entity: product
    rule: product.price must be > 0
    severity: error
    enforcement: runtime

  - name: order_quantity_must_be_positive
    description: Order quantity must be at least 1
    entity: order
    rule: order.quantity must be >= 1
    severity: error
    enforcement: runtime

Each invariant has a name, an entity it protects, a rule in plain language, a severity, and an enforcement mode. These are not documentation — they are structured nodes in the system graph that the compiler reads.

Step 3: Bind invariants to capabilities

The create_order capability declares which invariants it must enforce:

# system/capabilities.yaml (excerpt)
  - name: create_order
    module: orders
    description: Create a new order for a product
    entities: [order, product]
    input:
      - name: product_id
        type: uuid
        required: true
      - name: quantity
        type: number
        required: true
    output:
      - name: order
        type: order
        required: true
    policies:
      - only_active_products_orderable
    invariants:
      - stock_cannot_be_negative
      - order_quantity_must_be_positive

Notice: create_order lives in the orders module but references stock_cannot_be_negative, which is defined on the product entity in the inventory module. This is a cross-module invariant binding. In a traditional codebase, this constraint would live in a different service's source code — invisible to the orders team and invisible to AI agents.

Step 4: Build and verify

$ sysmara validate

════════════════════════════════════════════════════════════
  Validation Results
════════════════════════════════════════════════════════════

 Spec Type    │ Count
──────────────┼───────
 Entities     │ 2
 Capabilities │ 5
 Policies     │ 1
 Invariants   │ 3
 Modules      │ 2
 Flows        │ 1

[OK] Validation passed. 0 warning(s).
$ sysmara build

  Parsing specs...
[INFO] Found 2 entities, 5 capabilities, 1 policies, 3 invariants, 2 modules, 1 flows

  Cross-validating...
[INFO] No cross-validation issues.

  Building system graph...
[INFO] system-graph.json (14 nodes, 21 edges)

  Compiling capabilities...
[INFO] Generated 15 file(s)

  Scaffolding app/ stubs...
[INFO] Scaffold: 13 written, 0 skipped (already exist)

[OK] Build completed successfully.
$ sysmara doctor

════════════════════════════════════════════════════════════
  SysMARA Doctor — System Health Check
════════════════════════════════════════════════════════════

  [PASS] Configuration: sysmara.config.yaml found
  [PASS] Spec Directory: ./system directory found
  [PASS] Spec Parsing: Parsed successfully: 2 entities, 5 capabilities,
         1 policies, 3 invariants, 2 modules, 1 flows
  [PASS] Cross-Validation: No cross-validation issues
  [PASS] Module Boundaries: All boundaries valid
  [PASS] Invariant Specs: All invariant specs valid
  [PASS] Diagnostics: 0 error(s), 0 warning(s), 0 info
  [PASS] Orphan Detection: No orphan specs detected
  [PASS] Module Cycles: No dependency cycles detected

[OK] System is healthy.
$ sysmara check boundaries

════════════════════════════════════════════════════════════
  Boundary Check
════════════════════════════════════════════════════════════

[OK] All boundaries valid. No violations or cycles detected.

9 health checks pass. The system graph has 14 nodes and 21 edges — every entity, capability, policy, invariant, module, and flow is a node. Every relationship (uses_entity, governed_by, enforces, belongs_to) is a typed edge.

What AI agents actually see

When an AI agent is asked to implement create_order, it can query the system:

$ sysmara explain capability create_order

════════════════════════════════════════════════════════════
  Capability: create_order
════════════════════════════════════════════════════════════

  Description:  Create a new order for a product
  Module:       orders

  Entities
    - order
    - product

  Input
    - product_id: uuid (required)
    - quantity: number (required)

  Output
    - order: order (required)

  Policies
    - only_active_products_orderable (effect: deny)

  Invariants
    - stock_cannot_be_negative [error]
    - order_quantity_must_be_positive [error]

This is Constraint Visibility. The AI does not need to:

  • Read through 50 middleware files to find the product status check
  • Grep for "stock" across the codebase to discover the non-negativity rule
  • Ask a human "are there any business rules I should know about?"
  • Hope that someone put it in the README

The constraints are declared on the capability, and the CLI returns them in a structured format that any LLM can parse.

The invariant explains itself

$ sysmara explain invariant stock_cannot_be_negative

════════════════════════════════════════════════════════════
  Invariant: stock_cannot_be_negative
════════════════════════════════════════════════════════════

  Description:  Product stock must never go below zero after any operation
  Entity:       product
  Rule:         product.stock must be >= 0 after any update
  Severity:     error
  Enforcement:  runtime

  Referenced by Capabilities
    - update_stock (module: inventory)
    - create_order (module: orders)

Two capabilities reference this invariant — one in inventory, one in orders. The invariant itself does not "know" about modules. It is bound to the product entity. Capabilities that touch product and declare this invariant get the enforcement wired in.

Impact analysis: what breaks if you change product?

$ sysmara impact capability create_order

════════════════════════════════════════════════════════════
  Impact Analysis: capability:create_order
════════════════════════════════════════════════════════════

  Affected Modules (2):
    - inventory
    - orders

  Affected Capabilities (4):
    - add_product
    - cancel_order
    - list_orders
    - update_stock

  Affected Invariants (3):
    - order_quantity_must_be_positive
    - price_must_be_positive
    - stock_cannot_be_negative

  Affected Policies (1):
    - only_active_products_orderable

  Affected Flows (1):
    - order_placement_flow

  Tests Likely Affected (5):
    - tests/capabilities/add_product.test.ts
    - tests/capabilities/cancel_order.test.ts
    - tests/capabilities/create_order.test.ts
    - tests/capabilities/list_orders.test.ts
    - tests/capabilities/update_stock.test.ts

  Generated Artifacts (14):
    - generated/capability/add_product.ts ... (14 files)

  Total Impact Radius: 11 nodes

Changing create_order affects 11 nodes across both modules. The impact analysis tells the AI agent exactly which tests to run, which generated files will be regenerated, and which invariants could be affected.

In a traditional codebase, this information does not exist in machine-readable form. A developer might know it intuitively. An AI agent cannot.

The flow: saga compensation across modules

# system/flows.yaml
flows:
  - name: order_placement_flow
    description: Place order, deduct stock, with compensation on failure
    trigger: create_order
    module: orders
    steps:
      - name: create_order
        action: create_order
        onFailure: compensate
        compensation: cancel_order
      - name: deduct_stock
        action: update_stock
        onFailure: compensate
        compensation: update_stock
$ sysmara flow validate order_placement_flow

════════════════════════════════════════════════════════════
  Flow Validation: order_placement_flow
════════════════════════════════════════════════════════════
[OK] Flow is valid.
[INFO] Steps: 2
[INFO] Capabilities required: create_order, cancel_order, update_stock

The flow references capabilities from both modules. SysMARA validates that all referenced capabilities exist and that the compensation actions are valid. If someone renames cancel_order, the flow validation catches it at build time — not in production.

The generated code: constraints are structural

The scaffold for create_order — generated entirely from the YAML spec:

// SCAFFOLD: capability:create_order
// Edit Zone: editable — generated once, safe to modify

import { enforceOnlyActiveProductsOrderable }
  from '../policies/only_active_products_orderable.js';
import { validateStockCannotBeNegative }
  from '../invariants/stock_cannot_be_negative.js';
import { validateOrderQuantityMustBePositive }
  from '../invariants/order_quantity_must_be_positive.js';

export async function handleCreateOrder(ctx) {
  const input = ctx.body;

  // Policy gate — present because spec declares it
  if (!enforceOnlyActiveProductsOrderable(ctx.actor)) {
    throw new Error('Policy violation: only_active_products_orderable');
  }

  const repo = orm.repository('order', 'create_order');
  const result = await repo.create(input);

  // Invariant checks — present because spec declares them
  const stockViolation = validateStockCannotBeNegative(result);
  if (stockViolation) throw new Error(stockViolation.message);

  const qtyViolation = validateOrderQuantityMustBePositive(result);
  if (qtyViolation) throw new Error(qtyViolation.message);

  return result;
}

Three observations:

  1. The policy check (enforceOnlyActiveProductsOrderable) is an import and a function call — generated because policies: [only_active_products_orderable] appears in the capability spec.
  2. The invariant validators (validateStockCannotBeNegative, validateOrderQuantityMustBePositive) are imported and called — generated because invariants: [stock_cannot_be_negative, order_quantity_must_be_positive] appears in the capability spec.
  3. The validator functions themselves are stubs — the developer (or AI agent) fills in the logic. But the call site is guaranteed. You cannot forget to call the validator.

The invariant validator: what the AI must fill in

// SCAFFOLD: invariant:stock_cannot_be_negative
// Edit Zone: editable — generated once, safe to modify

import type { Product } from '../entities/product.js';

export interface InvariantViolation {
  invariant: string;
  message: string;
  severity: 'error' | 'warning';
}

export function validateStockCannotBeNegative(
  entity: Product
): InvariantViolation | null {
  // Rule: "product.stock must be >= 0 after any update"
  // TODO: Implement your validation logic here.
  return null;
}

The AI agent sees:

  • The invariant name
  • The entity type it receives
  • The rule in plain language
  • The return type (structured violation or null)

Implementing if (entity.stock < 0) return violation is trivial. The hard part — knowing this check exists and ensuring it is called — is already solved by the framework.

The system map: one file, full picture

// .framework/system-map.json (generated)
{
  "modules": [
    {
      "name": "inventory",
      "entities": ["product"],
      "capabilities": ["add_product", "update_stock"],
      "dependencies": []
    },
    {
      "name": "orders",
      "entities": ["order"],
      "capabilities": ["cancel_order", "create_order", "list_orders"],
      "dependencies": ["inventory"]
    }
  ],
  "capabilities": [
    {
      "name": "create_order",
      "module": "orders",
      "entities": ["order", "product"],
      "policies": ["only_active_products_orderable"],
      "invariants": [
        "order_quantity_must_be_positive",
        "stock_cannot_be_negative"
      ]
    }
    // ... 4 more capabilities
  ],
  "entities": ["order", "product"],
  "unresolved": []
}

An AI agent can read this single JSON file and know:

  • Which modules exist and their dependency graph
  • Which capabilities each module exposes
  • Which policies and invariants govern each capability
  • Which entities are referenced across modules
  • Whether anything is unresolved (dangling references)

Reproducing this case study

# Takes about 2 minutes
mkdir case-study && cd case-study
npx @sysmara/core init --db sqlite --orm sysmara-orm

# Copy the YAML specs from this post into system/*.yaml
# Then:
npx sysmara build
npx sysmara doctor
npx sysmara explain capability create_order
npx sysmara impact capability create_order
npx sysmara flow validate order_placement_flow
npx sysmara check boundaries

# Inspect generated code:
cat app/capabilities/create_order.ts
cat app/invariants/stock_cannot_be_negative.ts
cat .framework/system-map.json

What this proves

This is not a theoretical argument. It is a working system you can build and query right now.

  • Cross-module invariants work. stock_cannot_be_negative is defined on product (inventory) but enforced by create_order (orders). The binding is declared in the capability spec and compiled into the generated handler.
  • Module boundaries are formal. The system graph tracks allowed and forbidden dependencies. sysmara check boundaries validates them on every build.
  • Flows span modules safely. The order_placement_flow calls capabilities from both orders and inventory, with compensation actions that SysMARA validates for existence and type-correctness.
  • Every constraint is queryable. sysmara explain returns the policies and invariants for any capability. sysmara impact returns the blast radius of any change. No grep, no tribal knowledge, no hoping the docs are up to date.

Constraint Visibility is not a feature — it is the architecture. When every rule is a named node in a graph, AI agents can reason about the system the same way a senior engineer does: by knowing what they are not allowed to break.