TechFabricTechFabricPlatform
Getting started

Mental model

The seven concepts you need to hold in your head — and how they fit together.

If you can hold these seven concepts, you can read any other page on this site.

1. Action

A verb that mutates domain state. Identified by a stable <namespace>.<verb> ID like orders.submit. Registered as an ActionDefinition carrying its schema, policies, state-machine binding, and adapter steps. Actions are the only legal mutation path — no direct DB writes from API procedures or UI code.

2. Action invocation

A single attempt to run an action, recorded as an ActionInvocation row at the moment invokeAction is called. Carries the actor, parameters, status (pending → terminal), and a correlation ID. Every attempt — successful, failed, blocked, validation-failed — has a row. Audit is not opt-in.

3. Event (AssetEvent)

An immutable past-tense fact emitted by a governed action. Identified by eventType (PlanAccepted), tied to a subject (subjectType + subjectId), and carrying a typed payload. Events are canonical evidence and read models are derivations. Atomic domain-write/event persistence is an optional Host capability: it requires transactionWithEvents and a transaction provider bound to the same database transaction; legacy stores cannot claim it.

4. Policy

A predicate evaluated before the handler runs, returning pass, warn, or block. Three kinds: code (a TS evaluator), data (a declarative condition tree), or hybrid (data with code fallback). Each policy decision carries dispatchEvidence recording exactly which path was taken. Identified by <id>.v<integer> — the version is part of the ID.

5. State machine

A transition graph for a stateful entity. States carry a StateClass (initial, active, action_required, waiting, terminal, exception). Transitions are (from, to, causedByAction) tuples — the action that causes the transition is part of the rule. Validated by the runtime before atomic handlers run.

6. Module (FabricModule)

A module declaration describing a vertical's ontology: namespace, object types, event types, actions, policies, state machines, and related governance metadata. It is validated and registered at app startup. The separate exportModuleManifest function produces a deterministic, versioned, definitions-only JSON manifest for downstream tools without registering the module. Verticals declare modules; the host app composes them. There is no auto-discovery and no implicit registration.

7. Projection

A derived view built by replaying the event log through a reducer. Replay is deterministic: same events → same state. Projections may be persisted (read models, search indexes) or computed on demand. They never write back into the event log; corrections are new events.

How they connect

invokes creates gated by transitions emits registered in replayed by registers registers registers Actor Action ActionInvocation row Policy StateMachine Event Module Projection

Words you'll see — and what they mean here

WordMeans in Fabric
SubjectThe entity an event is about (subjectType = Plan, subjectId = the ID).
ActorWho/what caused the action — see the six ActorType values.
Correlation IDStable identifier across all events of a related invocation chain.
Causation IDThe immediate parent invocation — forms a tree for sagas.
SagaA multi-step orchestration declared as a single action with kind: "saga".
AdapterA retry/circuit-breaker-wrapped call to an external system, declared as an AdapterStep on an action.
Evidence packetA curated bundle of references handed to compliance (e.g. "the consent + the credit pull").

What it is not

  • Not a CRUD framework. There is no scaffolding that generates Create/Read/Update/Delete endpoints from a schema.
  • Not a workflow engine itself. Saga contracts, including SagaContext.awaitSignal, remain runtime-neutral. Applications may use the separately versioned @fabricorg/platform-temporal binding for governed activities and signals; Temporal remains the orchestration authority.
  • Not a UI framework. The SaaS app uses Next.js + shadcn; the platform doesn't care.

Next

On this page