dev.cocore.compute.exchangePolicy

cocore.dev

Documentation

main record

No description available.

Record Key tid Timestamp-based ID

Properties

active boolean Optional

Soft-delete: false means a newer policy supersedes this one. Settlements signed against an inactive policy are still valid for receipts that arrived before the policy flipped.

Default: true
createdAt string datetime Required

An RFC 3339 formatted timestamp.

exchange string did Required

Exchange DID. MUST equal the repo this record is published in.

fee ref #feeSchedule Required

Per-receipt fee. `fee.bps` is the fraction of each receipt's token cost routed to the treasury account instead of the provider (conservation 95/5 by default with `bps: 500`). The treasury accumulates these fees and redistributes them as patronage rebates on `patronageDistribution.cadenceDays`. `fee.currency` names the unit the fee schedule is denominated in.

patronageDistribution ref #patronageRule Optional

Optional periodic distribution of treasury balance back to active members in proportion to their patronage (consumer spending + provider earnings) during the period. Direct analog of REI's dividend and Rochdale-tradition patronage rebates. Set to absent to disable.

processor string Optional

Identifier for the settlement backend the exchange runs (e.g. 'closed-loop', 'usdc-base'). Useful as a hint to clients that need to know whether settlement is internal or external.

maxLength: 64 bytes
selfLoop ref #selfLoopRule Required

How the exchange handles jobs where requester DID == provider DID.

supportedCurrencies array of string Required

ISO 4217 (or XBT/XSAT-style) currency codes the exchange will settle in.

maxLength: 32 itemsminLength: 1 items
termsUri string uri Optional

URL to a human-readable Terms of Service / Privacy Policy for this exchange. Pinned with `termsVersion`; clients prompt the user for re-acceptance whenever the active policy's `termsVersion` no longer matches the version on the user's most recent dev.cocore.compute.termsAcceptance.

termsVersion string Optional

Version string for the terms-of-service text at `termsUri`. Bumping this triggers re-acceptance prompts in clients. Compared as a literal equality string; semantic versioning is a convention, not a requirement.

maxLength: 32 bytes
tokenFloor integer Optional

Minimum token balance a DID must hold post-dispatch for the exchange to accept a new job. The admission check is `balance - job.priceCeiling.tokensEquivalent >= tokenFloor`. Prevents a user from dispatching jobs that would zero out their balance, which keeps the failure mode 'wait for the next refresh' rather than 'mid-job settlement bounced'. cocore.dev sets this to 100_000.

minimum: 0
tokenGrant integer Optional

Tokens granted to a DID on first interaction with this exchange. Idempotent per DID: the exchange MUST issue the grant exactly once and MUST be able to prove which DIDs have already received it (typically via a `dev.cocore.account.tokenGrant` record per recipient). Set to 0 to disable grants. cocore.dev sets this to 1_000_000.

minimum: 0
tokenRate ref dev.cocore.compute.defs#tokenRate Optional

Uniform per-token rate the exchange asserts for jobs it settles. CANONICAL: providers settling through this exchange MUST price receipts at this rate, ignoring their own `dev.cocore.compute.provider.priceList`. Verifiers MAY reject receipts whose `price.amount` diverges from `tokenRate.inputPricePerMTok * tokens.in / 1e6 + tokenRate.outputPricePerMTok * tokens.out / 1e6` beyond a one-minor-unit floor. The provider's priceList is a denormalization for client display today; a future lexicon revision will introduce a per-receipt provider-set override (with the exchange's permission), at which point priceList becomes authoritative again. Optional only for pre-2026-05 policies, where the provider's priceList was canonical.

treasuryDid string did Optional

The DID whose token balance accumulates the per-receipt fee (5% by default) and from which patronage rebates are distributed. Defaults to the exchange's own DID (`exchange`) when unset, which matches the convention of a cooperative whose treasury IS the exchange's own balance sheet.

weeklyRefresh ref #refreshRule Optional

Optional 'use-it-to-keep-it' refresh that lazily issues `amountPerDid` tokens to active DIDs every `cadenceMinutes`. The refresh only fires when the DID touches the network (receipt as either side, balance read, governance act) — dormant DIDs accrue nothing. Sized so a member who actively uses the system stays roughly at the dignity floor; sized so the aggregate mint roughly matches the new-compute capacity coming online. Set to absent to disable.

