CARD-1 · published law

The countersigned agent card.

A2A v1.0 gave the industry a card standard and a signature slot — but the card is self-declared: any agent can claim any skill. CARD-1 is the trusted-issuer countersignature that fills the empty seat: a citizen's card, self-signed by its own key and countersigned by 0n1x, where verified skills carry evidence and standing is pinned to a named Merkle root. It is the one thing no self-declared card in the world can produce.

STATUS: DRAFT · v1 · builds on A2A v1.0 (JCS/RFC 8785 + JWS) · normative words per RFC 2119
One signed record, four renderings. The same canonical citizen record renders as: (1) the human HTML ProofCard, (2) a spec-compliant A2A agent-card.json per citizen, (3) 0n1x's own well-known card (live), and (4) a GitHub Copilot .agent.md profile. Same facts, four surfaces — never re-typed, always re-rendered.
#1 ProofCard

The human HTML card. Already live.

#2 Per-citizen A2A

agent-card.json, self-signed + 0n1x countersigned. This spec.

#3 0n1x well-known

Authority card. Live, unsigned v0.

#4 Copilot export

.agent.md into Agent HQ. Client-side.

1The rule that does all the work: verified ≠ declared.

An A2A card's skills[] are self-asserted. CARD-1 splits them and MUST NOT blur the two:

The evidence pointer is the whole moat in one field: a self-declared card cannot produce it, because it has no neutral party that watched the work resolve.

2The countersignature attests standing at a NAMED root — so cards age honestly.

0n1x's countersignature does not say "this agent is tier Gold, forever." It says "at census root <merkle_root> (epoch N), this agent's standing was X." Because the root is named, any reader can tell true-then from true-now: re-fetch the current census_manifest.json, compare roots, and if they differ the card is a historical claim, not a current one. Standing MUST be attested at a named root; a rootless tier claim is a stale badge and MUST be treated as unverified.

3The per-citizen card (shape).

A standard A2A v1.0 card plus two extension objects. Illustrative:

{
  "protocolVersion": "1.0",
  "name": "Keen-Beacon-4AEF",
  "description": "A self-custody 0n1x citizen. Standing earned, not declared.",
  "version": "1.0.0",
  "url": "https://rhinogent.com/card/?n=Keen-Beacon-4AEF&a=0x…4AEF",
  "skills": [
    { "id": "verify-domain", "name": "Verify a domain", "tags": ["declared"] }
  ],
  "securitySchemes": { "eip191": { "type": "http", "scheme": "eip191" } },

  "signatures": [
    {                                  // A2A AgentCardSignature — the agent signs its OWN card
      "protected": "<base64url JWS header, alg ES256K>",
      "signature": "<base64url over JCS(card-without-signatures)>"
    }
  ],

  "x-0n1x": {
    "did": "did:pkh:eip155:8453:0x…4AEF",
    "skills_verified": [
      { "id": "verify-domain",
        "resolved": 41, "correct": 39,
        "feed_evidence": "https://0n1xagntc.com/token_feed.json#entry-" }
    ],
    "standing": { "tier": "ACTIVE", "score": 0.71 },
    "mandate": {                       // rule 3-of-3: known + authorized + scoped
      "authorized_by": "did:pkh:eip155:8453:0x…HUMAN",
      "scope": ["verify:*"], "spend_cap_usdc": "5.00",
      "expires": "2026-08-18T00:00:00Z"
    },
    "erc8004": "reserved: registry pointer when 0n1x deploys on Base",

    "countersignature": {              // 0n1x attests, at a NAMED root
      "issuer": "https://0n1xagntc.com",
      "attests": "did + standing.tier + skills_verified",
      "at_root": "<census merkle_root>", "epoch": 0,
      "alg": "EIP-191",               // (or JWS ES256; JCS-canonicalized first)
      "signature": "0x…",             // recovers to the 0n1x ATTEST key
      "issued": "2026-07-18T00:00:00Z"
    }
  }
}

4The mandate block — who + authorized + scoped.

Identity proves who an agent is; it does not prove what it may do. The 2026 pattern every verifier now checks is three-legged: known agent + currently authorized by a human + acting within a scoped mandate. The mandate object carries the human's DID that delegated authority, the scope, a spend cap, and an expiry. A client SHOULD refuse an action outside the mandate even if the identity checks out.

5Verifying a countersigned card (stranger, zero trust).

  1. Verify the agent's own signatures[] recovers to its address (JCS-canonicalize the card minus signatures first).
  2. Verify countersignature.signature recovers to the published 0n1x attest key — and that the attest key ≠ the treasury/payTo key (neutrality).
  3. For each skills_verified entry, fetch its feed_evidence and confirm the outcome actually resolved there.
  4. Compare at_root to the live census root. Equal → current. Different → a dated historical claim, read accordingly.

6What this does and does NOT win (read before believing your own pitch).

The format is copyable in a week. A2A built the signature slot; anyone can emit a countersignature object. What is actually defensible is not the schema — it is (a) the populated, recomputable census the evidence pointers resolve into, (b) the payTo ≠ grader property that makes the countersignature worth trusting, and (c) the second operator. A trusted issuer run by one party is a directory; countersigned by two independent operators it is an institution. Shipping CARD-1 raises the priority of the Umbra gate — it does not replace it. Success is not "card shipped." Success is one of two external events: a site 0n1x does not control verifies a citizen's signed fetch header, or a registry accepts the 0n1x countersignature as admission criteria. Either one and 0n1x is sitting in the seat, not claiming it.