/sɪs.prɒm/
A recursive, decision-driven model for recording where every part of a system came from, what decisions shaped it, and how it reached its current form.
# From npm (when published)
npm install -g sysprom
# From GitHub
npm install -g github:ExaDev/SysProM
# Or use without installing
npx sysprom --helpBoth sysprom and spm are available as commands — use sysprom for new projects.
# Convert between formats
sysprom json2md --input .SysProM.json --output ./.SysProM
sysprom md2json --input ./.SysProM --output output.SysProM.json
# Diagram and label options
The `graph` and `json2md` commands support options to control diagram layout and node label style used when generating Mermaid/DOT output.
Examples:
```sh
# Generate a Mermaid graph with friendly labels (default)
sysprom graph --path .SysProM.json --format mermaid
# Compact node labels (IDs only) instead of `ID: Name`
sysprom graph --path .SysProM.json --format mermaid --label-mode compact
# Embed diagrams when converting JSON → Markdown, using compact labels
sysprom json2md --input .SysProM.json --output ./.SysProM --embed-diagrams --label-mode compact
# Control layout direction for graph (LR, TD, RL, BT)
sysprom graph --path .SysProM.json --format mermaid --layout LRNotes:
--label-mode friendly|compactcontrols whether nodes showID: Name(friendly) or justID(compact).--layout LR|TD|RL|BTcontrols graph direction.json2mduses sensible per-diagram defaults (relationship/refinement/decision diagrams default toTD, dependency diagrams default toLR) but you can override when callinggraphdirectly.--label-mode friendly|compactcontrols whether nodes showID: Name(friendly) or justID(compact).--layout LR|TD|RL|BTcontrols graph direction.json2mduses sensible per-diagram defaults (relationship/refinement/decision diagrams default toTD, dependency diagrams default toLR) but you can override when callinggraphdirectly.json2mdsupports per-diagram layout overrides to control each embedded diagram independently:--relationship-layout LR|TD|RL|BT— override the layout used for the Relationship Graph.--refinement-layout LR|TD|RL|BT— override the layout used for the Refinement Chain.--decision-layout LR|TD|RL|BT— override the layout used for the Decision Map.--dependency-layout LR|TD|RL|BT— override the layout used for the Dependency Graph.
Examples:
# Embed diagrams in multi-doc output but make dependency graph top-to-bottom (TD)
sysprom json2md --input .SysProM.json --output ./.SysProM --embed-diagrams --dependency-layout TD
# Override relationship and refinement layouts independently
sysprom json2md --input .SysProM.json --output ./.SysProM --embed-diagrams --relationship-layout LR --refinement-layout TDsysprom validate sysprom stats
sysprom query nodes --type decision sysprom query node D1 sysprom query rels --from D1 sysprom query trace I1 sysprom query timeline sysprom query state-at
sysprom add invariant --name "New Rule" --description "Must hold"
sysprom add decision --name "Choose X"
--option "OPT-A:Use framework X" --option "OPT-B:Use framework Y"
--selected OPT-A --rationale "Lower migration effort"
sysprom remove INV23
sysprom update node D1 --status deprecated sysprom update add-rel D1 affects EL5 sysprom update remove-rel D1 affects EL5 sysprom update meta --fields version=2
sysprom infer completeness # Score node completeness (0-1) sysprom infer lifecycle # Infer lifecycle phases sysprom infer impact I1 # Trace impact from node sysprom infer derived # Compute transitive closure sysprom infer all # Run all analyses
All commands auto-detect the document — they search the current directory for `.SysProM.json`, `.SysProM.md`, or `.SysProM/` (in that priority order), then fall back to `.spm.json`, `.spm.md`, or `.spm/`. Use `--path` to specify an explicit path. Note: `spm` is an alias for `sysprom` for backwards compatibility.
## MCP Server
SysProM includes an MCP (Model Context Protocol) server exposing tools over stdio transport. Any MCP-compatible agent — Cursor, Windsurf, VS Code Copilot, Cline, or custom clients — can use it.
### Configuration
Add the following to your MCP client's configuration (e.g. `.cursor/mcp.json`, `.vscode/mcp.json`, `cline_mcp_settings.json`, or equivalent):
```json
{
"mcpServers": {
"sysprom": {
"command": "npx",
"args": ["-y", "sysprom", "mcp"]
}
}
}
Or via the CLI subcommand (equivalent):
sysprom mcp # starts the MCP server on stdio| Tool | Description |
|---|---|
validate |
Validate a SysProM document and return issues |
stats |
Return document statistics |
query-nodes |
Query nodes by type, status, or text |
query-node |
Retrieve a single node by ID |
query-relationships |
Query relationships by source, target, or type |
trace |
Trace refinement chains from a node |
add-node |
Add a new node to the document |
remove-node |
Remove a node by ID |
update-node |
Update fields on an existing node |
add-relationship |
Add a relationship between nodes |
remove-relationship |
Remove a relationship |
infer-completeness |
Score node completeness (0-1) based on refinement relationships |
infer-lifecycle |
Infer lifecycle phase from status and lifecycle fields |
infer-impact |
Trace impact propagation from a starting node |
infer-derived |
Compute transitive closure and inverse relationships |
All tools accept a path parameter to specify the SysProM document location.
import {
// Schema and types
sysproMDocument,
node,
nodeType,
relationshipType,
type SysProMDocument,
type Node,
type Relationship,
// Conversion
jsonToMarkdown,
jsonToMarkdownSingle,
jsonToMarkdownMultiDoc,
markdownToJson,
// Validation and query
validate,
stats,
queryNodes,
queryNode,
queryRelationships,
traceFromNode,
// Mutation
addNode,
removeNode,
updateNode,
addRelationship,
removeRelationship,
updateMetadata,
// Inference
inferCompletenessOp,
inferLifecycleOp,
inferImpactOp,
inferDerivedOp,
// File I/O
loadDocument,
saveDocument,
// Utilities
canonicalise,
toJSONSchema,
} from "sysprom";
// Validate
const doc = JSON.parse(fs.readFileSync(".SysProM.json", "utf8"));
const result = validate(doc);
console.log(result.valid, result.issues);
// Query
const decisions = queryNodes(doc, { type: "decision" });
const trace = traceFromNode(doc, "I1");
// Mutate
const updated = addNode(doc, {
id: "INV23",
type: "invariant",
name: "New Rule",
});
const withRel = addRelationship(updated, {
from: "D1",
to: "INV23",
type: "must_preserve",
});
// Type guards
if (sysproMDocument.is(data)) {
/* data is SysProMDocument */
}
if (node.is(thing)) {
/* thing is Node */
}SysProM models systems as directed graphs across abstraction layers — intent, concept, capability, structure, and realisation — with explicit decisions, changes, and invariants. It is domain-agnostic, format-agnostic, and recursively composable.
For product repositories, use SysProM to model the specification, design, and implementation of the system being built.
Recommended node usage:
intent: user outcomes, business goals, and product promisesconcept: domain concepts, behavioural boundaries, and system rulescapability: user-visible or externally meaningful system behaviourselement: architectural components, services, stores, queues, and UI surfacesrealisation: implementation units such as packages, modules, handlers, schemas, and jobsprotocol: workflows and lifecycle paths such as review, publish, sync, or ingestion flowsartefact: API contracts, documents, prompts, tests, migrations, and generated outputsdecision: selected trade-offs and architectural choiceschange: implementation slices or delivery unitsrole: human or system actorsview: curated slices such as specification, architecture, implementation, and operations
Recommended trace chain:
intent -> concept -> capability -> element -> realisation -> artefact
Recommended relationship usage:
refines: tighten intent into concepts and concepts into capabilitiespart_of: decompose concepts, protocols, capabilities, and architecture structuresrealises: connect design structures to implementation structuresproduces: connect capabilities or stages to the artefacts they generateperforms: connect roles to capabilities, stages, protocols, and operational conceptsgoverned_by/constrained_by: express rules, policies, and invariants on design and implementationimplements/modifies: connect delivery changes to the nodes they implement or alteraffects+must_preserve: connect decisions to impacted areas and their protected invariants
Recommended implementation provenance:
- use
external_referencesonrealisationnodes to point to code paths, packages, handlers, or schemas - use
external_referencesonartefactnodes to point to API definitions, test files, migrations, docs, PRs, and generated outputs - use
status,scope, and decision/change links so the graph can answer both “what is the design?” and “what has actually been built?”
| System | Format | Structure | Decisions | Time | Analysis | Workflow | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Readable | Parseable | State | Nesting | Diagrams | Rationale | Constraints | History | Temporal | Inference | Impact | Scaffolding | Planning | Tracking | |
| MBSE (SysML) | 🔶 | ✅ | ✅ | ✅ | ✅ | 🔶 | ✅ | 🔶 | ✅ | |||||
| Knowledge Graphs | ✅ | ✅ | ✅ | 🔶 | 🔶 | ✅ | ||||||||
| EA (ArchiMate) | ✅ | 🔶 | ✅ | 🔶 | ✅ | 🔶 | ✅ | |||||||
| Git | 🔶 | ✅ | ✅ | ✅ | ✅ | 🔶 | ||||||||
| Event Sourcing | ✅ | 🔶 | 🔶 | ✅ | ✅ | |||||||||
| DDD | ✅ | ✅ | 🔶 | 🔶 | ||||||||||
| C4 | ✅ | ✅ | 🔶 | ✅ | ||||||||||
| Traceability Matrices | ✅ | ✅ | 🔶 | 🔶 | 🔶 | |||||||||
| PRD | ✅ | 🔶 | 🔶 | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | ✅ | 🔶 | ||||
| ADR | ✅ | ✅ | 🔶 | |||||||||||
| RFC Processes | ✅ | ✅ | 🔶 | 🔶 | 🔶 | |||||||||
| BDD (Gherkin) | ✅ | ✅ | 🔶 | 🔶 | ✅ | 🔶 | 🔶 | ✅ | ||||||
| Spec Kit | ✅ | ✅ | 🔶 | 🔶 | 🔶 | ✅ | ✅ | ✅ | ||||||
| Ralplan | ✅ | 🔶 | ✅ | 🔶 | ✅ | 🔶 | ||||||||
| GSD | ✅ | 🔶 | 🔶 | |||||||||||
| GSD-2 | ✅ | 🔶 | ✅ | ✅ | 🔶 | 🔶 | ✅ | 🔶 | ✅ | ✅ | ✅ | |||
| Taskmaster | ✅ | ✅ | ✅ | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | ✅ | |||
| OpenSpec | ✅ | 🔶 | ✅ | 🔶 | ✅ | ✅ | ✅ | ✅ | ✅ | |||||
| Kiro | ✅ | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | ✅ | ✅ | |||
| cc-sdd | ✅ | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | ✅ | ✅ | |||
| Ouroboros | ✅ | 🔶 | ✅ | ✅ | ✅ | 🔶 | ✅ | 🔶 | 🔶 | ✅ | 🔶 | |||
| Spec Kitty | ✅ | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | ✅ | ✅ | |||
| Shotgun | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | 🔶 | |||||
| Superpowers | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | 🔶 | ✅ | 🔶 | ✅ | ✅ | ✅ | ||
| SysProM | ✅ | ✅ | ✅ | ✅ | 🔶 | ✅ | ✅ | ✅ | ✅ | ✅ | 🔶 | ✅ | ✅ | ✅ |
✅ = first-class support. 🔶 = partial or implicit.
Nodes — typed entities (intent, concept, capability, element, realisation, invariant, principle, policy, protocol, stage, role, gate, mode, artefact, decision, change, view)
Relationships — typed directed edges (refines, realises, implements, depends_on, affects, supersedes, must_preserve, and 17 others)
Invariants — rules that must hold across all valid system states
Decisions — choices between alternatives, with context, options, rationale, and must_preserve links to invariants (required when affecting domain nodes)
Changes — modifications to the system, linked to decisions, with scope, operations, and lifecycle tracking
Subsystems — any node can contain a nested SysProM graph, using the same structure recursively
SysProM is format-agnostic. This repository includes:
- JSON — validated against
schema.json, supports recursive subsystems - Markdown — single file (
.SysProM.md), multi-document folder, or recursive nested folders with automatic grouping by type
Round-trip conversion between JSON and Markdown is supported with zero information loss.
pnpm build # Typecheck + compile + schema + docs (cached via Turbo)
pnpm typecheck # Type-check only
pnpm compile # Compile to dist/
pnpm test # Typecheck + run all tests
pnpm test:coverage # Tests with coverage report
pnpm docs # Generate API + CLI markdown docs
pnpm docs:html # Generate HTML site for GitHub Pages
pnpm docs:serve # Live-reload HTML docs during development
pnpm spm <command> # Run the CLI from source (e.g. pnpm spm validate ...).SysProM.json is SysProM describing itself — the specification, its decisions, invariants, changes, and worked examples are all encoded as a SysProM document. The ./.SysProM/ folder contains the same content as human-readable Markdown.
All significant activity — decisions, changes, new capabilities, and invariants — should be recorded in the self-describing document. Updates can be made either by editing the Markdown files in ./.SysProM/ directly or by using the CLI:
# Add a decision via the CLI
sysprom add decision --id D23 --name "My Decision" --context "Why this was needed"
# Or edit ./.SysProM/DECISIONS.md directly, then sync
sysprom md2json --input ./.SysProM --output .SysProM.jsonKeep both representations in sync after any change:
# JSON → Markdown
sysprom json2md --input .SysProM.json --output ./.SysProM
# Markdown → JSON
sysprom md2json --input ./.SysProM --output .SysProM.jsonImportant: Always keep
.SysProM.jsonand./.SysProM/up to date with current activity and in sync with each other. Record all decisions, changes, and new capabilities as they happen. After any change to either representation, run the appropriate conversion command above. Validate withsysprom validatebefore committing.
SysProM is available as a Claude Code plugin with skills for managing provenance documents. The plugin is defined in .claude-plugin/marketplace.json with skills in .claude/skills/.
# Add the SysProM marketplace
/plugin marketplace add ExaDev/SysProM
# Install the plugin
/plugin install sysprom@syspromSkills are namespaced when installed as a plugin (e.g. /sysprom:add-decision, /sysprom:query-nodes).
When working on the SysProM repo itself, skills in .claude/skills/ are auto-discovered without plugin installation. Skills use short names (e.g. /add-decision, /query-nodes).
Node Creation
add-decision— Create decision nodes with context, options, rationale, and invariant linksadd-change— Create change nodes with scope, operations, and task trackingadd-invariant— Create invariant nodes representing system rules and constraintsadd-node— Generic node creation for any SysProM type
Node Modification
update-node— Modify node fields, status, lifecycle, context, or rationaleremove-node— Delete nodes with safety flags (hard delete, recursive, repair)rename-node— Rename node IDs across all references
Relationships
add-relationship— Create relationships between nodes with specific typesremove-relationship— Delete relationships
Query & Analysis
query-nodes— Search nodes by type, status, text, or IDquery-relationships— Query relationships by source, target, or typetrace-node— Trace refinement chains through abstraction layerscheck-document— Validate document structure and report issuesstats— Show document statistics and composition metrics
Visualisation
graph— Generate Mermaid or DOT graphs with filtering
Format Conversion
init-document— Create new SysProM documents with metadatajson-to-markdown— Convert JSON to Markdown formatmarkdown-to-json— Convert Markdown to JSON formatsync-formats— Bidirectional sync between JSON and Markdown
Spec-Kit Integration
speckit-import— Import Spec-Kit features as SysProM nodesspeckit-export— Export SysProM nodes to Spec-Kit formatspeckit-sync— Bidirectional sync with Spec-Kit specificationsspeckit-diff— Show differences between SysProM and Spec-Kit
Task Management
task-list— List tasks in a change node with progresstask-add— Add tasks to a changetask-mark-done— Mark tasks as complete
Plan Management
plan-init— Initialise plans with phases and gatesplan-status— Show plan progress and phase gates
If spm is not globally installed, skills automatically fall back to npx -y sysprom for command execution. All skills work with either global or per-project installation.