FabricFabricPlatform
Platform referenceReference

Module manifest

Export a stable, JSON-serializable, versioned manifest of a FabricModule's ontology for downstream tooling.

The @fabricorg/platform/manifest subpath exports a FabricModule's ontology — object types, subject types, id prefixes, event types, actions, policies, state machines, views, and capability metadata — as a stable, JSON-serializable, versioned data structure. Downstream tooling can consume it without loading live module code or a database client.

This export is a public definition seam, not a generator. Manifest v2 includes typed entity definitions, logical view contracts, and declared capability metadata. Archetype conformance and compiler/generator targets ship as separate packages so Platform remains archetype-agnostic and runtime-portable.

Exporting a manifest

import { exportModuleManifest, exportModuleManifestBundle } from "@fabricorg/platform/manifest";

const manifest = exportModuleManifest(myModule);
const json = JSON.stringify(manifest, null, 2);

// Or export several modules at once, preserving input order:
const bundle = exportModuleManifestBundle([coreModule, billingModule]);

exportModuleManifest is a pure function of the module object. It does not read or mutate the platform registries, and the module does not need to be registered first.

Contract guarantees

  • Versioned. Every manifest carries manifestVersion (currently 2, exported as MODULE_MANIFEST_VERSION). Consumers should check it before interpreting the payload. A v2 reader can use normalizeModuleManifest to accept v1; down-conversion is not promised.
  • Deterministic. Declaration order is preserved everywhere — nothing is sorted alphabetically — so the same module object always produces byte-identical JSON. Safe for content hashing and diffing.
  • Definitions only. The manifest never contains raw parameter values, secrets, or runtime data. Function fields are elided: action handler, policy evaluate, adapter getInput, and dynamic targetState functions are dropped; transition guards serialize as hasGuard: true.
  • Normalized registrations. String and object registration inputs normalize to one shape. For example, objectTypes: ["Shipment"] becomes [{ type: "Shipment" }], and a bare event-type string becomes { eventType, schemaVersion: 1 }.

Actions and parameter schemas

Each action serializes its static metadata: actionId, version, kind ("atomic" or "saga"), idempotent, mutatesDomain, emitsEvents, policies, requiredRoles, requiredPermissions, eventPhase, state-machine binding, and adapter steps (with retry policy).

SchemaValidator is not inherently serializable, so parameter schemas are opt-in. If a validator also exposes toJSONSchema() — as Zod 4 schemas do via z.toJSONSchema — the manifest includes parameterSchema and parameterSchemaFormat: "json-schema":

import { isJsonSchemaExportableValidator } from "@fabricorg/platform/manifest";

if (isJsonSchemaExportableValidator(action.schema)) {
  // action.schema.toJSONSchema() will be called during export
}

Validators without toJSONSchema simply omit both fields.

Views may also carry a portable parameterSchema in the manifest. Unlike action validators, this is a JSON Schema contract consumed by ProjectionHost at query time; its values are never embedded in the manifest's snapshot or audit records.

parameterSchema describes action input only. It does not validate handler database writes and does not imply that an arbitrary application TDb persists records matching an object schema.

Actions may also declare resultSchema. The Host validates public result data immediately after the handler and before event append or adapter execution. Failure records a sanitized invocation failure, emits no domain/completion event, and invokes no adapter. Domain writes roll back only when the Host store transaction provider includes them.

Typed object definitions

Object registrations can include schema, namespaced semantics, qualified relations, and enforcement-owned invariants. These fields are copied into the manifest as definitions-only JSON. See typed object definitions and manifest compatibility.

Policies

Policies serialize as a discriminated union:

  • Code evaluators become { type: "code", policyId, version, previewSafe? } — the evaluate function is never serialized.
  • Declarative data/runtime policy definitions become { type: "data", policyId, policyVersion, kind, dataDefinition?, codeEvaluatorPolicyId?, fallback? } — the declarative content flows through as data.

State machines

State machines serialize as { entityType, states, transitions }, where states is an array in declaration order (Object.values order of the definition record) and each transition is { from, to, causedByAction, hasGuard }.

On this page