View raw schema
{
  "key": "tid",
  "type": "record",
  "record": {
    "type": "object",
    "required": [
      "exchange",
      "fee",
      "supportedCurrencies",
      "selfLoop",
      "createdAt"
    ],
    "properties": {
      "fee": {
        "ref": "#feeSchedule",
        "type": "ref",
        "description": "Per-receipt fee. `fee.bps` is the fraction of each receipt's token cost routed to the treasury account instead of the provider (conservation 95/5 by default with `bps: 500`). The treasury accumulates these fees and redistributes them as patronage rebates on `patronageDistribution.cadenceDays`. `fee.currency` names the unit the fee schedule is denominated in."
      },
      "active": {
        "type": "boolean",
        "default": true,
        "description": "Soft-delete: false means a newer policy supersedes this one. Settlements signed against an inactive policy are still valid for receipts that arrived before the policy flipped."
      },
      "exchange": {
        "type": "string",
        "format": "did",
        "description": "Exchange DID. MUST equal the repo this record is published in."
      },
      "selfLoop": {
        "ref": "#selfLoopRule",
        "type": "ref",
        "description": "How the exchange handles jobs where requester DID == provider DID."
      },
      "termsUri": {
        "type": "string",
        "format": "uri",
        "description": "URL to a human-readable Terms of Service / Privacy Policy for this exchange. Pinned with `termsVersion`; clients prompt the user for re-acceptance whenever the active policy's `termsVersion` no longer matches the version on the user's most recent dev.cocore.compute.termsAcceptance."
      },
      "createdAt": {
        "type": "string",
        "format": "datetime"
      },
      "processor": {
        "type": "string",
        "maxLength": 64,
        "description": "Identifier for the settlement backend the exchange runs (e.g. 'closed-loop', 'usdc-base'). Useful as a hint to clients that need to know whether settlement is internal or external."
      },
      "tokenRate": {
        "ref": "dev.cocore.compute.defs#tokenRate",
        "type": "ref",
        "description": "Uniform per-token rate the exchange asserts for jobs it settles. CANONICAL: providers settling through this exchange MUST price receipts at this rate, ignoring their own `dev.cocore.compute.provider.priceList`. Verifiers MAY reject receipts whose `price.amount` diverges from `tokenRate.inputPricePerMTok * tokens.in / 1e6 + tokenRate.outputPricePerMTok * tokens.out / 1e6` beyond a one-minor-unit floor. The provider's priceList is a denormalization for client display today; a future lexicon revision will introduce a per-receipt provider-set override (with the exchange's permission), at which point priceList becomes authoritative again. Optional only for pre-2026-05 policies, where the provider's priceList was canonical."
      },
      "tokenFloor": {
        "type": "integer",
        "minimum": 0,
        "description": "Minimum token balance a DID must hold post-dispatch for the exchange to accept a new job. The admission check is `balance - job.priceCeiling.tokensEquivalent >= tokenFloor`. Prevents a user from dispatching jobs that would zero out their balance, which keeps the failure mode 'wait for the next refresh' rather than 'mid-job settlement bounced'. cocore.dev sets this to 100_000."
      },
      "tokenGrant": {
        "type": "integer",
        "minimum": 0,
        "description": "Tokens granted to a DID on first interaction with this exchange. Idempotent per DID: the exchange MUST issue the grant exactly once and MUST be able to prove which DIDs have already received it (typically via a `dev.cocore.account.tokenGrant` record per recipient). Set to 0 to disable grants. cocore.dev sets this to 1_000_000."
      },
      "treasuryDid": {
        "type": "string",
        "format": "did",
        "description": "The DID whose token balance accumulates the per-receipt fee (5% by default) and from which patronage rebates are distributed. Defaults to the exchange's own DID (`exchange`) when unset, which matches the convention of a cooperative whose treasury IS the exchange's own balance sheet."
      },
      "termsVersion": {
        "type": "string",
        "maxLength": 32,
        "description": "Version string for the terms-of-service text at `termsUri`. Bumping this triggers re-acceptance prompts in clients. Compared as a literal equality string; semantic versioning is a convention, not a requirement."
      },
      "weeklyRefresh": {
        "ref": "#refreshRule",
        "type": "ref",
        "description": "Optional 'use-it-to-keep-it' refresh that lazily issues `amountPerDid` tokens to active DIDs every `cadenceMinutes`. The refresh only fires when the DID touches the network (receipt as either side, balance read, governance act) — dormant DIDs accrue nothing. Sized so a member who actively uses the system stays roughly at the dignity floor; sized so the aggregate mint roughly matches the new-compute capacity coming online. Set to absent to disable."
      },
      "supportedCurrencies": {
        "type": "array",
        "items": {
          "type": "string",
          "maxLength": 8,
          "minLength": 3
        },
        "maxLength": 32,
        "minLength": 1,
        "description": "ISO 4217 (or XBT/XSAT-style) currency codes the exchange will settle in."
      },
      "patronageDistribution": {
        "ref": "#patronageRule",
        "type": "ref",
        "description": "Optional periodic distribution of treasury balance back to active members in proportion to their patronage (consumer spending + provider earnings) during the period. Direct analog of REI's dividend and Rochdale-tradition patronage rebates. Set to absent to disable."
      }
    }
  }
}
feeSchedule object

