Chio/Docs
LOGIN · JOIN

EconomyCredit

Credit Scorecards

A CreditScorecardReport combines reputation, exposure, and settlement history into one of five bands.


Five bands

Every scorecard resolves to one of five bands. Bands are ordinal, from most permissive to most restrictive:

crates/economy/chio-credit/src/lib.rsrust
pub enum CreditScorecardBand {
    Prime,
    Standard,
    Guarded,
    Probationary,
    Restricted,
}

The band is a categorical output, not a numeric cut. The crate encodes no score threshold per band: the band follows from the reason codes, the anomalies, and the confidence the evidence supports. What each band then does to a credit facility is fixed, and per-band consequences below carries the exact factors.

BandWhat puts a subject here
PrimeHigh score, clean settlement record, no loss pressure.
StandardHealthy default tier.
GuardedMild signals of stress: slow settlement, a mixed-currency book, modest loss pressure.
ProbationarySparse receipt history, sparse day coverage, or low confidence. It yields no facility terms and sends the decision to manual review.
RestrictedPersistent failed settlements, outstanding provisional losses, or low reputation. The facility disposition is always a denial.

Four dimensions

A scorecard exposes the band's reasoning across four scored dimensions. Each dimension carries an optional 0.0 to 1.0 score, a weight, a description, and evidence references back to the receipts, decisions, or attestations that justify it:

crates/economy/chio-credit/src/lib.rsrust
pub enum CreditScorecardDimensionKind {
    ReputationSupport,
    SettlementDiscipline,
    LossPressure,
    ExposureStewardship,
}

pub struct CreditScorecardDimension {
    pub kind: CreditScorecardDimensionKind,
    pub score: Option<f64>,
    pub weight: f64,
    pub description: String,
    pub evidence_refs: Vec<CreditScorecardEvidenceReference>,
}
DimensionWhat it scores
ReputationSupportThe composite reputation score for the subject, attenuated by imported-trust dependencies.
SettlementDisciplinePending vs failed settlement counts on the subject's receipts.
LossPressureProvisional loss amounts still outstanding against the subject.
ExposureStewardshipConcentration, currency mix, and reserve-aware utilization patterns.

Confidence

crates/economy/chio-credit/src/lib.rsrust
pub enum CreditScorecardConfidence {
    Low,
    Medium,
    High,
}

Confidence indicates whether the scorecard has enough evidence to support its band. An agent with a strong reputation score but only 12 receipts cannot get the same band as an agent with the same score and 12000 receipts. Sample size determines confidence; confidence in turn caps the band.

The probation block on the report makes the receipt-count and time-span thresholds explicit:

crates/economy/chio-credit/src/lib.rsrust
pub struct CreditScorecardProbationStatus {
    pub probationary: bool,
    pub reasons: Vec<CreditScorecardReasonCode>,
    pub receipt_count: u64,
    pub span_days: u64,
    pub target_receipt_count: u64,
    pub target_span_days: u64,
}

While receipt_count < target_receipt_count or span_days < target_span_days, the subject is probationary. The reason codes attached to the status say which threshold is missing:

crates/economy/chio-credit/src/lib.rsrust
pub enum CreditScorecardReasonCode {
    SparseReceiptHistory,
    SparseDayHistory,
    LowConfidence,
    PendingSettlementBacklog,
    FailedSettlementBacklog,
    ProvisionalLossPressure,
    MixedCurrencyBook,
    LowReputation,
    ImportedTrustDependency,
    MissingDecisionCoverage,
}

Anomalies and severity

Anomalies are typed reasons the band would otherwise be too high for the underlying signal. They reuse the same reason-code enum and attach a severity:

crates/economy/chio-credit/src/lib.rsrust
pub enum CreditScorecardAnomalySeverity {
    Info,
    Warning,
    Critical,
}

pub struct CreditScorecardAnomaly {
    pub code: CreditScorecardReasonCode,
    pub severity: CreditScorecardAnomalySeverity,
    pub description: String,
    pub evidence_refs: Vec<CreditScorecardEvidenceReference>,
}

A scorecard with a strong composite score but a FailedSettlementBacklog anomaly at Critical severity will be band-shifted toward Restricted regardless of how clean the reputation looks.


Report shape

crates/economy/chio-credit/src/lib.rs519-531rust
pub struct CreditScorecardReport {
    pub schema: String,
    pub generated_at: u64,
    pub filters: ExposureLedgerQuery,
    pub support_boundary: CreditScorecardSupportBoundary,
    pub summary: CreditScorecardSummary,
    pub reputation: CreditScorecardReputationContext,
    pub positions: Vec<ExposureLedgerCurrencyPosition>,
    pub probation: CreditScorecardProbationStatus,
    pub dimensions: Vec<CreditScorecardDimension>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub anomalies: Vec<CreditScorecardAnomaly>,
}

