v0.9 · preview
Concepts

Core concepts

Fibric is one operational layer that senses every system you run, reasons about what is happening, and acts safely. Nine concepts hold the whole thing together. Each one is small; together they are what lets an agentic model touch the physical world without ever going off the rails.

Event envelope

Everything that happens in Fibric travels as one canonical event envelope. A sensor reading, an incoming order, a model proposal, an executed action, all of them are envelopes with the same shape. A single canonical type is what lets the kernel route, govern, and audit anything without special-casing where it came from.

Two fields are mandatory on every envelope and every row it ever touches: reseller_id and tenant_id. They are not metadata; they are the spine of isolation. An envelope with no tenant cannot exist, which is why a placeholder can never quietly leak across the wall.

EventEnvelope
type EventEnvelope = {
  id: string;
  reseller_id: string;   // who resells the workspace
  tenant_id: string;     // the walled-off tenant, never optional
  kind: "observation" | "proposal" | "action" | "receipt";
  capability?: string;   // e.g. "orders.hold"
  payload: unknown;
  at: string;            // ISO-8601
};

Operators

An operator is a named AI worker that runs an operation. It has a goal in plain language, a set of capabilities it is allowed to use, and the three-phase shape of the loop: it senses through connectors, reasons with a base model, and proposes action. A ship-risk operator watches orders; a comfort operator tunes a building's light and air; a floor operator clears warehouse exceptions. The operator never acts directly, it only ever proposes.

Operators are themselves integrations. The kernel does not hardcode any one of them, you install operators from the Marketplace or define your own with the SDK, and they run on the same governed runtime as everything else.

Connectors & capabilities

A connector is how Fibric plugs into a real system, software like a help desk or an order system, or hardware like sensors, locks, and HVAC. Every connector is built on MCP, so software and hardware present the same interface to the kernel. No connector is special-cased; operators and connectors are the integrations.

A capability is what a connector can do, named by intent rather than by vendor: orders.read, orders.hold, access.unlock, hvac.setpoint. Operators request capabilities; configuration binds each capability to a connector. This is capability over connector indirection, and it is why swapping one vendor for another, say a help desk from Kustomer to Zendesk, is a config change, not a rewrite.

i
Why the indirection matters

An operator that asks for orders.hold keeps working when you change order systems, because the capability is the contract and the connector behind it is configuration. The operator never learns the vendor's name.

Sense, reason, act

Fibric runs one loop. Sense unifies real-time data from siloed systems into one operational picture. Reason is where agentic models understand what is happening, predict what is needed, and plan multi-step action, resolving conflicts before they occur. Act controls systems and dispatches teams, with no new hardware required, and leaves a receipt for every step.

Sense

Real-time data from every system, unified into one picture.

Reason

Understand, predict, and plan. Resolve conflicts up front.

Act

Control systems, dispatch teams, and leave a receipt.

The act step never reaches a system directly from the model. It always passes through the executor, which is where the next four concepts live.

Execution plans: propose and dispose

This is the single most important idea in Fibric. The model never acts. It produces a validated execution plan, a list of proposed actions stated as capabilities and arguments. A deterministic executor then disposes of that plan: it validates the shape, checks every action against your policy, and runs what survives, in order. The model proposes; the executor disposes.

Model

Proposes

Reasons over what was sensed and emits a validated plan of capabilities and arguments. Suggestive, never authoritative.

Executor

Disposes

Deterministic. Validates the plan, applies policy, enforces single-flight and idempotency, runs what is allowed, writes a receipt.

Because the dispose half is deterministic and the model cannot reach a system except through it, the boundary between "what the model wants" and "what actually happens" is a hard line, not a hope.

Trust policies: fail-closed

A trust policy is the rulebook the executor enforces while disposing. It is fail-closed: anything the policy does not explicitly allow is refused. A policy can veto any action before it ever happens, regardless of how confidently the model proposed it. You decide the allow list, the per-run limits, and the conditions; the executor decides nothing on its own.

Fail-closed is the default for a reason. An open-by-default system fails toward action; a fail-closed system fails toward inaction. When you are acting on the physical world, the safe failure is to do nothing.

!
Real data only is a policy too

Fibric refuses to act on data it cannot verify is real. A fallback value is tagged as such and can never be treated as a governed metric, so a placeholder can never trigger a real action.

Single-flight & idempotency

Two kernel primitives keep action safe under load. Single-flight per entity means at most one action is in flight for a given entity at a time, so two runs cannot both hold the same order or unlock the same door at once. Idempotency keys mean the same logical action applied twice has the effect of applying it once, retries are safe, duplicates collapse.

Together they make a runaway action structurally impossible. The classic failure mode, a loop that fires the same message over and over until it has sent six hundred and fifty-seven of them, cannot occur: single-flight serializes per entity, and the idempotency key makes the repeats no-ops.

idempotency key
ship-risk:SO-10884:hold
└── operator ──┘ └─ entity ─┘ └ action ┘
same key twice  →  applied once. retries collapse.

Receipts

Every action leaves a receipt: the immutable record of what was proposed, which policy rule decided it, the idempotency key, and the outcome. Receipts are what make Fibric explainable, you can always answer "what did it do, and why" after the fact, for any action, in any tenant.

A receipt is not a log line you hope was written. It is part of the action, the executor writes it as it disposes, and a policy can require a receipt before an action is considered complete. If you cannot account for an action, it did not happen.

receipt
{
  "receipt_id": "rc_5b21",
  "tenant_id": "t_8f2a…c901",
  "capability": "orders.hold",
  "proposed_by": "model",
  "policy": { "decision": "allow", "rule": "orders.hold" },
  "idempotency_key": "ship-risk:SO-10884:hold",
  "outcome": "applied"
}

Tenancy

Tenancy is provable isolation. Every envelope and every row carries reseller_id and tenant_id, and the data layer enforces that a query for one tenant can only ever see that tenant's rows. Isolation is not a convention the application remembers to follow; it is a property the storage layer guarantees, so nothing of yours touches anyone else's.

Tenancy is also why a real tenant renders only governed real data. The same wall that keeps tenants apart keeps seed and mock data out of a tenant that is supposed to see live numbers, the boundary is the spine of the whole system.

!
The nine, in one sentence

An operator senses through a connector by capability, reasons over an envelope, and proposes an execution plan that a deterministic executor disposes of under a fail-closed policy, with single-flight and idempotency making it safe, a receipt making it accountable, and tenancy keeping it walled off.

Keep going