Linear fee model: max(amountMinor * bps / 10000, minMinor).

Properties

bps integer Required

Basis points (1/10000) retained by the exchange. 500 = 5%.

minimum: 0maximum: 10000
currency string Required

Currency the fee schedule is denominated in.

maxLength: 8 bytesminLength: 3 bytes
minMinor integer Required

Floor on the fee in integer minor units. 0 means there is no floor.

minimum: 0
View raw schema
{
  "type": "object",
  "required": [
    "bps",
    "minMinor",
    "currency"
  ],
  "properties": {
    "bps": {
      "type": "integer",
      "maximum": 10000,
      "minimum": 0,
      "description": "Basis points (1/10000) retained by the exchange. 500 = 5%."
    },
    "currency": {
      "type": "string",
      "maxLength": 8,
      "minLength": 3,
      "description": "Currency the fee schedule is denominated in."
    },
    "minMinor": {
      "type": "integer",
      "minimum": 0,
      "description": "Floor on the fee in integer minor units. 0 means there is no floor."
    }
  },
  "description": "Linear fee model: max(amountMinor * bps / 10000, minMinor)."
}
patronageRule object

Periodic distribution of treasury balance to active members in proportion to patronage during the period.

Properties

cadenceDays integer Required

Days between distribution ticks. cocore.dev: 30.

minimum: 1
fractionBps integer Required

Basis points of the treasury balance distributed at each tick. Remainder is retained as operating reserve. cocore.dev: 8000 (80% distributed, 20% retained).

minimum: 0maximum: 10000
View raw schema
{
  "type": "object",
  "required": [
    "fractionBps",
    "cadenceDays"
  ],
  "properties": {
    "cadenceDays": {
      "type": "integer",
      "minimum": 1,
      "description": "Days between distribution ticks. cocore.dev: 30."
    },
    "fractionBps": {
      "type": "integer",
      "maximum": 10000,
      "minimum": 0,
      "description": "Basis points of the treasury balance distributed at each tick. Remainder is retained as operating reserve. cocore.dev: 8000 (80% distributed, 20% retained)."
    }
  },
  "description": "Periodic distribution of treasury balance to active members in proportion to patronage during the period."
}
refreshRule object

Periodic refresh: amount + cadence.

Properties

amountPerDid integer Required

Tokens credited to a DID per refresh tick. cocore.dev: 70_000 (~7% of the 1M-token onboarding grant).

minimum: 0
cadenceMinutes integer Required

Minimum minutes between refreshes for a given DID. cocore.dev: 10_080 (7 days).

minimum: 60
View raw schema
{
  "type": "object",
  "required": [
    "amountPerDid",
    "cadenceMinutes"
  ],
  "properties": {
    "amountPerDid": {
      "type": "integer",
      "minimum": 0,
      "description": "Tokens credited to a DID per refresh tick. cocore.dev: 70_000 (~7% of the 1M-token onboarding grant)."
    },
    "cadenceMinutes": {
      "type": "integer",
      "minimum": 60,
      "description": "Minimum minutes between refreshes for a given DID. cocore.dev: 10_080 (7 days)."
    }
  },
  "description": "Periodic refresh: amount + cadence."
}
selfLoopRule object

What happens when the same DID owns the requester job and the receipt's provider field — e.g., a user running an inference on their own machine via the exchange.

Properties

feeWaived boolean Required

If true, the exchange takes no fee on self-loop jobs. The settlement still gets published as an audit trail.

minMinor integer Optional

Optional facilitation floor — the exchange may still take a small flat amount to cover its operating cost. Ignored when feeWaived is true.

minimum: 0
View raw schema
{
  "type": "object",
  "required": [
    "feeWaived"
  ],
  "properties": {
    "minMinor": {
      "type": "integer",
      "minimum": 0,
      "description": "Optional facilitation floor — the exchange may still take a small flat amount to cover its operating cost. Ignored when feeWaived is true."
    },
    "feeWaived": {
      "type": "boolean",
      "description": "If true, the exchange takes no fee on self-loop jobs. The settlement still gets published as an audit trail."
    }
  },
  "description": "What happens when the same DID owns the requester job and the receipt's provider field — e.g., a user running an inference on their own machine via the exchange."
}

Lexicon Garden

@