schema is CREDIT_SCORECARD_SCHEMA, chio.credit.scorecard.v1. The summary is where the whole book collapses into one row:

crates/economy/chio-credit/src/lib.rs503-515rust
pub struct CreditScorecardSummary {
    pub matching_receipts: u64,
    pub returned_receipts: u64,
    pub matching_decisions: u64,
    pub returned_decisions: u64,
    pub currencies: Vec<String>,
    pub mixed_currency_book: bool,
    pub confidence: CreditScorecardConfidence,
    pub band: CreditScorecardBand,
    pub overall_score: f64,
    pub anomaly_count: u64,
    pub probationary: bool,
}

The CreditScorecardSupportBoundary on each report declares what the report authoritatively covers. The default boundary is subject_scoped_only = true with cross-currency netting, capital allocation, and facility policy support all turned off.


How a scorecard is produced

A scorecard is built from three local sources, all of which the operator already maintains:

  • Reputation: a LocalReputationScorecard for the subject (see Reputation Scoring), with imported-signal acceptance counted.
  • Exposure: an ExposureLedgerReport (schema chio.credit.exposure-ledger.v1) covering the subject's receipts and underwriting decisions in the window.
  • Settlement: per-receipt SettlementStatus (Pending, Failed, Settled, etc.) drives both settlement discipline and loss pressure dimensions.

Export a scorecard with chio trust credit-scorecard export, or read the same signed report through trust-control at GET /v1/reports/credit-scorecard. Both emit the chio.credit.scorecard.v1 report documented above; the export resolves against a local receipt store (--receipt-db) or a remote trust-control service (--control-url). Optional flags narrow the window (--since, --until) and the row budget (--receipt-limit, default 100, and --decision-limit, default 50).

The scorecard does not mint capital. It is an evaluation report, and the capital decision is a separate artifact: a CreditFacilityReport (schema chio.credit.facility-report.v1) carries the scorecard summary in its scorecard field and adds a disposition, prerequisites, terms and findings on top of it. The CreditFacilityArtifact (schema chio.credit.facility.v1) then wraps that report with a facility id, an expiry, and a lifecycle state.


Worked example

A subject with three governed receipts against one tool server, each carrying a 2500 minor-unit USD ceiling, and one underwriting decision on the same subject.

Run it

The receipts the export scores, listed with the governed amount each one carried:

credit-scorecard · receiptstranscript
$ chio --receipt-db ./receipts.db receipt list --admin-all \
    | jq -r '[.decision.verdict, .tool_server, .tool_name, .metadata.governed_transaction.max_amount.units] | @tsv'
allow	ledger	settle_invoice	2500
allow	ledger	settle_invoice	2500
allow	ledger	settle_invoice	2500
exit 0

Expected output

Without --json the command prints eleven aligned lines: the schema, the generation time, the key that signed the export, the subject, and the summary fields that decide the band.

credit-scorecard · exporttranscript
$ SUBJECT=$(chio --receipt-db ./receipts.db receipt list --admin-all \
    | jq -r '.metadata.attribution.subject_key' | head -1)
$ chio --receipt-db ./receipts.db trust credit-scorecard export \
    --agent-subject "$SUBJECT" \
    --authority-seed-file ./authority.seed
schema:                 chio.credit.scorecard.v1
generated_at:           1788542733
signer_key:             fb4d4902815fd5db1e628702eeb87c48271872ac2fde57298767c3f8c04f9402
subject_key:            3b9ed9e1a200eec3b3fcc461f54ca1cf8af94e7ab205751d0d330320afedcb41
overall_score:          0.6000
confidence:             Low
band:                   Probationary
probationary:           true
matching_receipts:      3
matching_decisions:     1
anomaly_count:          1
exit 0

Three receipts clear neither target_receipt_count nor target_span_days, so probationary is true, confidence resolves to Low, and the band lands on Probationary even though the settlement record is clean. The single anomaly is the one that low confidence itself raises.

With --json the same run emits a SignedExportEnvelope instead: a body holding the report, a signerKey, and a signature over the canonical JSON of the body, with deny_unknown_fields and camelCase keys. The block below pipes that envelope through jq '.body.summary', so the camelCase keys and the snake_case enum values are the wire form of the summary struct above:

credit-scorecard · export-summary-jsontranscript
$ SUBJECT=$(chio --receipt-db ./receipts.db receipt list --admin-all \
    | jq -r '.metadata.attribution.subject_key' | head -1)
