Fibric. Docs fibric.io →
v0.9 ยท preview
Build

Operator pack manifest

An operator pack is an operator made installable: a versioned artifact bundling the operator's ConnectorDef, its prompt contract, its capability requirements, recommended guardrail defaults, and marketplace metadata. This page documents the manifest file by file: what each carries, how connectors travel with a pack, where pricing metadata lives, and how the bundle is validated and published. The operator packs page covers the concepts; this is the reference for the artifact itself.

Pack structure

A pack is a directory with fixed filenames. fibric init --template operator scaffolds it; fibric publish reads it whole.

pack project layout
packs/order-risk/
  index.ts            the ConnectorDef (category: ai-operator)
  prompt.md           the prompt contract, versioned with the pack
  guardrails.ts       recommended TrustPolicy[] defaults
  requires.json       capability requirements, by intent
  listing.json        marketplace metadata, including pricing
  fixtures/           recorded envelopes for review and CI
  connectors/         optional: private connectors bundled with the pack
FileRequiredRead byCarries
index.tsyesregistry, executorIdentity, version, and the tools the operator may propose.
prompt.mdyesruntime, reviewThe fixed reasoning frame. Versioned like an interface.
guardrails.tsyesinstall flowRecommended TrustPolicy[]; applied only when the installer accepts.
requires.jsonyesinstall flowCapabilities needed, by intent, with which are optional.
listing.jsonfor marketplacemarketplaceThe card and detail-page fields, plus pricing. Private packs may omit it.
fixtures/for marketplacereview, CIRecorded envelopes demonstrating the operator's proposals. Review replays them.
connectors/noregistryConnectors published together with the pack; see bundling.

The ConnectorDef core

Operators are connectors too, so the manifest's core is an ordinary ConnectorDef with category: 'ai-operator'. The tools record lists the actions the pack may propose, every one side-effecting, because an operator's only output is a plan; and auth is none(), because an operator holds no credentials and acts through the connectors the installing tenant has already authorized.

packs/order-risk/index.ts
import { defineConnector, tool, none } from '@fibric/connector-sdk';

export default defineConnector({
  id: 'op-order-risk',
  version: '1.0.0',
  category: 'ai-operator',
  publisher: 'partner',
  auth: none(),

  // the actions this pack may PROPOSE; proposals only ever run through the executor
  tools: {
    'order.hold':  tool({ sideEffecting: true, handler: () => { /* proposed, never called directly */ } }),
    'notify.send': tool({ sideEffecting: true, handler: () => { /* proposed, never called directly */ } }),
  },
});

prompt.md

The prompt contract: the goal statement, the constraints, the shape of the ExecutionPlan the model must return, and the refusal conditions under which it must propose nothing. Nothing at runtime can rewrite it, and a change to it is a version change installers see as a diff before upgrading. Structure it in the four sections review expects:

prompt.md skeleton
# Goal
One paragraph. The outcome, in plain language, matching listing.json's tagline in substance.

# Constraints
What the operator must never propose, value bounds it must respect, and the
sourcing rule: every claim it emits carries the capability it was sensed through.

# Output
The ExecutionPlan shape, with the pack's idempotency-key convention spelled out:
  order-risk:<order_id>:<action>

# Refusal
The conditions under which the correct plan is `{ "actions": [] }`, stated
positively. An operator that cannot verify its inputs proposes nothing.

guardrails.ts

The pack's recommended trust-policy defaults, in the kernel's TrustPolicy shape. They are suggestions with a formal role: the install flow shows them, the installer accepts or edits them, and the tenant's own policy always has the last word. A pack cannot grant itself anything; the executor evaluates default-closed regardless of what shipped here.

packs/order-risk/guardrails.ts
import type { TrustPolicy } from '@fibric/sdk';

export const defaults: TrustPolicy[] = [
  { tool: 'order.hold',  decision: 'ALLOW' },
  { tool: 'notify.send', decision: 'ALERT' },               // act, and page a human
  // no refund rule shipped: if a future version proposes one, it BLOCKS until
  // the tenant writes a rule. fail closed is the default everywhere.
];

requires.json

The capabilities the operator needs, by intent, never by vendor. The install flow walks this list and binds each entry to one of the tenant's connectors; creation fails, naming the gaps, if a required capability has no provider.

