fibric Docs fibric.io →
Reference preview
Reference preview

These pages describe Fibric’s target architecture. Public CLI, API, SDK, and sandbox access are not available. Examples do not establish deployed capabilities.

Concepts

Governance & trust

The reference execution path validates proposed plans against deterministic policy. Per-entity coordination and idempotency controls limit concurrent or repeated attempts. Tenant context and action records remain part of the request.

#Planning and execution

This is the single most important idea in the platform, and governance is built directly on top of it. The model never acts. It produces a validated ExecutionPlan, 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, enforces single-flight and idempotency, runs what survives in order, and writes a receipt for each step.

Model

Proposes

Reasons over what was sensed and emits a validated plan of capabilities and arguments. Suggestive, never authoritative. The model is allowed to want things.

Executor

Disposes

Deterministic. Validates the plan, applies policy, enforces single-flight and idempotency, runs what is allowed, writes a receipt. The executor is the only thing allowed to do things.

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. Everything else on this page is what that line is made of.

#Fail-closed trust policies

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, no matter how confidently the model proposed it. You write the allow list, the per-run limits, and the conditions; the executor decides nothing on its own.

Explicitly allowed

The capability is on the allow list, its arguments pass, and any conditions and limits are satisfied. The action runs, and a receipt records which rule allowed it.

Everything else

Not on the allow list, a limit exceeded, a condition unmet, or simply unrecognized. The action is refused. The default answer is no.

A failed or missing permission check blocks execution. The policy below illustrates an order-hold capability with per-run limits. It is a reference example; enabled actions and operating procedures are specific to a validated deployment.

policy.yaml
# fail-closed: nothing runs unless a rule below allows it.
default: deny

allow:
  - capability: orders.read          # reads are unconditional here

  - capability: orders.hold
    where:
      reason: ship-risk-review        # only this hold reason
    limits:
      per_run: 25                     # at most 25 holds in one run
      per_entity: 1                   # never hold the same order twice
    require:
      - receipt                       # a hold is not complete without one

  - capability: notify.send
    where:
      to: ops-queue                   # may only message the ops queue
    limits:
      per_run: 50
i
The model cannot widen its own policy

An operator that proposes access.unlock when the policy only allows orders.* does not error out in the world. The executor refuses the action and records the refusal. A proposal can be declined, but it can never edit the rulebook that declined it.

#Real data is a policy too

Fibric refuses to act on data it cannot verify is real. A fallback or placeholder value is tagged at the source as source: "fallback", and a tagged value can never be treated as a governed metric. So a placeholder can never trigger a real action. It is the same fail-closed instinct, applied to the inputs rather than the outputs.

policy.yaml (real-data guard)
# refuse to act on anything not verified as real data
require:
  - data.source: governed             # never "fallback", never "seed"

# a value tagged source:"fallback" is visible to a human,
# but it can never satisfy this rule, so it can never act.
!
A placeholder can never masquerade as a metric

The data layer tags any fallback so a placeholder cannot pass as a real number. A real tenant renders only governed real data, and an action gated on data.source: governed simply will not fire on a value that was filled in to keep a chart from being empty.

#Single-flight and idempotency

Two kernel primitives keep action safe under load, and the executor enforces both while disposing. 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.

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

The target key combines the operator, entity, and action. A recognized stable key can make a repeated proposal a no-op within the executor, while single-flight serializes work by entity. These controls materially reduce runaway risk; they rely on correct keys, connector behavior, and downstream reconciliation.

#The 657-flood

Repeated events and overlapping runs can propose the same action before the first request settles. Single-flight coordinates concurrent work for one entity. Idempotency identifies repeated requests. Connectors still need a reconciliation path when the downstream result is uncertain.

657
Ungoverned

The same notification fired again and again. No key to collapse the repeats, no single-flight to serialize the entity. The loop floods.

1
Governed

A recognized stable key suppresses the repeated proposal inside the executor, and single-flight serializes the entity. The connected system must still confirm the actual send outcome.

!
Defense in depth, with explicit boundaries

Nobody has to remember to add a guard. Single-flight and idempotency are properties of the executor, so the 657-flood cannot occur whether the loop is yours, the model's, or a bug. The repeats collapse before they ever reach a connector.

#Walled-off tenancy

Events and stored records carry reseller and tenant identifiers. The data path must apply the correct customer context and enforce the corresponding access policy. A deployment needs evidence that each relevant read and write path applies those controls.

row-level isolation
-- every query runs under the caller's tenant, set per request.
-- the row-level policy makes cross-tenant reads return nothing.
CREATE POLICY tenant_isolation ON events
  USING (tenant_id = current_setting('app.tenant_id'));

-- a placeholder or seed row for one tenant cannot surface in
-- another, and a real tenant sees only governed real data.

Real-data tenants must not receive seed or mock values as a fallback. Missing source data stays explicitly unavailable. An action request also needs valid tenant context before execution.

#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 it did and why, after the fact, for any action, in any tenant. A receipt is not a log line you hope was written. The executor writes it as it disposes, and a policy can require a receipt before an action is considered complete.

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"
}

A refused action leaves a receipt too. When the policy denies a proposal, the receipt records the decision as deny and the rule that produced it, so a refusal is as accountable as an action. If you cannot account for something, it did not happen. Governance is precisely the guarantee that everything can be accounted for.

i
Governance in one sentence

The operator proposes a plan. The execution path checks policy, coordinates attempts, and records the reported outcome.

#Keep going