$ chio --receipt-db ./receipts.db --json trust credit-scorecard export \
    --agent-subject "$SUBJECT" \
    --authority-seed-file ./authority.seed \
    | jq '.body.summary'
{
  "matchingReceipts": 3,
  "returnedReceipts": 3,
  "matchingDecisions": 1,
  "returnedDecisions": 1,
  "currencies": [
    "USD"
  ],
  "mixedCurrencyBook": false,
  "confidence": "low",
  "band": "probationary",
  "overallScore": 0.6,
  "anomalyCount": 1,
  "probationary": true
}
exit 0

When it refuses

The export is signed and computed from receipts rather than defaulted, so it refuses on either gap before emitting anything. Without a signing key it exits 1 with an empty stdout:

credit-scorecard · export-unsignedtranscript
$ SUBJECT=$(chio --receipt-db ./receipts.db receipt list --admin-all \
    | jq -r '.metadata.attribution.subject_key' | head -1)
$ chio --receipt-db ./receipts.db trust credit-scorecard export \
    --agent-subject "$SUBJECT"
error [urn:chio:error:cli:other]: behavioral feed export requires --authority-seed-file or --authority-db so the export can be signed
context: {"domain":"cli","severity":"error","stability":"deprecated","string_code":"CHIO-CLI-OTHER"}
suggested fix: Preserve the original message and migrate the call site to a specific registry code when touched.
exit 1

With a key, against a store holding no receipt for that subject, it exits 1 the same way:

credit-scorecard · export-empty-storetranscript
$ SUBJECT=$(chio --receipt-db ./receipts.db receipt list --admin-all \
    | jq -r '.metadata.attribution.subject_key' | head -1)
$ chio --receipt-db ./empty.db trust credit-scorecard export \
    --agent-subject "$SUBJECT" \
    --authority-seed-file ./authority.seed
error [urn:chio:error:cli:other]: credit scorecard requires at least one matching governed receipt
context: {"domain":"cli","severity":"error","stability":"deprecated","string_code":"CHIO-CLI-OTHER"}
suggested fix: Preserve the original message and migrate the call site to a specific registry code when touched.
exit 1

A third refusal sits between those two and catches the case the wording above does not describe. The first gate counts receipts; the second needs money on them. credit_scorecard_position_denominator returns a value only when governed exposure, or settled plus pending plus failed units, is above zero, and without one the export answers credit scorecard requires monetary exposure in the requested window. A subject whose receipts carry no governed_transaction.max_amount and no charged cost has receipts to count and nothing to score, so it stops here rather than reporting a zero.

There is no zero-evidence scorecard to read. The local reputation scorer returns Unknown metrics against an empty store; the credit export declines to sign anything at all.


Per-band consequences

The band does not translate into terms through operator judgement. The facility report derives the disposition first, and builds terms only when the disposition is Grant.

  • Deny when the band is Restricted, or the subject misses the minimum runtime assurance tier, or certification is required for the tool server and no active certification is present.
  • ManualReview when the book is mixed-currency, or the scorecard carries FailedSettlementBacklog or PendingSettlementBacklog, or the subject is probationary, or the runtime-assurance evidence came from more than one verifier family.
  • Grant otherwise.

The credit limit is the subject's own exposure scaled twice, by the band and then by confidence, and floored: floor(base_units × band_factor × confidence_factor). The confidence factors are 1.0 for High, 0.9 for Medium and 0.75 for Low. The band factors and the rest of the terms:

BandLimit factorUtilization ceilingReserve ratioConcentration capTerm
Prime1.09000 bps1000 bps3500 bps30 days
Standard0.858000 bps1500 bps3000 bps14 days
Guarded0.656500 bps2500 bps2000 bps7 days
Probationary0.40No terms. The builder returns None for this band, and the disposition is ManualReview anyway.
Restricted0.0No terms and no facility. The disposition is Deny.

The two weakest bands demand the strongest attestation

credit_facility_minimum_runtime_assurance_tier asks RuntimeAssuranceTier::Attested of Prime, Standard and Guarded, and Verified, the strictest tier, of Probationary and Restricted. A subject with a thin history that cannot produce verified runtime attestation is denied on the prerequisite before the band is weighed.

Terms carry their own ttl_seconds, which is what expires a granted facility. A report without terms falls back to seven days for Grant and ManualReview, and one day for Deny. Every granted facility is stamped CreditFacilityCapitalSource::OperatorInternal, so the capital behind it is the operator's own.


See also

Credit Scorecards · Chio Docs