Caliber Factor
Advance against escrow, not promises — the methodology.
by PokoBlue · @PokoBlue99 · September 2026 Version: v1.2 · PROVISIONAL PARAMETERS · published ahead of the Arc mainnet release; the parameters below become operative only when the proving period closes — see §Provisional Parameters and the Proving Period Sibling to, and consumer of, Caliber Rating v2.1.0 Derived from the Caliber Coverage v1.1 internal draft (May 2026), narrowed to committed, escrowed receivables. Coverage remains a separate future methodology — see §Future Work.
TL;DR
Caliber Rating tells you whether an agent delivers. Caliber Factor tells a capital provider one narrower thing: how much of this agent's escrowed, confirmed work is safe to advance against — and gives both sides the on-chain controls that make the advance repay itself as those jobs settle.
Factor never advances against a forecast. It advances only against USDC a client has already locked in ERC-8183 escrow, only for jobs that pass a counterparty-independence graph test, discounted by a dispute haircut and a client-diversification weight, and always less than the client locked. Repayment is skimmed from those same jobs' settlements. The agent's collateral — posted, or earned from its own repaid settlements — and an earned reserve backstop the residual, and every advance matures: at its maturity anyone may apply them to what is still owed.
Caliber publishes the eligibility decision, the advanceable backlog, a signed FactorAttestation, and the control primitives. It does not lend, price, or decide the advance. The capital provider owns the credit decision, the pricing, and any recourse; Caliber owns the signal and the controls. Caliber holds no advance, bears no credit loss, performs no KYC.
Everything is computed from public ERC-8004 + ERC-8183 events. Same house rule as the Rating: if you can read the tables below, you can audit any number we publish.
Why This Exists
Under ERC-8183 the client escrows USDC before work is delivered. An agent with confirmed jobs therefore holds something rare in credit: receivables where the payer's money is already locked on-chain. Traditional factoring advances against invoices and hopes the debtor pays; Factor advances against escrow that cryptographically cannot be spent elsewhere. Structurally safer than the off-chain original — the collection risk is reduced to dispute risk.
This is deliberately not lending against future earning power. That harder question — projecting settlement velocity, coverage ratios, breach covenants — belongs to the separate Caliber Coverage methodology, which remains future work. Factor is the narrow, conservative slice: committed backlog only. If the money isn't already locked, it doesn't count. That single restriction is what makes every downstream number in this document verifiable rather than forecast.
Where Caliber Stops and the Capital Provider Begins
Factor is neutral, permissionless infrastructure. It measures, attests, and provides on-chain control primitives. It is not the lender.
| Caliber owns — permissionless, on-chain | The capital provider owns — their risk |
|---|---|
| Eligibility decision (the graph test), per job | The capital — and the credit loss |
| Advanceable backlog: haircut δ, diversification weight w | Whether and how much to actually advance |
| The signed FactorAttestation | The advance rate (within the published cap) |
| Control primitives: skim splitter, earned reserve, collateral, maturity and resolution, routing-away default mark | Pricing / fees |
| Guarded-launch caps (published, event-logged) | Any KYC, legal contract, or off-chain recourse |
| The reproducible calculation method | Any PD / loss model derived from Caliber's measurements |
Provider disclosure — state this to anyone consuming Factor. Caliber measures and controls on-chain risk and provides no legal recourse. The collateral and reserve bound only the loss that code and economic deterrence cover; the clients' escrow is theirs and bounds nothing for the provider. A provider advancing beyond those bounds carries the tail itself and mitigates it by its own means — contracts, KYC, or pricing. That is a provider decision, never a Caliber guarantee.
What Factor Measures (The Core Table)
Items marked [reused] come from Caliber Rating v2.1.0; [new] are introduced here.
| Input | What it is | Source | Status |
|---|---|---|---|
Job state (Open/Funded/Submitted/terminal) | Which jobs are confirmed and escrowed | ERC-8183 | [new use] |
funded_backlog | USDC locked in this agent's confirmed, unsettled jobs | ERC-8183 escrow | [new] |
| Counterparty graph | Who funds whom; ownership and funding links between wallets | ERC-8004/8183 | [new] |
dispute_rate (credibility-weighted) | How often this agent's work is rejected | Rating §2.1 | [reused] |
counterparty_hhi over eligible clients | Concentration of the repayment source | derived | [adapted] |
self_deal_share, sybil / concentration flags | Wash-activity signals | Rating §2.3 | [reused as gates] |
| Client identity age, prior settled jobs | Fresh-counterparty test inputs | ERC-8004/8183 | [new] |
| Caliber tier + flags | Agent-side quality gate | Rating | [reused] |
Advance terms (advance_rate, fee) | Chosen by the provider within published caps | provider-supplied | — |
outstanding | Advance + fee not yet repaid | advance contract | [new] |
Honest notes: only escrowed money counts — no off-chain income, no self-reported pipeline, no velocity extrapolation. Eligibility is per job, then aggregated per agent. Factor requires confirmed escrow to exist; an agent with an empty backlog has an advanceable amount of zero, correctly.
Step 1 — The Eligibility Gates (binary, per job)
A job contributes to the advance base only if every gate passes. Fail one, and the job counts $0 — however large. Exclusion may deter activity; it is never counted as collateral.
Gate 1 — Confirmed and escrowed. Job state is Funded or Submitted
(work delivered, awaiting acceptance), and the job is not past its
expiredAt. Open jobs never count — nothing is locked. A job past its
expiry does not count either: on Arc's AgenticCommerce, claimRefund() may
be called by anyone once expiredAt has passed and returns the escrow to the
client, so that money is the client's to take back at any moment. Jobs in dispute are excluded entirely; δ (below) prices the risk of
future disputes on clean jobs, not the fact of a live one.
On Arc that dispute exclusion is presently vacuous, and saying so is better
than implying a control that does not run. Arc's AgenticCommerce has no
Disputed job state — the indexed vocabulary is
Open / Funded / Submitted / Completed / Rejected / Expired — and the one
dispute signal the index holds, the validations table, carries no job_id,
so no job-level dispute can be excluded even in principle. The practical
consequence: a Submitted job whose validation came back FAILED contributes
its full escrow to the advance base. A dispute becomes observable only once
the job leaves Submitted, at which point Gate 1 excludes it as a terminal
state. Linking validations to jobs is the fix and it is a Rating-side schema
change, not a Factor one.
Gate 2 — Not self-dealt, directly or through a cycle. The client must not be the agent's owner or operator — through the agent's identity addresses or its registered payout address, since funding one's own splitter is self-dealing just as plainly — and there must be no funding path connecting client and agent within the counterparty graph (multi-hop cycle detection, reference depth ≤ 3). Nor may the job's ERC-8183 evaluator be the agent's own side — its wallet, its operator or its splitter — because the evaluator alone decides whether funded work completes, and an agent that evaluates itself confirms its own escrow. Where the client is the evaluator, as on most Arc jobs, acceptance is discretionary but not self-dealt: that is priced as a weight, not excluded. This is the full graph-cycle test the Rating's sybil section listed as future work; Factor v1.0 delivers it. The Rating's sybil and concentration flags additionally act as hard agent-side gates.
The traversed edge set is funding only. An edge exists where a client has funded a provider; ownership edges — two agents sharing a beneficial owner — are not traversed, because beneficial ownership is not observable on-chain beyond the NFT owner already folded into the agent's addresses. Earlier drafts of this section said "ownership-or-funding", which overstated it. Entity clustering would strengthen this and is not in v1.0.
The edge set is a materialized view refreshed on the daily snapshot, so a funding cycle constructed after the last refresh is invisible to this gate for up to 24 hours. Staleness is conservative in one direction only — a missing edge cannot invent a path, but it can hide one — which is the wrong direction for an anti-fraud gate, and is stated here rather than left to be discovered.
Gate 3 — No fresh single-use counterparties. The funding client must have an identity older than the reference age (14 days) and at least one prior settled job with an unrelated counterparty. A wallet minted yesterday that has only ever funded this agent is not evidence of demand; it is the setup for manufactured collateral.
Identity age is measured on chain time — the block its first job was created in, converted by interpolating between the nearest real block timestamps we hold, and not on when Caliber's indexer happened to write the row. The interpolation is deliberately local: a chain's block rate is not a constant, and on Arc a single straight line fitted across all history implies 5.6 blocks/sec against a current rate near 1, which misdates a week-old block by four days. The two differ by months across any backfilled range, and reading the gate off insert time would make every client on the chain read as newly minted after a re-backfill. On Arc a plain EOA emits no registration event, so first on-chain activity remains the only observable proxy for identity age; measuring it on chain time is what makes it a property of the client rather than of us.
Gate 4 — Agent-side quality. The agent holds a quality tier (Bronze or above) with no active risk flag. Watch-tier agents have an advanceable amount of zero for as long as the flag stands.
The eligible set E is everything that survives all four gates.
The unit of aggregation — payout address, not agent id
Eligibility is decided per job. It is then aggregated per payout address, not per agent id, and the distinction is load-bearing.
An ERC-8004 registration is an NFT. One wallet may hold many, and on Arc the
agent's payout address is its owner, because agentWallet/operator is
unpopulated. Escrow is therefore held against the address, while the Rating is
computed per agent id. Measured on Arc on 2026-09-01: one wallet
(0xafe6dd95…0549) held 143 agent registrations over $51.25 of live
escrow, and the next held 100. Summed per agent id the qualified population
showed $5,609.25 of advanceable escrow; de-duplicated by payout address it
was $41.55 — the same pot counted 135 times.
This matters because per-attestation safety does not compose. Each of those
attestations would be individually truthful and would each satisfy
advance < escrow locked; together they would authorise 135 advances against
one pot. An invariant that holds on every document and fails on the set is not
an invariant.
Two rules follow, and both are part of the eligibility decision Caliber owns:
-
Aggregate to the payout address. Eligible escrow, the advanceable backlog, and any outstanding advance are quantities of an address. An attestation names the agent id it was requested for and the payout address it is computed over; a consumer holding two attestations that share a payout address is holding one claim twice.
The payout address is the agent's registered splitter, and it is not the same set as the agent's identity. Under ERC-8183
provideris fixed atcreateJob, so escrow created against the agent's own wallet can never be skimmed — counting it would size an advance against collateral the repayment rail cannot reach. An agent with no registered splitter therefore has an advanceable backlog of zero, whatever its wallet holds, and Caliber refuses to attest rather than issuing a truthful-looking number that no advance could be repaid from. Identity addresses remain what Gate 2 and the sibling union are evaluated over: who the agent is, versus where it is paid. -
Gate 4 evaluates the union of siblings. Where several registrations share a payout address, the address inherits the worst tier and the union of active flags among them. Without this, Gate 4 is trivially bypassable: the wallet above spans Silver and Watch, because
feedback_eventsare keyed by agent id while jobs resolve by address, so an operator could attest through whichever registration happens to be clean while the flagged sibling sits at the same address, drawing on the same escrow.
Both rules are implemented, not aspirational. The union is applied in
rating/engine/factor/gates.ts (unionSiblingQuality), which takes the
maximum tier ordinal — ordinals ascend as quality descends, so the worst
tier is the largest number — and the bitwise OR of active flags, across every
registration resolving to the payout address. The attestation route refuses
outright when the union fails Gate 4, and names the sibling that bound the
decision, so a refusal is explainable rather than asserted.
One honest limit: a sibling that has never been rated contributes neither a
tier nor an absence of one. It is counted and reported (siblings_without_rating),
because an unrated sibling is absence of evidence, not evidence of cleanliness —
and inventing a tier for it would be the same species of overclaim the union
exists to prevent. Its flags, where it has any, still count.
Enforcement is deliberately duplicated rather than trusted to the attestation
alone: the advance contract keys outstanding by payout address, so a second
advance against the same address is refused on-chain however many attestations
exist. Same discipline as §Defense in Depth — two independent layers, neither
asked to be perfect alone.
Step 2 — The Advanceable Backlog
Two published discounts turn eligible escrow into the advanceable backlog — the dispute haircut and the client-diversification weight — and, from v1.1, a third mechanism that is published but set to 1.0:
The client-evaluator weight. On most Arc jobs the client paying for the work
is also its ERC-8183 evaluator, and decides alone whether it is accepted; the
job contract has no appeal step. Escrow on such a job counts at weight
CLIENT_EVALUATOR_WEIGHT. It is 1.0, so today it changes no number: the
reference parameters are fitted on mainnet, not invented on testnet, and the
risk is disclosed to providers instead of priced by a guess. The mechanism is
published now so that setting it later is a parameter change under this
version, not a new methodology.
δ — the dispute haircut, per agent. The share of confirmed work that history says may still be rejected. Derived from the Rating's credibility-weighted dispute rate, floored:
δ = max( δ_min , dispute_rate_credibility_weighted ) δ_min = 5% (reference)
An agent whose smoothed rejection rate is 18% gets δ = 0.18; a clean agent with thin history is pulled toward the population floor rather than flattered by a small sample — the same credibility discipline the Rating uses everywhere.
What dispute_rate_credibility_weighted is, exactly. It is
1 − completion_rate_smoothed from the Rating (rating/engine/rating.ts), and
three properties of that number matter enough to state rather than leave to the
reader:
- The window is 30 days, not lifetime. δ prices what this agent's recent conduct implies, which is the right horizon for escrow that will settle in weeks — but it does mean an agent's δ can move without any new dispute, simply as old jobs age out of the window.
- The denominator is resolved jobs, and "unresolved badly" counts.
Rejected,Expired,Disputed,CancelledandRefundedall count against completion. That is broader than the word "dispute" suggests: an expired job is not a dispute, but it is confirmed work that did not turn into a settlement, which is precisely the risk δ exists to price. Stated plainly because the alternative — a narrow literal dispute count — would understate the haircut on exactly the agents that deserve it. - It is credibility-blended toward the population mean, per chain, so a thin history is pulled toward the floor rather than reading as perfect.
This is a defensible proxy rather than a literal reading of the phrase "credibility-weighted dispute rate", and it is written down here so a provider reproducing δ from the public rating response gets our number and not a different one.
w — the client-diversification weight, over the eligible set. In factoring, concentration is repayment-source risk: if 80% of the eligible escrow comes from one client, one dispute or one walk-away impairs most of the repayment path. So:
w = clamp( 1 − HHI_eligible_clients , w_min , 1 ) w_min = 0.30 (reference)
A disclosed refinement vs. the Coverage draft: Coverage's quality factor q
multiplied (1 − self_deal_share) into the weight and deliberately did not
haircut backlog. Factor differs on both, for stated reasons: self-dealt jobs
are already excluded at Gate 2 (a binary gate beats a discount), and in
Factor the backlog is the repayment source, so its concentration must be
priced. Different product, different treatment — disclosed here so the
divergence is auditable.
The advanceable backlog:
advanceable_backlog = ( Σ_{jobs ∈ E} escrow_i ) × (1 − δ) × w
Worked example. Eligible escrow $10,000; agent's smoothed dispute rate 18%, so δ = 0.18. Shares are stated so every figure is reproducible:
| Client shares | HHI | w | ×(1−δ) | Advanceable | Provider @ 55% | |
|---|---|---|---|---|---|---|
| Diversified | 4 × $2,500 | 0.25 | 0.75 | 0.82 | 6,150 | ≈ 3,383 |
| One dominant client | $8,500 + 3 × $500 | 0.73 | 0.30 (floored) | 0.82 | 2,460 | ≈ 1,353 |
Same locked money, well under half the safe advance — because most of the
repayment path hangs on one counterparty's behaviour. Note the second row hits
w_min: raw 1 − HHI is 0.27, and the floor is what stops concentration from
driving the backlog to zero.
Worth reading carefully: w = 1.0 is unreachable with a finite client list.
1 − HHI approaches 1 only as the number of equally-weighted clients grows
without bound; four equal clients cap out at 0.75, ten at 0.90. An earlier
draft of this example asserted w ≈ 1.00 for four clients, which contradicted
the formula directly above it — corrected in 1.0-draft2.
Step 3 — The Advance and Its Caps
Two ceilings, and the advance is the smaller of them:
escrow ceiling = advance_rate × advanceable_backlog advance_rate 0.55 (reference)
flow ceiling = collateral + 0.8 × E E = expected independent flow
advance ≤ min( escrow ceiling , flow ceiling )
advance < Σ escrow_i (always less than the clients locked — hard invariant,
enforced by the splitter when the advance opens)
The escrow ceiling is the v1.0 rule: a discount on escrow already locked. It bounds what the agent could be advanced against. The flow ceiling is new in v1.2 and bounds what it will plausibly repay: the collateral it already holds on its splitter, plus 80% of the independent settlements expected before the advance matures.
E — expected independent flow. E = r × H × h × w, where
r= the slower of the trailing 30-day and 90-day daily rates of settlements through the splitter from qualifying clients — so a burst cannot inflate it and a collapse shows at once;H= days from now to the advance's maturity (§Maturity);h = n / (n + 20),n= qualifying settled jobs in 90 days — a credibility discount for a thin record;w= the client-diversification weight (§Step 2) over the qualifying flow.
E is zero when nothing has settled through the splitter, when no client
qualifies, when the last qualifying settlement is more than 14 days old (a
dormant agent's advance falls to its collateral with no judgement involved),
or when there are fewer than 30 days or 5 jobs of qualifying history.
Which clients qualify. A client counts only if it is independent of the
agent's side — the Gate 2 idea applied to the flow record, plus a
funding-source test: a client whose first money came from the agent's side, or
from a wallet that also funded it, does not count. That test needs the USDC
transfer history, which Caliber does not yet index; until it does, no client
qualifies and E is zero for every agent, so every advance is capped at the
collateral its agent holds. The funding page says so. Caliber's own wallets
never qualify — the seeded agents and clients are labelled as Caliber's, so
Caliber's own money is never presented as independent flow.
When an advance is an offer. An advance at or below the collateral its
agent already holds leaves nothing uncovered and gives the agent no liquidity;
it is not offered to providers. While E is zero that is every advance. A
Caliber rehearsal — Caliber on every side — may still be funded by a
Caliber-own wallet to run the contracts end to end, labelled as a test.
The fee. The factoring fee is flat and one-time, charged at
acceptance, and provider-set within a published range — reference 2.40% of
the advance. It is a factoring discount fee, not a time-accruing charge, and
the vocabulary stays on factoring fee. The fee is part of outstanding, so
the skim captures it on the same waterfall as the principal. §The Pricing Model
shows what a fee would need to cover; it does not set the fee.
During the guarded launch, additional published caps apply — a per-agent USDC maximum, a global outstanding maximum, and an allowlist of agents and providers — all admin-set, event-logged, changes effective when published. Caps are a launch-safety instrument, not a credit judgment.
The FactorAttestation
Every eligibility decision ships as a signed EIP-712 FactorAttestation
that any contract can verify — the same primitive pattern as the
RatingAttestation, on its own verifier.
Carried fields (pinned at FactorVerifier deployment): chain id · agent id ·
agent address · eligible escrow (USDC) · advanceable backlog (post-δ, post-w) ·
eligible job count · δ and w as applied · Factor methodology version ·
freshness window · replay nonce. Issued through a paid x402 nanopayment
route (HTTP 402, pay-per-attestation), verified on-chain by a dedicated
FactorVerifier; the deployed RatingVerifier is unchanged. A provider that
verifies the signature against the published Caliber signer key knows the
claim is current, complete, and untampered — and sizes the advance from it.
δ and w are carried as applied, rounded to basis points, so a consumer can
recompute advanceable_backlog = eligible_escrow × (1−δ) × w rather than take
it on trust. Because the engine computes the backlog from the full-precision
values and the attestation carries the rounded ones, an honest attestation
can miss exact equality by up to roughly one basis point of the backlog.
FactorVerifier.checkBacklogArithmetic therefore takes a tolerance, and the
published minimum safe value is toleranceBps = 1. A consumer calling it
with toleranceBps = 0 — the natural "check it exactly" choice — can reject a
correct attestation, so the tolerance is stated here rather than left to be
discovered against a live advance.
Nonce consumption on requireAdvanceWithinBounds is restricted to consumers
Caliber has allowlisted, and the authorisation event names the consumer that
burned the nonce. An attestation is public calldata once broadcast, so an
unrestricted gate let any observer burn a valid attestation's nonce and force
it to be re-purchased. The allowlist narrows that to an accountable set; it
does not bind one attestation to one provider, which would require a
provider field in the signed struct and therefore a version change.
Repayment — The Skim Splitter
Read together with §Security. The splitter is the preferred repayment rail for a cooperative agent — not an enforcement mechanism.
The agent registers a Caliber payout splitter as its payment address at onboarding. Settlements of advance-encumbered (factored) jobs route through it and split by a fixed waterfall:
on settlement(amount) of a factored job:
repay = min(amount × skim_rate, outstanding)
reserve = min(amount × reserve_rate, reserve_target − reserve_balance)
transfer(repay, provider) # repayment first, code-enforced
transfer(reserve, earned_reserve) # then the reserve slice
transfer(remainder, agent) # agent keeps the rest
if outstanding == 0: reserve joins the agent's collateral # earned, not paid out
Reference default: skim_rate = 80%. With reserve_rate = 5%
(§The Earned Reserve), the agent retains 15% of each factored settlement while
the advance is outstanding.
Seniority is fixed and unconditional: repayment → reserve → agent. If the two published slices would ever exceed the settlement, the reserve gives way and the provider is paid in full — never the reverse.
That seniority imposes a condition the reference parameters must respect:
skim_rate + reserve_rate ≤ 100% — the condition for the reserve to accrue
Above it, repayment consumes the settlement and the reserve slice is zero by
construction. skim_rate = 100% remains a permitted provider choice, and
under it the reserve is dormant by design. That configuration is not
unsafe: at a full skim the reserve is redundant, because provider exposure
(outstanding − collateral − reserve) is identical whether a dollar reduces the
outstanding or is retained as seizable collateral. It simply cannot exercise a
reserve — which is why it is not the reference.
An earlier draft published skim_rate = 100% as the reference alongside a 5%
reserve rate. The two are arithmetically incompatible; see §Change History,
1.0-draft3.
The published sizing rule is unchanged — at the chosen rate the advance must clear from the eligible backlog alone:
skim_rate ≥ ( advance + fee ) / advanceable_backlog
At the reference advance rate and fee this binds well below the reference skim: 0.55 × 1.024 ≈ 0.56 ≤ 0.80, leaving margin for a provider pricing above the reference fee or sizing above the reference rate.
Two properties define this design: repayment is code-enforced for every settlement that passes the splitter, and there is no fixed due date — the advance clears exactly as fast as the underlying jobs settle. What is not enforced is the agent's choice to keep routing here. That is the next two sections.
The Earned Reserve, and Earned Collateral
A published slice of each factored settlement (reference reserve_rate = 5%,
target = 10% of the original advance) accumulates in an on-chain earned
reserve while an advance is open — the agent's own money, held as cushion and
applied ahead of the collateral on any recovery.
What changed in v1.2. v1.0 returned the reserve to the agent on full repayment. From v1.2 it is not paid out: it joins the agent's collateral balance on its splitter, which the agent may withdraw whenever nothing is outstanding and which counts toward the collateral its next advance requires. Fresh capital stops being the price of every advance; an agent with a working record builds collateral out of its own repaid settlements, and walking away from an advance starts costing it money it earned. (With no advance open, settlements pass through the splitter to the agent in full; the slice accrues only while an advance is open.)
The Collateral
Every advance needs collateral on the agent's own splitter before it opens — posted by the agent or a sponsor, or earned (above). The funding contract refuses to fund an advance without it. The required amount follows Factor's tier-stepped schedule, as a percentage of the advance:
| Agent tier | Collateral |
|---|---|
| Gold | 3% of advance |
| Silver | 4% of advance |
| Bronze | 5% of advance |
| Pending · Watch · Dormant | not eligible — excluded at Gate 4 |
Floor: 25 USDC. The splitter factory enforces a floor of its own that the operator cannot quote under — 25 USDC or 3% of the advance, whichever is larger — and the required amount is inside what the provider signs.
While an advance is open the collateral cannot be withdrawn. At maturity, or after an uncured routing-away default, it is applied to what the provider is owed, after the reserve, capped at what is owed; whatever is left stays the agent's own balance. Once nothing is outstanding the agent may withdraw it.
The collateral asset is a deployment parameter of the splitter factory,
and today it must be USDC — the same asset the advance is paid in. Collateral
in another asset would have to be valued against a USDC debt, which means an
oracle and its governance; that is not done. (v1.0's per-advance FactorBond
is retired with the v1 contracts; advances opened under v1.0 kept their bonds.)
Maturity and Mechanical Resolution
Every advance has a maturity, fixed when it is funded: the latest deadline
(expiredAt) among the ERC-8183 jobs it is financed against, plus the cure
window. The splitter records the financed jobs and checks each when the
advance opens — it must pay the splitter, hold escrow, and be before its
deadline — and refuses an advance that is not below their combined escrow. By
maturity every financed job has either settled or become refundable to its
client.
At maturity, anyone may call resolution. It applies the reserve, then the collateral, to whatever is still owed, pays that to the provider up to the amount owed, leaves anything over in the agent's own balance, and closes the advance. Caliber takes nothing from it. It is a resolution, not a default: it makes no accusation and needs no keeper, and the public record calls it a resolution. It covers every way an advance can end badly — the agent routed settlements away, the jobs were rejected, or nobody delivered them and they expired — which is why it exists: the most ordinary of those paths produces no routing-away evidence at all.
The provider's loss is therefore at most the advance minus the collateral, and nothing about recovery waits on anyone's judgement.
A settlement that reaches the splitter after resolution — ERC-8183 lets an evaluator accept a delivered job even after its deadline — goes to the agent: the advance is closed.
The cure window is fixed when the splitter factory is deployed and has no setter. The reference value is 24 h, which is what a mainnet deployment uses. The Arc testnet deployment of 23 September 2026 uses 1 hour, so that a maturity and a resolution can be run and observed inside a working day; the funding page states the deployed value.
Routing-Away Default — Factor's Default Definition
Distinct from the Rating's performance-default (work rejected — a property of work quality), Factor defines one default: routing-away — a property of the advance.
Definition: while an advance is outstanding, a factored job settles to an address other than the registered splitter, or the agent re-points its payout address away from the splitter. Both are provable on-chain.
Detection and consequence: a keeper marks the breach with the settlement evidence; a cure window lets the agent remit and clear the mark; past the window anyone may execute recovery, which applies the reserve and then the collateral to what is owed, capped at what is owed, in one call — there is no owner-gated first step. The mark's cure deadline is fixed when the mark is made. The evidence is a citation, not a proof: a mark must cite something, and nothing on chain can verify that the citation resolves, because the breach is the absence of a settlement.
A routing-away default closes an advance before its maturity; maturity closes it in every other case (§Maturity). The Rating is not altered by a routing-away default directly, but the mark is public, and the outcome is published (§Outcomes).
v1.0 history: on the v1 contracts the reserve seizure was owner-only on the deployed testnet factory, which left the bond slash waiting on Caliber. The V2 contracts remove that step; v1 splitters take no new advance.
Outcomes, Published
Each closed advance's outcome is written to the ERC-8004 Reputation Registry against the agent's identity, by a permissionless call that anyone may make once per advance and that is never part of repayment — so a registry that refuses a write can delay a record but never a payment.
tag1=caliber.factor.v1;tag2=repaid·resolved·defaulted;value= the whole-percent share of principal + fee that reached the provider (100 = made whole).
resolved is its own word: an advance closed at maturity is not an accusation.
The agent's right of reply is ERC-8004's own appendResponse. The registry
keeps records forever, so ageing is a rule for reading them: weight a record
by 0.5^(age / 180 days) and disregard it after 730 days.
The Pricing Model
What a fee would need to cover on an advance, in absolute USDC: the expected
loss after the collateral (δ × max(0, advance − collateral), with δ from
Step 2), the cost of the capital for the time to maturity, and Caliber's
servicing. It is built now so that it can be fitted on mainnet. On testnet
every input is synthetic or measured on Caliber's own activity, it is labelled
so, and it does not set the fee — the fee is the published flat rate. It is
not a predictive rate and is not published as one.
Defense in Depth Against Self-Financing
The primary defense is exclusion: self-dealt and circular escrow counts $0
at Gate 2, so manufactured backlog buys no advance. The escrow arithmetic is
not a second layer against collusion, and this paper previously said it was.
The invariant advance < escrow locked protects a provider only if that escrow
settles to the splitter. A disguised self-hirer controls the other side of the
job: its confederate client — or its confederate evaluator — can reject the
work, or let it expire, and ERC-8183 refunds the escrow to that client. Nothing
settles and nothing is routed away. On the v1 contracts no default could be
marked and nothing was seized; from v1.2 the advance matures, and resolution
applies the reserve and the self-hirer's collateral to what is owed. The
self-hirer keeps the advance and loses its collateral, and nets
advance − collateral. What stands between the book and collusion is therefore
the independence gates and the size of the collateral — which flow sizing now
makes at least as large as any advance while no independent flow exists — not
the arithmetic. For an agent that is not colluding the arithmetic
still matters: walking away forfeits its own customers' escrow, which is
usually worth far more to it than the advance.
Where the arithmetic layer is enforced, at v1.0. FactorVerifier .requireAdvanceWithinBounds implements both published bounds — advance ≤ advance_rate × advanceable_backlog and advance < Σ escrow_i — and refuses
the amounts they forbid. But a provider must choose to route its advance
through it: CaliberSplitterFactory.openAdvance, the function that records an
advance, takes the skim rate and the principal as parameters and does not
itself consult the verifier. So at v1.0 the arithmetic layer is a check a
provider performs, not a property the advance path enforces. An independent
review on 2026-09-07 found this paper describing it as structural, and it was
not; the sentence you are reading is the correction.
The exclusion layer is unaffected — it runs off-chain in the eligibility
engine before any attestation is signed, which is where it always ran. What
changes is only the claim about the second layer: it is available and
published, it is not automatic. Making openAdvance consume a
FactorAttestation is the mainnet design and is deliberately not being
retrofitted to the testnet deployment, because redeploying the factory
re-keys the CREATE2 splitter clones that already-seeded jobs name as their
ERC-8183 provider.
What This Is / Is Not
It is: a neutral, permissionless eligibility-and-control layer for advances against escrowed ERC-8183 receivables; deterministic and reproducible given its inputs; a consumer of Caliber Rating v2.1.0 attestations.
It is not: the lender (no capital, no sizing decision) · a credit-line or pricing recommendation · a credit rating or PD/LGD model · legal recourse or KYC · a forecast of future earnings (that is Coverage, unshipped) · financial advice.
The Honest Disclaimers
- ⚖️ No legal recourse. On-chain controls only; the provider disclosure above applies in full.
- 🧪 Not calibrated, and testnet cannot calibrate it. Every value in this document is an editorial starting point, not fitted to resolved-advance data — none exists yet. Nor can testnet supply it: the only Arc population with enough eligible escrow to fit against is a cohort we provisioned ourselves, and fitting a parameter to activity we constructed is circular, not calibration. The parameters stay provisional until the proving period below closes on live mainnet outcomes. Until then the guarded-launch caps, not the parameters, are what bound the downside.
- 🔌 The splitter is a rail, not a lock. A sovereign agent can re-route or respawn. Routing-away is made provable and costly, abandonment is made irrational by the advance cap, the reserve and the collateral — not impossible. The fuller willingness-to-pay framework (franchise value, loan-to-franchise sizing) lives in Coverage, unshipped. The loss bound is the advance minus the collateral: at maturity — whatever went wrong, including jobs rejected or expired and escrow refunded to the client — the reserve and then the collateral are applied to what is owed. Beyond the collateral the loss is the provider's.
- 🎯 Evaluator noise is inherited. If a lenient client accepts bad work, the escrow settles and the haircut never sees it — Factor inherits the Rating's evaluator-quality gap.
- 📉 Dispute risk is priced, not eliminated. δ is a haircut on history, not a guarantee about the next job.
- 🤝 Garbage in, garbage out. Every limitation of the underlying ERC-8183 event data flows through.
Provisional Parameters and the Proving Period
None of these values is signed off, and none is operative on its own. They are published so the calculation is reproducible and so the eventual recalibration has a stated starting point — not because they are calibrated.
The proving period runs from the Arc mainnet deployment until
resolved-advance data exists to review them against: advances that have been
funded and have either fully repaid or defaulted. During it, every attestation
carries the provisional marker, the guarded-launch caps are held at their
conservative setting, and the participating agents and providers are
allowlisted. Sign-off at the end is a dated, event-logged act that closes the
period and moves the version from 1.2.0-provisional to 1.2.0 — not an
assumption made by anyone's silence. Should the review move a value, that is a
material change: it is published, and it takes effect when it is published. An
advance already open keeps the terms it was opened under.
| Parameter | Provisional value | Owner | Read from |
|---|---|---|---|
| δ_min — dispute-haircut floor | 5% | Caliber, published | engine |
| w_min — diversification-weight floor | 0.30 | Caliber, published | engine |
| Cycle-detection depth | 3 hops | Caliber, published | engine |
| Fresh-counterparty age / history | 14 days / ≥1 unrelated settled job | Caliber, published | engine |
| Agent quality gate | Bronze+ tier, no active flag | Caliber, published | engine |
| Advance rate | 0.55 reference | Provider, within caps | engine |
| Factoring fee | 2.40% of advance — flat, one-time, at acceptance | Provider, within published range | engine |
| skim_rate | 80% of factored settlements | Provider, ≥ sizing rule; ≤ 100% − reserve_rate for the reserve to accrue | engine |
| reserve_rate / target | 5% / 10% of advance | Caliber, published | engine |
| Bond | 3% / 4% / 5% of advance (Gold / Silver / Bronze), floor 25 USDC | Caliber, published | engine |
| Cure window | 24 h | Caliber, published | contract |
| Guarded-launch caps (per-agent, global, allowlist) | published at deploy | Caliber, event-logged | deploy config |
| Aggregation unit | payout address, siblings unioned | Caliber, published | engine |
Rows marked engine are read at render time from the eligibility engine’s own parameter module, not transcribed into this document — so the published number and the computed number cannot drift apart. Attestations issued while these values are provisional carry the methodology version 1.7.0-provisional; closing the proving period is what removes the marker.
Relationship, Versioning, Provenance
Own version line: Caliber Factor v1.x. Not Rating v3.0 (nothing in the
performance rating changes — attestation bytes, tiers, weights, deployed
RatingVerifier all untouched) and not Coverage v1.x (a different object:
Factor measures committed escrow; Coverage would measure loans against
projected cash flow). Factor adopts the Rating's governance wholesale:
published versions, a change log, and a dedicated on-chain version pointer in
FactorVerifier. A published change takes effect when it is published. The
dual-version acceptance that follows a version bump is a property of the
contract, not a notice period: FactorVerifier accepts the current version and
the immediately-previous one, and the previous one stops verifying when the next
bump displaces it.
Consumes Rating v2.1.0 (not v2.0.1 — older Factor materials citing 2.0.1 are superseded). Supersedes the Coverage draft's disclaimer that "full counterparty-graph cycle detection is future work": v1.0 ships it as Gate 2.
Provenance. Factor is the disciplined subset of the Caliber Coverage v1.1 draft (May 2026): the neutrality boundary, δ, the diversification logic, the skim rail, the bond, and the routing-away breach concept are inherited; the velocity forecast (v̂), CFADS/DSCR ratios, breach state machine, margin calls, mark-to-market franchise, and credit-line sizing are deliberately excluded — they underwrite lending, not factoring, and the data to calibrate them does not yet exist. The same instinct that retired the v1.0 credit-rating framing applies: ship only what the evidence supports.
Future Work: Caliber Coverage
Everything fenced out above has a home. Caliber Coverage — continuous cash-flow coverage for agent loans (live DSCR, dual-trigger covenants, franchise-bounded sizing) — remains a designed-but-unshipped sibling on its own future version line. It is explicitly not part of the Factor release and nothing in a Factor deployment depends on it.
Change History
| Version | Date | Changes |
|---|---|---|
| 1.2 | 2026-09-23 | The V2 contracts, on Arc testnet (operator decision of 23 Sep: ship now on testnet; one release applies to mainnet only). (1) Maturity and mechanical resolution: every advance matures at its latest financed job's deadline plus the cure window, and anyone may then apply reserve and collateral to what is owed — a resolution, not a default. (2) Earned collateral: the reserve joins the agent's collateral at repayment instead of being paid out; collateral replaces the per-advance bond, is required before funding, and is withdrawable only with nothing outstanding. (3) Flow-based sizing: the advance is the smaller of the escrow ceiling and collateral + 0.8 × expected independent flow; no client qualifies until the funding-source test can run, and Caliber's own wallets never do. (4) Permissionless recovery in one call after an uncured routing-away default. (5) Outcomes published to the ERC-8004 Reputation Registry. (6) A pricing model, synthetic on testnet, that does not set the fee. The collateral asset is a deployment parameter and must be USDC. Attestations issued from publication cite 1.2.0-provisional; FactorVerifier accepts it and the immediately-previous 1.1.0-provisional. The testnet deployment's cure window is 1 hour (reference 24 h). |
| 1.1 | 2026-09-23 | Gate 2 excludes a job whose ERC-8183 evaluator is the agent's own side — its wallet, operator or splitter — because the evaluator alone decides whether funded work completes, and an agent that evaluates itself confirms its own escrow. Measured on Arc before the change: 1.4% of funded jobs, which completed at 19.6%. Gate 2's text never named the evaluator, so this is a change to a gate and a new minor version, not a correction. And a client-evaluator weight, published and set to 1.0 (§Step 2): 73.5% of funded Arc jobs are evaluated by the client paying for them; the risk is disclosed rather than priced until mainnet data can fit it. No other gate, weight, rate or attestation field changes. Attestations issued from publication cite 1.1.0-provisional; FactorVerifier accepts it and the immediately-previous 1.0.0-provisional, so an attestation issued under v1.0 still verifies. v1.0 stays readable at its own URL, marked superseded. |
| 1.0 · corrections | 2026-09-23 | Three sentences promised providers protection the contracts do not deliver, and Gate 1 counted escrow the client could already take back. (1) §Defense in Depth called the escrow arithmetic a second layer — "down before it even defaults, with reserve and bond seized on top", under a slogan this row does not repeat. On a rejected or expired job ERC-8183 refunds the escrow to the client, no routing-away default exists to mark, and nothing is seized; a colluding self-hirer nets advance − bond. Rewritten. (2) §Known Limitations told providers to treat the bond and reserve together as their loss bound; the loss bound is the whole advance. (3) Gate 1 now excludes a Funded/Submitted job past its expiredAt: claimRefund() is callable by anyone from that moment and returns the escrow to the client, and the index does not record the refund, so such jobs were being counted as confirmed escrow — measured 23 Sep, of 5,298 jobs the index listed as in flight, 5,077 were past expiry and 90 already refunded. No weight, rate, cap or attestation field changes. Ops ruled on 23 Sep that (3) is a correction, not a gate change: Gate 1 already justifies itself by what is locked, and escrow anyone can refund is not locked. Gate 1's text now carries the expiry clause explicitly. REQUEST-033 §1 and §3. |
| 1.0 · corrections | 2026-09-19 | The 30-day notice rule was withdrawn on 19 September 2026. Operator decision. Changes to prices, the bond table, caps, reference parameters and methodology versions now take effect when they are published. No parameter, gate, formula or attestation field changes, so neither the document version nor the 1.0.0-provisional stamp moves — this is a corrections revision of v1.0 in place, at the same URL, on the same reasoning as the 2026-09-07 entry below: a version bump would falsely signal a methodology change. What was not withdrawn: an advance opened before a change keeps the terms it was opened under. Dual-version acceptance also survives, because it was never the notice rule — FactorVerifier accepts the current version and the immediately-previous one, and the previous stops verifying when the next bump displaces it, with no expiry date. |
| 1.0 · corrections | 2026-09-07 | Six places where this paper claimed more than the deployment delivers. No parameter, gate, formula or attestation-field changes, so neither the document version nor the 1.0.0-provisional version stamped on attestations moves, and no 30-day notice is owed. This is a corrections revision of v1.0 in place, at the same URL, recorded here rather than issued as a new version: a version bump would falsely signal a methodology change and open a dual-version acceptance window for nothing. Every edit below narrows a claim to what is true, in the same commit as the code it describes. Prompted by an independent review of the Factor rail (docs/seoul/reports/REVIEW-2026-09-07.md) which was given the published spec and the deployed artifacts and told to find where they disagree. (1) The arithmetic layer is a provider check, not a contract guarantee, at v1.0. FactorVerifier.requireAdvanceWithinBounds implements both published advance bounds correctly and nothing on the advance path calls it — CaliberSplitterFactory.openAdvance takes the principal and skim rate as free parameters. §Defense in Depth said "structural"; it is available and published, not automatic. On-chain consumption is the mainnet design and is deliberately not retrofitted, because redeploying the factory re-keys the CREATE2 clones that seeded jobs name as provider. (2) The permissionless two-leg seizure is mainnet-only until the factory is redeployed. draft4(5) asserted it as current fact; the deployed testnet factory predates that change and holds no FactorBond reference at all, which by this paper's own all-or-nothing argument makes the permissionless second leg unreachable there. (3) Gate 2 traverses funding edges only. The text said "ownership-or-funding path"; ownership edges are not traversed, because beneficial ownership is not observable on-chain beyond the NFT owner already folded into the agent's addresses. Also now states that the edge set is a materialized view refreshed daily, so a cycle constructed after the last refresh is invisible for up to 24 h — staleness hides paths, it cannot invent them, which is the wrong direction for an anti-fraud gate and is better said than found. (4) Gate 1's dispute exclusion is vacuous on Arc. AgenticCommerce has no Disputed state and validations carries no job_id, so no job-level dispute exclusion is possible even in principle; a Submitted job whose validation came back FAILED contributes its full escrow. The fix is a Rating-side schema link. (5) A default mark's evidence is a citation, not a proof — non-empty is now enforced, but nothing on-chain can verify the reference resolves, because the breach is the absence of a settlement and a contract cannot observe an absence. Also: a mark's cure deadline is now fixed when the mark is made, so shortening the window cannot collapse a cure period already running. (6) The attestation's bps rounding has a published tolerance. δ and w are carried rounded while the backlog is computed from full precision, so an honest attestation can miss exact equality by ~1 bp; toleranceBps = 1 is the published minimum and 0 can reject a correct attestation. Nonce consumption is additionally restricted to allowlisted consumers. |
| 1.0-draft5 | 2026-09-07 | The engine was measuring the wrong pot of money. No parameter changes. (1) Eligible escrow is now gathered from the agent's payout address — its registered splitter — not from its identity addresses. ERC-8183 fixes provider at createJob, so escrow naming the agent's own wallet can never be skimmed; the engine had been computing the advanceable backlog over exactly the escrow a repayment rail cannot reach, and on the seeded cohort both pots happened to hold 1.00 USDC, so the arithmetic looked correct while describing unreachable collateral. An agent with no splitter now has a backlog of zero and the attestation route refuses (no_repayment_rail) rather than signing a number no advance could repay from. Gate 2 additionally treats the payout address as the agent's own, since funding one's own splitter is the shape a manufactured advance base would actually take. (2) Gate 3's block→time conversion is now local interpolation between the nearest real block timestamps rather than one line fitted across all history: on Arc the global fit implies 5.63 blocks/sec against a current ~1/sec and misdated 1 Sep as 5 Sep — safe in direction, but it would have moved the seeded cohort's Gate 3 from 15 Sep to ~19 Sep. Both fallbacks err toward reporting a client as younger, because for an anti-fraud gate over-rejecting is the survivable error. |
| 1.0-draft4 | 2026-09-06 | Five places where the paper described a control the code did not have. No parameter changes; every edit here brings the document into line with what now ships, in the same commit as the code. (1) The sibling union is implemented, not merely specified. draft2 announced that Gate 4 evaluates the worst tier and the union of flags across registrations sharing a payout address; the engine reported the siblings and evaluated the gate per agent id anyway, leaving the exact bypass the paper names — attest through the clean sibling while the flagged one draws on the same escrow — open. unionSiblingQuality() now takes the maximum tier ordinal and the OR of flags, the attestation route refuses on it and names the binding sibling, and an unrated sibling is counted rather than assumed clean. (2) δ's derivation is written down. It is 1 − completion_rate_smoothed: a 30-day window, credibility-blended toward the per-chain population mean, over a denominator that counts Expired, Cancelled and Refunded alongside Rejected. That is a defensible proxy for "credibility-weighted dispute rate" and a broader one than the phrase implies, so it is stated rather than left to be rediscovered by anyone reproducing δ. (3) Gate 3's identity age is measured on chain time, via a block→timestamp fit, not on the indexer's insert timestamp — which differs by months across any backfilled range and would have made every client on the chain read as newly minted after a re-backfill. (4) The bond schedule is Factor's own on chain. draft3 moved the published table to 3/4/5% of the advance with a 25 USDC floor, but FactorBond still read CaliberEscrow.requiredBond() — bps of a job budget — and answered $0.50 for a $100 advance against a published floor of $25. The contract now implements the published table, asserted against params.ts in both test suites. (5) Permissionless slashing covers both legs. The reserve is seized before the bond, and reserve seizure was owner-only, so the permissionless bond slash was unreachable and a provider's recovery depended on Caliber acting. seizeReserve() now opens to any caller the moment FactorBond.slashable() reports an uncured mark past the cure window, and stays owner-only before it. |
| 1.0-draft3 | 2026-09-06 | Skim/reserve compatibility, Factor's own bond schedule, and the fee's shape. Three operator-signed parameter changes, all from designing the surfaces that render them. (1) The reference skim_rate moves from 100% to 80%. At 100%, skim + reserve = 105% of a settlement, so under the waterfall's repayment-first seniority the reserve slice is zero by construction — the paper described a mechanism its own default configuration could never exercise, and an end-to-end demonstration of the earned reserve requires one that actually accrues and releases. The seniority rule and the skim_rate + reserve_rate ≤ 100% accrual condition are now stated explicitly; a 100% skim stays a permitted provider choice, documented as dormant by design and shown to be safe (at a full skim the reserve is redundant, since provider exposure is unchanged whether a dollar repays or is retained as seizable collateral). The reserve's purpose is restated honestly: it is what makes partial-skim configurations safe, by forcing part of the agent's retained cash into a seizable bucket. (2) The bond leaves the CaliberEscrow per-job schedule for Factor's own tier-stepped table — 3% / 4% / 5% of the advance for Gold / Silver / Bronze, floor 25 USDC. The escrow table is bps of a job budget, a different quantity gating a different failure, and 150 bps of an advance does not deter routing away from it. The base is the advance rather than the backlog because a bond must be a fixed known amount at posting and the backlog moves with every settlement. (3) The factoring fee is specified for the first time: flat, one-time, charged at acceptance, provider-set within a published range, 2.40% reference at the pilot tenor, and part of outstanding so the skim captures it. Gates, δ, w, the caps, the attestation fields, the cure window and the slash waterfall are unchanged. |
| 1.0-draft2 | 2026-09-01 | Provisional-parameter regime and the payout-address aggregation unit. Three changes, all from building the engine against live data. (1) Parameters are restated as provisional and non-operative rather than "reference values pending sign-off", with a defined proving period that closes only on resolved-advance outcomes from mainnet; the disclaimer now states plainly that testnet cannot calibrate Factor, because the only population with enough eligible escrow is one we provisioned ourselves. (2) Aggregation moves from per-agent-id to per payout address: one Arc wallet holds 143 registrations over $51.25 of escrow, so summing per agent id reported $5,609.25 advanceable where $41.55 exists. (3) Gate 4 now evaluates the union of siblings (worst tier, OR-ed flags) — the same wallet spans Silver and Watch, so a per-agent-id gate was bypassable by attesting through a clean sibling. Also corrects the Step 2 worked example, which asserted w ≈ 1.00 for four equal clients while the formula immediately above it gives 1 − HHI = 0.75; the formula was right and the example wrong, so the table is restated with explicit client shares and the w_min floor shown doing its job. Gate definitions, δ, w, caps, the attestation fields and the waterfall are unchanged. |
| 1.0-draft | 2026-09-01 | First Factor methodology, extracted and narrowed from Coverage v1.1 draft. Adds: four binary eligibility gates (incl. multi-hop cycle detection), per-agent δ from credibility-weighted dispute rate, w over the eligible set (self-deal term dropped — excluded upstream; divergence from Coverage disclosed), advance-rate cap structure, FactorAttestation struct, splitter waterfall with reserve accrual/release rules, routing-away default with cure window and permissionless slash, guarded-launch cap governance, reference-parameter table. Removes (to Coverage): v̂, CFADS, DSCR, breach state machine, franchise mark-to-market, credit-line sizing. |
| 1.0 | 2026-09-07 | Publication. The drafting sequence closes and the document is published at a stable, versioned URL, so an on-chain FactorAttestation cites a public specification rather than a repository file. No change to any gate, parameter, formula or control since 1.0-draft5 — publication is not a content change, and saying so is the point of a change history. Parameters remain provisional and non-operative: they are re-stated against the mainnet deployment and become operative only when the proving period closes on resolved-advance outcomes. |
Caliber Factor v1.2 · September 2026 · Bangkok 🇹🇭 Neutral eligibility & control layer. The capital provider owns the credit decision. Standards-native, open methodology — improves by getting punched.