# wity-system Headless spatial/topological network computation and temporal simulation. Type-driven propagation, cascade, impact, pathfinding, scenario state, regions, playback, spatial projection, and frequency-based simulation runtime over wity-graph. Zero DOM. Zero framework. Isomorphic. Stored as . Current version: 0.15.0 Docs: https://www.wity.ai/stack/system-graph/ ## Architecture ``` system-core -- SystemGraph, TypeRegistry, cascade, impact, serialize, parse, setGraphProvider. (wity-system) Peer dependency: @wity/graph-headless. Zero DOM. Isomorphic. Stack-agnostic. system-formalisms -- The formalisms an aspect of a system can be made in, each declared as data (process), with its own analyses, and describe() — a formalism in words. Headless. Published as @wity-ai/system-formalisms. system-sim -- SimulationRuntime, FeatureStore, SimClock, InfluenceEngine, HistoryBuffer. Temporal simulation runtime over system-core. Frequency-based features, topological influence, event detection. Declarative dynamics: behaviour as data (compileDynamics, buildRuntime). system-ui-compute -- computeScene (a system resolved to a render scene), computeAspectScene (one aspect of it, as the same scene) and the signal strip views (wavesView, heatView). Zero DOM. Published as @wity-ai/system-ui-compute. system-ui -- : draws what system-ui-compute returns. Muffin component. Published as @wity-ai/system-ui. ``` Level 2 domain library in the Wity ecosystem (same level as wity-workbook, wity-ideation, wity-rkf). Monorepo: system-core (structural authoring, and the mechanism of aspects), system-formalisms (the kinds of model an aspect can be), system-sim (temporal dynamics), system-ui-compute and system-ui (showing a system). Composes over @wity/graph-headless (Level 1). Core model: SystemGraph wraps a GraphAbstract internally — one graph. Assets are typed nodes, connections are typed edges: the system's STRUCTURE. TypeRegistry declares behavioral traits that algorithms consume automatically. Beside the structure a system can hold ASPECTS: further models of the same system in the same graph (the order process of a shop). The kind of model an aspect is — its FORMALISM — is declared as data and handed to the system; system-core names none. ## Quick start ```js import { GraphAbstract } from '@wity/graph-headless'; import { SystemGraph } from 'wity-system'; const sys = new SystemGraph({ GraphAbstract }); sys.registerAssetType('plant', { role: 'source', canFail: true, coordFields: ['lat', 'lon'], }); sys.registerConnectionType('feeds', { carriesFlow: true, costField: 'length', }); sys.addAsset('WTP', 'plant', { lat: -19.25, lon: 146.80 }); sys.addAsset('V1', 'valve', {}); sys.addAsset('H1', 'house', {}); sys.addConnection('WTP', 'V1', 'feeds', { length: 500 }); sys.addConnection('V1', 'H1', 'feeds', { length: 120 }); sys.cascade(['V1']); // → { reachable: ['WTP'], cutOff: ['H1'], disabled: ['V1'] } sys.shortestPath('WTP', 'H1'); // → { path: ['WTP', 'V1', 'H1'], cost: 620 } ``` ## Type registry Asset type traits: `role` (source|sink|relay), `canFail`, `cascadeOnFailure`, `coordFields`, `meta` (open bag). Connection type traits: `directionality`, `carriesFlow`, `defaultCost`, `costField`, `meta` (open bag). When types are registered, algorithms auto-read traits. Explicit options always override. ## Algorithms - **propagate(fromUid, options?)** — BFS traversal, direction/edgeTypes/maxDepth - **cascade(disabledUids, options?)** — cut-off analysis from sources; auto-detects sources and flow edges - **impact(uid, options?)** — upstream + downstream analysis - **reachable(fromUid, options?)** — list all reachable nodes - **shortestPath(fromUid, toUid, options?)** — Dijkstra with trait-driven cost - **allPaths(fromUid, toUid, options?)** — DFS enumeration with depth limit ## Aspects and formalisms - **structure** — the assets and connections: what the system is made of. - **aspect** — one more model of the same system, in the same graph: `{ id, formalism, label?, members, lines }`. - **formalism** — the kind of model an aspect is, declared as data: its kinds of member and of line, its rules, what a member may name (a link), its analyses. - **member** / **line** — a node of an aspect / an edge between two of its members. **member type** — a kind of member a system declares for itself, in one formalism. ```js import { formalisms } from 'wity-system/formalisms'; const sys = new SystemGraph({ GraphAbstract, formalisms }); sys.addAsset('warehouse', 'team', {}); sys.setAspect({ id: 'order', formalism: 'process', members: [{ id: 's', kind: 'start' }, { id: 'pack', kind: 'task', performedBy: 'warehouse', minutes: 10 }, { id: 'e', kind: 'end' }], lines: [{ from: 's', to: 'pack' }, { from: 'pack', to: 'e' }] }); sys.checkAspect('order'); // [] — or what breaks a rule: [{ rule, member?, line?, message }] sys.shortestPath('s', 'e', { in: 'order', costField: 'minutes' }); // { path: ['s', 'pack', 'e'], cost: 10 } — the same analyses that answer for assets, run over the aspect sys.membersLinkedTo('warehouse'); // [{ aspect: 'order', member: 'pack', link: 'performed-by' }] ``` A value that is not an aspect in shape is refused (`setAspect` throws); one that breaks a rule is kept as a draft and `checkAspect` says what breaks. One member or line at a time: `setAspectMember`, `removeAspectMember`, `setAspectLine`, `removeAspectLine`. The structure — assets, connections, every analysis, regions, scenarios, the simulator — is unaffected by aspects. Stored under `aspects` in the snapshot, only when there are some; what 0.13 (`activities`) and 0.14 (`occurants`, `stepTypes`) stored is read as aspects of `process`. The formalisms (generated from their declarations): ``` Process (formalism 'process') use it for: Things that happen in an order — a procedure, a workflow, a flowchart, a checklist with decisions in it. not for: Parts that exist and connect (that is the map's assets and connections), or how a number changes over time (a behaviour). members: steps — start (where the process begins; flows in 0, out 1) · end (where it finishes; flows in 1 or more, out 0) · task (a piece of work; flows in 1 or more, out 1) · branch (one way out is taken — each flow out says its case in its label; flows in 1 or more, out 2 or more) · split (every way out is taken, side by side; flows in 1 or more, out 2 or more) · join (waits for all the ways in, then goes on; flows in 2 or more, out 1) lines: flows — then (`from` happens, then `to`) links: performedBy (the uid of the asset that does the step — the steps one asset does are its lane) a member type is a task unless it says another kind checked: A process begins at one start; A process finishes at an end; Each way out of a branch says the case it is taken in, and no two say the same; A step is performed by an asset of the system; Every step can be reached from the start; From every step, an end can be reached analyses: lanes (who performs which steps, and where the work changes hands) State machine (formalism 'state-machine') use it for: The conditions one thing can be in and the events that move it between them — an order (placed, paid, shipped), a connection, a door, a document under review. not for: Work done in an order by several parts (that is a process), or a choice someone must make (a decision). members: states — initial (where it starts — a marker, with one transition to the first state; transitions in 0, out 1) · state (a condition it stays in until an event takes it elsewhere; transitions in any, out any) · final (where it ends — nothing leaves it; transitions in any, out 0) lines: transitions — transition (on the event in `label`, `from` gives way to `to` (`guard`: a condition that must also hold)) a member type is a state unless it says another kind checked: A state machine starts at one initial marker; Each transition out of a state says the event it is taken on, and no two out of one state say the same; Every state can be reached from the initial marker Petri net (formalism 'petri-net') use it for: Things that are used up and made, or shared and waited for — stock and orders, machines and jobs, a protocol where two sides must both be ready. not for: A plain order of steps with no counting of what is available (that is a process). members: nodes — place (holds tokens — a stock, a free machine, a waiting order (`tokens`: how many it starts with); arcs in any, out any) · transition (something that happens when every place leading into it has enough tokens; arcs in any, out any) lines: arcs — arc (from a place to a transition (it takes tokens) or from a transition to a place (it gives them); `weight`: how many) a member type is a place unless it says another kind checked: A Petri net has at least one place; A Petri net has at least one transition; Each arc joins the kinds it may: arc place → transition or transition → place; No node is cut off from the rest Behaviour tree (formalism 'behaviour-tree') use it for: How an agent — a robot, a game character, an automated responder — picks what to do next from what is true right now: priorities, fallbacks, checks before acting. not for: A fixed order of steps (that is a process), or the conditions a thing can be in (a state machine). members: nodes — sequence (does its children in order; fails at the first that fails; links in 0 to 1, out 1 or more) · selector (tries its children in order; succeeds at the first that succeeds; links in 0 to 1, out 1 or more) · parallel (does all its children; succeeds when all succeed; links in 0 to 1, out 1 or more) · inverter (one child; succeeds when it fails and fails when it succeeds; links in 0 to 1, out 1) · repeat (one child, done again (`times`: how many; forever when not said); links in 0 to 1, out 1) · action (a leaf: something done; links in 0 to 1, out 0) · condition (a leaf: something checked — true or false; links in 0 to 1, out 0) lines: links — child (`to` is a child of `from`; a node's children are tried in the order of its lines) a member type is a action unless it says another kind checked: It is a tree: each node has at most one parent, and none leads back to itself; It is one tree: no node is cut off from the rest Syntax tree (formalism 'syntax-tree') use it for: The structure of something written — a formula, a line of code, a query, a sentence — shown as parts within parts. not for: Choosing what to do (a behaviour tree), or steps in an order (a process). members: nodes — of any kind you name lines: links — child (`to` is a part of `from`; parts are in the order of the lines, and `label` may say what part it is) checked: It is a tree: each node has at most one parent, and none leads back to itself; It is one tree: no node is cut off from the rest ``` ## Scenarios Named graph + viewport + regions snapshots. Save, load, diff, delete. Deep-cloned. ## Regions Polygon spatial annotations. Point-in-polygon containment queries: `getAssetsInRegion`, `getRegionsOfAsset`. Included in scenario snapshots. ## Playback Ordered step sequences for presentation. Open-ended step types interpreted by L3. Selector resolution: region, assetType, path, uids, all, union. ## Serialization Documents serialize as `` via graph-headless. Inject once: `setGraphProvider(graph)`. ## Simulation (system-sim) SimulationRuntime overlays temporal dynamics onto an authored SystemGraph: - **FeatureStore** — columnar Float64Array storage, one array per feature per asset type - **Generators** — pure functions (currentValue, simTime, dt, asset) => newValue, scheduled by frequency - **Influence** — connection-type rules propagated in topological order (multi-hop in one tick) - **Events** — condition predicates over asset state, with per-asset cooldown - **History** — opt-in ring-buffer time-series per feature ```js import { SimulationRuntime } from 'wity-system/sim'; const sim = new SimulationRuntime(sys, { speed: 10, tickRate: 100 }); sim.defineFeatures('router', [ { id: 'cpu-load', frequency: 5000, range: [0, 100], unit: '%' }, ]); sim.setGenerator('router', 'cpu-load', (v, t, dt) => v + (Math.random() - 0.5) * 10); sim.defineInfluence('data-link', [ { source: 'cpu-load', target: 'cpu-load', fn: (src, tgt) => tgt + src * 0.1 }, ]); sim.defineEvent('overload', { condition: (state) => state['cpu-load'] > 90, cooldown: 30000, }); sim.on('event', ({ id, uid, simTime }) => console.log(`${id} on ${uid} at ${simTime}`)); sim.start(); ``` Declarative dynamics — behaviour as data; the features come from the system's asset types: ```js import { buildRuntime } from 'wity-system/sim'; const sim = buildRuntime(sys, { generators: { 'router:cpu-load': { kind: 'randomWalk', step: 6 } }, influence: { 'data-link': [{ source: 'cpu-load', target: 'cpu-load', kind: 'proportional', gain: 0.1 }] }, events: { overload: { kind: 'threshold', feature: 'cpu-load', op: '>', value: 90, cooldown: 30000 } }, }); sim.start(); ``` `simulate(sys, spec, { durationMs })` runs a behaviour headless and reports the events that fired and each signal against its threshold. The system holds its behaviours (`sys.setDynamicsSpec(spec)`, `getDynamics()`), saved with it. Generator kinds: constant, sine, randomWalk, noise, ramp, pulse (a bump between two moments), sum (composite), byAsset (a generator per asset uid). Influence kinds: proportional, additive, decay, max, replace. Event kinds: threshold, range, whenMode (a named predicate over features). --- ## Documentation pages ### Guides - [Overview](/guide/overview) -- architecture, core model, L2 positioning, monorepo structure, snapshot format - [Type Registry](/guide/type-registry) -- asset/connection types, behavioral traits, meta field - [Algorithms](/guide/algorithms) -- propagation, cascade, impact, pathfinding - [Scenarios](/guide/scenarios) -- scenarios, regions, playback, spatial projection, serialization - [Aspects and formalisms](/guide/aspects) -- further models of a system beside its structure; declaring a formalism; the rules; how an aspect is stored ### API Reference - [system-core](/packages/system) -- SystemGraph, TypeRegistry, cascade, impact, serialize, parse, setGraphProvider - [system-formalisms](/packages/formalisms) -- formalisms, process, lanes, describe - [system-sim](/packages/sim) -- SimulationRuntime, FeatureStore, SimClock, InfluenceEngine, HistoryBuffer, declarative dynamics - [system-ui-compute & system-ui](/packages/ui) -- computeScene, computeAspectScene, signal strip views,