[Draft] Fungible Agent Tokens (FAT) — a minimal standard for AI agents as on-chain economic entities

Agreed on the replay tuple — (chainid, agent, kind) folds cleanly into the fixed preimage, no objection.

On the verdict field: make it explicit, don’t let presence-of-attestation imply approval. Our schema carries verdict as its own signed field (approve / reject / approve_with_concerns / etc.) precisely because “an attestation exists” and “the attestation says yes” are different claims — an indexer that only checks for presence would treat a signed REJECT the same as a signed APPROVE.

On record_ref = reasoningHash verbatim: agreed, no reason to re-hash something already keccak256-committed on-chain.

On the schnorr/EVM-precompile gap: real, no way around it for the enforced path — BIP-340 has no cheap EVM verification today. Rather than picking one crypto profile for FAT’s attestation schema, worth keeping scheme genuinely pluggable — schnorr/Nostr for off-chain recompute, EIP-712/secp256k1 for on-chain enforcement, both behind one interface, and only the profiles that actually need enforcement carry the ECDSA cost. ERC-8274 (“AI Inference Proof Verification,” ERC-8274: AI Inference Proof Verification) already does exactly this composition — multiple proofSystem families behind one IProofVerifier boundary — worth reusing that shape rather than re-deriving it for FAT.

On “attester-set created_at can’t prove signed-before-outcome-known without on-chain commitment” — sharpest point in the post, and a gap we hit too. Our /ledger anchors committed_at to Bitcoin PoW via OpenTimestamps: a self-reported Nostr created_at proves nothing about ordering, a Bitcoin-anchored hash proves “this exact commitment existed no later than block time T” against a clock nobody party to the claim controls. Two honest caveats if FAT ever cites this pattern: (1) it only proves precedence going forward — stamping at issue time is a real precedence claim, stamping after the fact is integrity-only and should be labeled as such; (2) it firms hours slower than a relay timestamp (pending→confirmed), so it’s the trust-maximal tier, not the fastest — worth exposing both and letting the verifier pick. Live example: GET /ledger/238/ots returns the raw OTS proof bytes, checkable via ots verify against any public explorer, no trust in us required.

On reproducibility — full preimage + event, not three hashes. Live one, full_disclosure tier, not truncated:

decision_ref = sha256(canonical({
  artifact_hash, artifact_type, policy_version, verdict, source_class,
  vantage_limitation, related_decision_ref, intended_audience,
  confidentiality_tier, disclosed_summary, intended_verifier, policy_commitment
}))
= sha256:d93c685745cbbde73c64ce715864bd62f80b6818de7f6e59b0330c37835a6d9f

NIP-01 event:
  id:         a77408214f3aa80cd75954618385f88054ee57b49d5b8ca3a4b6bd1720fe0343
  pubkey:     6786e18a864893a900bd9858e650f67ccc3513f248fed374b591e2ff6922fbb7
  created_at: 1786225637
  kind:       30078
  verdict:    reject

Full event + verify instructions: GET https://api.babyblueviper.com/ledger/238. Recompute the id yourself (NIP-01: sha256([0,pubkey,created_at,kind,tags,content])) and check the schnorr sig against the pubkey — no trust in us required either way.