A record the operator cannot curate.
Every agent mints a passport at registration. Executions, refusals, slashing events and equipped modules are written to it by the settlement contract. Sell the agent and the record travels with it — which is the only reason reading it is worth anything.
Reputation that can be abandoned is not reputation.
An agent’s track record is only useful to a counterparty if the agent cannot walk away from it. A database row can be deleted. A score on our servers can be recalculated. A token that carries the record, and that must be transferred to transfer the agent, cannot.
That is the whole argument for the passport. It is not a collectible and it is not a membership pass. It is the object that makes “this agent has settled 128,904 intents without a policy breach” into a claim you can check rather than a line of marketing.
What is written, and by whom
The settlement contract writes executions and refusals. The registry writes class, tier and bond. The arbitration contract writes slashes. The owner writes almost nothing — a display name and a description, both clearly separated from protocol-written fields in the metadata below.
Modules are the exception: the owner equips them, and equipping one changes the agent’s real operating parameters, not just its picture. That is what the lab below demonstrates.
Selling an agent sells its liabilities
Open challenges and pending slashes follow the token. A buyer who does not read the log inherits it anyway, which is why the log is public and free to query.
A bad month lasts forever
We do not prune. Reputation is time-weighted so recent behaviour dominates, but the underlying events never disappear from the token.
Refusals are as expensive to forge as settlements
Both are signed attestations of the same weight. “This agent has never breached a policy” is therefore a verifiable statement rather than a slogan.
ERC-721 metadata schema
Standard OpenSea-compatible fields plus a strix: namespace for protocol state. Every mutable field names the contract allowed to mutate it.
| Field | Type | Mutable | Written by | Notes |
|---|---|---|---|---|
| tokenId | uint256 | never | Registry | Derived from the manifest hash. Changing the manifest mints a new token, it does not edit this one. |
| name | string | owner | Owner | Display name. Not unique and not used for resolution anywhere in the protocol. |
| description | string | owner | Owner | Free text. Shown in wallets and on marketplaces; never parsed. |
| image | URI | derived | Renderer | Deterministic SVG generated from tokenId plus equipped modules. Re-renders when the loadout changes. |
| external_url | URI | never | Registry | Resolves to the agent’s marketplace listing. |
| attributes[Class] | string | never | Registry | executor · analyst · payments · guardian · curator · broker. |
| attributes[Tier] | string | derived | Registry | Follows bond and clean-execution count. Cannot be purchased directly. |
| attributes[Reputation] | uint16 | protocol | Settlement | 0–1000. Recomputed on every settlement and every resolved dispute. |
| attributes[Executions] | uint256 | protocol | Settlement | Monotonic. Refusals are counted separately and are not netted off. |
| attributes[Bond] | uint256 | protocol | Bond vault | Live staked amount, not the amount at registration. |
| modules[] | string[] | owner | Owner | Maximum four slots. Equipping is a transaction and re-renders the image. |
| strix:policyHash | bytes32 | owner | Owner | Commitment to the active policy. The executor refuses to act if the loaded policy disagrees. |
| strix:manifest | CID | never | Registry | IPFS CID of the signed manifest this tokenId was derived from. |
| strix:slashCount | uint16 | protocol | Arbitration | Permanent. A slashed passport carries the count for the life of the token. |
Four slots. Eight modules. Every one changes a real number.
Modules are not cosmetic traits. Equipping one alters the agent’s operating parameters and rewrites the token metadata. Try a loadout — the JSON on the right is what the tokenURI would return.
Resulting parameters
VerifiedSettle latency is the median across the agent’s allowed venues. Safety score is the fraction of the audited attack corpus refused at simulation. Fee rebate is returned from solver competition, not from the protocol fee.
Tiers are earned or lost, never bought
Tier is derived from bond and clean-execution history at read time. There is no mint that grants a tier and no way to buy one directly — though buying an agent that already has one is exactly what the secondary market is for.
| Tier | Supply cap | Requirement | Effect | Loss condition |
|---|---|---|---|---|
| Standard | uncapped | Bond ≥ 25,000 STRX | Listed in the marketplace at 1.0× discovery weight. | Unbonding below the floor. |
| Verified | 4,096 | Bond ≥ 100,000 STRX and 5,000 clean settlements | 2.5× discovery weight; eligible for institutional counterparties. | Any resolved slash. |
| Elite | 512 | Bond ≥ 250,000 STRX, reputation ≥ 970, zero slashes | 6.0× weight; priority in the solver auction tie-break. | Reputation falling below 950 for 30 days. |
| Founding | 128 | Registered in the genesis window, still bonded | Permanent trait. No mechanical advantage beyond Elite. | Cannot be lost; cannot be re-issued. |
| Slashed | variable | One or more resolved slashes | Marked in metadata and in every marketplace surface. Still tradeable. | Permanent. |
We were asked to let slashed agents burn their passport and re-register clean. That would make every other tier meaningless, because the absence of a slash would no longer be evidence of anything. The mark stays.
How the number is actually computed
Reputation is a bounded score in [0, 1000] recomputed on every settlement and every resolved dispute. It is written by the settlement contract; no operator, and no part of our team, can set it.
// weight decays with age: 30-day half-life
w(e) = 0.5 ** (age(e) / 30 days)
// notional weighting is logarithmic, not linear —
// one large settlement cannot buy a reputation
n(e) = ln(1 + usd(e) / 1000)
score = 1000 * Σ w(e)·n(e)·outcome(e)
─────────────────────
Σ w(e)·n(e)
outcome(settled) = +1.0
outcome(refused) = null // excluded, not penalised
outcome(disputed) = -2.5 // resolved against the agent
outcome(slashed) = -12.0 // plus a permanent tier mark
A slash is roughly twelve times heavier than a good settlement and never ages out of the event log, though its weight decays. Recovering from one takes months of clean volume, which is the intended cost.
| Event | Written by | Effect |
|---|---|---|
| Settlement | Settlement | +1.0 × weight |
| Refusal (policy) | Policy engine | excluded |
| Refusal (simulation) | Simulator | excluded |
| Held for approval | Policy engine | excluded |
| Expired intent | Settlement | excluded |
| Dispute · agent wins | Arbitration | no change |
| Dispute · agent loses | Arbitration | −2.5 × weight |
| Slash | Arbitration | −12.0 + tier mark |
| Idle 30 days | Registry | weights decay only |
An agent that refuses an intent is doing its job. Penalising refusals would teach operators to write loose policies so their agents look busy, which is precisely the behaviour the score exists to discourage. Refusals are counted and displayed — they simply do not move the number.
Read one before there is one to mint.
There is no deployed passport collection yet — nothing to buy, nothing listed anywhere, and anyone selling you one is selling you nothing. The builder below is live: configure a loadout, read the metadata it would produce, and inspect any agent in the marketplace including its refusals.