packs/order-risk/requires.json
{
  "requires": [
    { "capability": "orders.read",         "why": "order state and promise dates" },
    { "capability": "orders.hold",         "why": "the action the pack proposes" },
    { "capability": "conversations.read",  "why": "support context per order", "optional": true },
    { "capability": "notify.send",         "why": "operator notices to the ops channel" }
  ]
}
FieldTypeRequiredDescription
capabilitystringyesA name from the shared capability vocabulary, noun.verb.
whystringyesOne line shown in the install flow. Review checks it against the prompt contract.
optionalbooleannoDefaults to false. An optional capability left unbound degrades the operator gracefully; the prompt contract must say how.

listing.json

The marketplace card and detail page, field for field the same schema as any connector listing, documented on publishing. For a pack the fields that do the work are senses (three lines on what it reads), acts (what it proposes), and worksWith (connectors known to satisfy its requirements). The two live packs, op-order-sentinel and op-radar-analyst, both list cn-kustomer and cn-magento in worksWith, which is exactly the binding running in production inside BearScope, Fibric's flagship product.

Bundling connectors with a pack

Most packs bundle nothing: they require capabilities and let the tenant's existing connectors provide them, which is the shape to prefer. Bundle a connector only when the pack targets a system no marketplace connector covers, by placing an ordinary connector project under connectors/:

a pack with a bundled connector
packs/coldchain-watch/
  index.ts                       op-coldchain-watch (ai-operator)
  prompt.md
  guardrails.ts
  requires.json                  requires: sensor.read, notify.send
  listing.json
  connectors/
    cn-coldchain-mqtt/
      index.ts                   an ordinary ConnectorDef (category: hardware)

Bundled connectors keep their own ids, versions, and review; publishing the pack publishes them as separate listings linked from the pack's worksWith. The pack still binds to them through capabilities: nothing in requires.json names cn-coldchain-mqtt, so a tenant with a different sensor source binds that instead. Bundling is distribution convenience, never coupling.

Pricing metadata

Pricing lives in listing.json, and the marketplace renders it; the pack never bills anything itself. Metering is read off receipts, the same records you audit with, so there is no separate billing counter to disagree with the audit trail.

listing.json — pricing block
{
  "pricing": {
    "model": "per-operator-monthly",
    "from_usd_month": 49,
    "trial": { "mode": "propose-only", "days": 14 }
  }
}
FieldTypeDescription
modelstringper-operator-monthly for packs. Operator packs are priced from $49 per operator per month; premium connectors from $29 per source per month.
from_usd_monthnumberThe listed floor price. Tiering above it is a publisher-and-marketplace arrangement, not a manifest field.
trialobjectOptional. The conventional trial is a propose-only period: the pack runs its full loop, plans queue for review, and the executor disposes nothing.

Actions disposed above plan allowances meter at $0.01 per action against the installing tenant, uniformly; that is platform billing, not a listing field. During early access the platform itself is free and the Team plan is $240/mo.

Validating a pack

Everything above is checkable offline, and the CLI checks it:

terminal
$ fibric publish --check packs/order-risk
  def          op-order-risk@1.0.0  ai-operator  ok
  auth         none()                            ok (required for ai-operator)
  tools        2 declared, all sideEffecting     ok
  prompt.md    4 sections present                ok
  guardrails   2 rules parse as TrustPolicy[]    ok
  requires     4 capabilities, 1 optional        ok (all in shared vocabulary)
  listing      pricing per-operator-monthly $49  ok
  fixtures     3 envelopes replay to valid plans ok
  check passed. publish with: fibric publish packs/order-risk

The fixture replay is the substantive gate: review runs your recorded envelopes through the pack and inspects the proposed plans, keys and all, without executing anything. Ship fixtures that exercise the refusal path too; a pack whose fixtures never produce an empty plan draws questions.

Publishing

fibric publish submits the bundle for review; the lifecycle from submission through early access to live, review timelines, and how updates roll out are on publishing to the marketplace. Version discipline specific to packs: the prompt contract is part of the public interface, so a contract change that alters what the operator proposes is at least a minor bump, shown to installers as a diff, and never auto-applied. Changed guardrail defaults or a new required capability are major. Published versions are immutable, and receipts record the pack version that proposed every action.

Keep going