Schematics
← The library family

Relationships as data

@schema-reflection/algebra

Published · 0.1.0

Know what points at what.

A string can name a thing, or point at a thing. Your schema should know the difference. Teach it once, and every consumer can ask the same relationship questions.

01 Why it matters

Why it matters

A schema can prove that actionIds is an array of strings while every string in it names an action that no longer exists. Shape validation and relationship validation answer different questions. Once records reference one another, a structurally valid document can still describe a broken system.

The usual fix is another loop in a validator, another index in an editor, and another list of special cases in an agent tool. Those implementations drift. Algebra puts identity and reference meaning beside the fields that carry it, then extracts one graph from the schema and the data. A CLI, a browser, and a server can all inspect that graph without owning separate relationship rules.

02 What it unlocks

What it unlocks

Catch the broken link before the deploy

Report duplicate definitions and unresolved references with structured paths. A config review can point to the exact workflow entry that still names a deleted action, instead of waiting for that workflow to run.

Give your tools a shared map

Use the graph's definitions and references to build navigation, candidate lists, and impact views. Algebra supplies the semantic facts; your editor or agent supplies the UI and edit operations.

Keep identity local to the domain

Scoped identities let a name mean something inside its parent rather than forcing every form field or nested resource into one global namespace. References can resolve in the appropriate scope.

03 How to use it

How to use it

Start with one document type that contains ids and references. Add relation checks to its existing validator, then reuse the graph in the next tool that needs it. Algebra stands alone; the other family packages are optional.

  1. Annotate the fields that carry meaning

    Use Relation.id for definitions, Relation.ref for one reference, and Relation.refs for a list. Give each entity type a stable name. Keep ordinary shape constraints in Effect Schema.

  2. Decode first, then check the relationships

    Validate the incoming value with your schema, then pass the decoded root to Relation.validate. Pass it to Relation.graph when a consumer needs the underlying definitions and references.

  3. Put the same check at each boundary

    Run it in CI, before accepting an edit, or before planning a deployment. Map diagnostic paths to your own file positions or UI fields; the library does not own your files or rendering.

Published · 0.1.0pnpm add @schema-reflection/algebra@0.1.0View the npm release ↗

The published 0.1.0 release declares Effect 4.0.0-beta.68. Schematics tests that release with its RC.112 pin and an explicit peer override; check compatibility for your own application.

workspace.tsnpm API
import { Schema } from "effect"
import { Relation } from "@schema-reflection/algebra"

const Action = Schema.Struct({
  id: Relation.id("Action"),
  label: Schema.String,
})

const Workflow = Schema.Struct({
  id: Relation.id("Workflow"),
  actionIds: Relation.refs("Action"),
})

const Workspace = Schema.Struct({
  actions: Schema.Array(Action),
  workflows: Schema.Array(Workflow),
})

Relation.validate(Workspace, config)
// → [{ code: "unresolved-ref", path: [...], message: ... }]
▶ try itsimulated in your browser

Interactive simulation loads when this panel comes into view.

The interactive panel is a Foldkit/Foldworks simulation of the behavior, not an execution of this package. The definition above is an API excerpt; supply your application's domain values and contracts.

04 In practice

In practice

Deleting an action becomes a reviewable change.

An onboarding configuration has reusable actions and several workflows. A cleanup removes notify-manager, but two workflows still reference it.

  1. Describe

    Mark each action's id as an Action definition and each workflow's actionIds as Action references.

  2. Inspect

    Extract the graph for the proposed configuration. The two remaining references are still visible even though their target disappeared.

  3. Decide

    Show both diagnostics before accepting the change. The author can restore the action or update the workflows deliberately.

05 How it composes

How it composes

Each library owns one kind of meaning. Combine the ones your application needs, with an explicit boundary between their jobs.

  • algebra + predicates

    Relationships say which records are connected; predicates decide whether a domain condition holds. A host can expose graph facts to its leaf interpreter, such as whether an action is referenced. That integration is application code.

  • algebra + logic

    Check a candidate configuration around an action that changes it. Logic describes the behavior, while algebra detects broken relationships in the resulting values. Graph validation does not automatically wrap action execution.

  • algebra + workflow

    A host can annotate named process definitions and action references to review their connections before dispatch. Workflow still owns progress through time; algebra does not schedule or resume work.

  • algebra + core

    Share domain shapes where the portable subset allows it, but keep relation declarations explicit: MetaSchema does not promise to preserve algebra annotations. A portable shape alone is not a relationship graph.

  • algebra + filesystem

    The proposed filesystem layer would route and decode documents, then combine their identities and references into a cross-file graph. That integration is planned; algebra already works over values supplied by your own loader.

These are application composition patterns, not a promise of automatic adapters. Align Effect peers and artifact formats before combining runtimes; source prototypes can differ from published releases.

See the family's approval scenario →

06 Where it stops

Where it stops

A graph is not a refactoring engine

Relation metadata, extraction, and validation are implemented. Automatic rename, schema-aware patches, migrations, and broader algebra operations remain separate tooling or roadmap work.

The host decides what to accept

Algebra reports facts about a value. It does not commit files, change database rows, or choose whether a diagnostic blocks a deployment. Keep those decisions in your application's boundary.

All libraries are pre-1.0. Pin exact versions and plan for changes to APIs and artifact formats.

Continue with the piece next to it

One library at a time.

Try the Schematics playground →