tx

tx invariant

Machine-checkable rules extracted from design docs

Purpose

Invariants are machine-checkable rules extracted from design documents. They bridge the gap between documentation and enforcement — each invariant has a defined enforcement mechanism (integration test, linter, or LLM-as-judge) and an audit trail of check results.

Enforcement Types

TypeDescriptionExample
integration_testVerified by running a testtest/auth.test.ts
linterVerified by a lint ruletx/require-taskwithdeps-return
llm_as_judgeVerified by LLM evaluationprompts/check-auth.md

Invariant IDs

Invariants use a structured ID format: INV-[A-Z0-9-]+

Examples: INV-AUTH-001, INV-DB-SCHEMA-002, INV-API-RESPONSE-003

Audit Trail

Every invariant check is recorded with:

  • Whether it passed or failed
  • Optional details (error messages, test output)
  • Timestamp and duration

This creates an audit trail showing when invariants were last verified and their pass/fail history.

Usage

# List all invariants
tx invariant list
tx invariant list --subsystem auth
tx invariant list --enforcement integration_test

# Show invariant details
tx invariant show INV-AUTH-001

# Record a check result
tx invariant record INV-AUTH-001 --passed
tx invariant record INV-AUTH-001 --failed --details "bcrypt not used in signup"

# Sync invariants from YAML docs into DB
tx invariant sync
tx invariant sync --doc auth-design
import { DocService } from '@jamesaphoenix/tx-core'
import { Effect } from 'effect'

// List invariants
const invariants = yield* svc.listInvariants()
const authInvariants = yield* svc.listInvariants({ subsystem: 'auth' })
const testInvariants = yield* svc.listInvariants({ enforcement: 'integration_test' })

// Record a check
const check = yield* svc.recordInvariantCheck(
  'INV-AUTH-001',
  true,       // passed
  'All tests pass',  // details
  1200        // duration in ms
)

// Sync invariants from YAML
const synced = yield* svc.syncInvariants()       // all docs
const synced = yield* svc.syncInvariants('auth-design')  // specific doc

Tool name: tx_invariant_list

Arguments:

ArgTypeRequiredDescription
subsystemstringNoFilter by subsystem
enforcementstringNoFilter by enforcement type

Tool name: tx_invariant_show

ArgTypeRequiredDescription
idstringYesInvariant ID (e.g., INV-AUTH-001)

Tool name: tx_invariant_record

ArgTypeRequiredDescription
invariantIdstringYesInvariant ID
passedbooleanYesWhether the check passed
detailsstringNoCheck details or error message
durationMsnumberNoCheck duration in milliseconds

Tool name: tx_invariant_sync

ArgTypeRequiredDescription
docNamestringNoSync from specific doc (default: all)

Note: Dedicated invariant REST endpoints are not yet available. Invariant data is accessed through the docs API. Use the CLI or MCP interface for full invariant management (list, show, record, sync).

# Get the doc graph (includes invariant metadata)
curl http://localhost:3456/api/docs/graph

# Get a design doc (invariants defined in its YAML source)
curl http://localhost:3456/api/docs/auth-design

# List all design docs (which contain invariants)
curl "http://localhost:3456/api/docs?kind=design"

Defining Invariants in YAML

Invariants are defined in the invariants section of a design doc YAML:

kind: design
name: auth-design
title: Authentication Design

invariants:
  - id: INV-AUTH-001
    rule: Passwords must be hashed with bcrypt before storage
    enforcement: integration_test
    subsystem: auth
    test_ref: test/auth.test.ts

  - id: INV-AUTH-002
    rule: JWT tokens must expire within 15 minutes
    enforcement: integration_test
    subsystem: auth
    test_ref: test/jwt.test.ts

  - id: INV-AUTH-003
    rule: Login endpoints must be rate-limited
    enforcement: linter
    subsystem: auth
    lint_rule: security/rate-limit-required

  - id: INV-AUTH-004
    rule: Auth error messages must not reveal user existence
    enforcement: llm_as_judge
    subsystem: auth
    prompt_ref: prompts/check-auth-errors.md

Syncing Invariants

Running tx invariant sync reads the invariants array from each doc's YAML and upserts them into the database. Invariants that are no longer present in the YAML are marked as deprecated.

# Sync all docs
tx invariant sync

# Sync a specific doc
tx invariant sync --doc auth-design

Invariant Statuses

StatusDescription
activeCurrently enforced
deprecatedNo longer in YAML, kept for audit trail

On this page