dev.cocore.compute.receipt

cocore.dev

Schema Diff

+50 -0

From

CID
bafyreiauw7sdeyt...
Indexed At
2026-06-25 16:58 UTC
View this version

To

CID
bafyreihmilyggly...
Indexed At
2026-07-26 20:05 UTC
View this version

Compatibility Analysis

Breaking Changes Detected

4 breaking changes, 12 non-breaking changes.

Breaking Changes (4)
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.sig", kind: "prop", name: Some("sig") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.authority", kind: "prop", name: Some("authority") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.nonce", kind: "prop", name: Some("nonce") }
  • RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.machineId", kind: "prop", name: Some("machineId") }
Non-Breaking Changes (12)
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.authority" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.machineId" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.nonce" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.sig" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#generationParams.outputSchemaHash" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt#generationParams.toolSchemaHash" }
  • AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.receipt:body.brokerageCountersignature" }
  • AddedEdge AddedEdge { src: "dev.cocore.compute.receipt#generationParams", tgt: "dev.cocore.compute.receipt#generationParams.outputSchemaHash", kind: "prop", name: Some("outputSchemaHash") }
  • AddedEdge AddedEdge { src: "dev.cocore.compute.receipt#generationParams", tgt: "dev.cocore.compute.receipt#generationParams.toolSchemaHash", kind: "prop", name: Some("toolSchemaHash") }
  • AddedEdge AddedEdge { src: "dev.cocore.compute.receipt:body", tgt: "dev.cocore.compute.receipt:body.brokerageCountersignature", kind: "prop", name: Some("brokerageCountersignature") }
  • AddedEdge AddedEdge { src: "dev.cocore.compute.receipt:body.brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature", kind: "ref", name: None }

Migration Guidance

Added Elements

  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.authority" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.machineId" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.nonce" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature.sig" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#generationParams.outputSchemaHash" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt#generationParams.toolSchemaHash" }
  • AddedVertex { vertex_id: "dev.cocore.compute.receipt:body.brokerageCountersignature" }

Additional Notes

  • Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.sig", kind: "prop", name: Some("sig") }
  • Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.authority", kind: "prop", name: Some("authority") }
  • Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.nonce", kind: "prop", name: Some("nonce") }
  • Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.compute.receipt#brokerageCountersignature", src: "dev.cocore.compute.receipt#brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature.machineId", kind: "prop", name: Some("machineId") }
  • Non-breaking: AddedEdge { src: "dev.cocore.compute.receipt#generationParams", tgt: "dev.cocore.compute.receipt#generationParams.outputSchemaHash", kind: "prop", name: Some("outputSchemaHash") }
  • Non-breaking: AddedEdge { src: "dev.cocore.compute.receipt#generationParams", tgt: "dev.cocore.compute.receipt#generationParams.toolSchemaHash", kind: "prop", name: Some("toolSchemaHash") }
  • Non-breaking: AddedEdge { src: "dev.cocore.compute.receipt:body", tgt: "dev.cocore.compute.receipt:body.brokerageCountersignature", kind: "prop", name: Some("brokerageCountersignature") }
  • Non-breaking: AddedEdge { src: "dev.cocore.compute.receipt:body.brokerageCountersignature", tgt: "dev.cocore.compute.receipt#brokerageCountersignature", kind: "ref", name: None }
1 1
{
2 2
  "$type": "com.atproto.lexicon.schema",
3 3
  "defs": {
4 +
    "brokerageCountersignature": {
5 +
      "description": "A brokerage's session-bound witness on a receipt (ADR-0004). Verified OFFLINE against the `authority` DID document's signing key (invariant #2 holds — the live challenge happened at seal time; the receipt stays verifiable after the fact). The signature covers the sorted-key canonical JSON of `{ authority, attestation, jobCid, jobUri, machineId, nonce, requester }`, where `attestation`/`jobUri` are the `uri` of the receipt's respective strong-refs, `jobCid` is the receipt's `job.cid`, and `requester` is the receipt's `requester` — so the witness is bound to this exact job, requester, serving machine, and attested identity, and cannot be lifted onto another receipt.",
6 +
      "properties": {
7 +
        "authority": {
8 +
          "description": "The brokerage's DID (did:web or did:plc). The verifier resolves its DID document to get the signing key, and MUST require this DID to be in its configured trust set — validity is relative to a named authority the verifier chooses to trust (CA-style trust roots).",
9 +
          "format": "did",
10 +
          "type": "string"
11 +
        },
12 +
        "machineId": {
13 +
          "description": "The stable per-machine id (the provider record's rkey / advisor machine_id) the brokerage dispatched to and live-challenged. Bound into `sig` so the witness names the specific machine that served.",
14 +
          "maxLength": 256,
15 +
          "type": "string"
16 +
        },
17 +
        "nonce": {
18 +
          "description": "Lowercase-hex nonce unique to this witness (the brokerage's per-job witness id). Bound into `sig`.",
19 +
          "maxLength": 64,
20 +
          "minLength": 16,
21 +
          "type": "string"
22 +
        },
23 +
        "sig": {
24 +
          "description": "P-256 signature (DER) by the brokerage authority key over the canonical message described above. Verified against the key in the `authority` DID document.",
25 +
          "maxLength": 256,
26 +
          "type": "bytes"
27 +
        }
28 +
      },
29 +
      "required": [
30 +
        "authority",
31 +
        "machineId",
32 +
        "nonce",
33 +
        "sig"
34 +
      ],
35 +
      "type": "object"
36 +
    },
4 37
    "generationParams": {
5 38
      "description": "Sampling parameters committed to in a receipt. Integer-only because the canonical signing form forbids floats — temperature and top_p are carried as milliunits (value × 1000, e.g. temperature 0.7 -> 700).",
6 39
      "properties": {
7 40
        "maxTokens": {
8 41
          "description": "Max output tokens requested for this job.",
9 42
          "minimum": 0,
10 43
          "type": "integer"
11 44
        },
45 +
        "outputSchemaHash": {
46 +
          "description": "SHA-256 hex over the canonical JSON of the outputSchema the provider used for this job. Present only when the job specified outputSchema. Covered by enclaveSignature, so a requester can prove the provider honored the schema they asked for.",
47 +
          "maxLength": 64,
48 +
          "minLength": 64,
49 +
          "type": "string"
50 +
        },
12 51
        "seed": {
13 52
          "description": "RNG seed, when the provider ran with a fixed seed (enables reproducibility claims).",
14 53
          "type": "integer"
15 54
        },
16 55
        "temperatureMilli": {
17 56
          "description": "Sampling temperature × 1000 (e.g. 0.7 -> 700). Omitted when the provider used the model default.",
18 57
          "minimum": 0,
19 58
          "type": "integer"
20 59
        },
60 +
        "toolSchemaHash": {
61 +
          "description": "SHA-256 hex over the canonical JSON of the tools the provider used for this job. Present only when the job specified tools. Covered by enclaveSignature, so a requester can prove the provider honored the tool definitions they asked for.",
62 +
          "maxLength": 64,
63 +
          "minLength": 64,
64 +
          "type": "string"
65 +
        },
21 66
        "topPMilli": {
22 67
          "description": "Nucleus sampling top_p × 1000 (e.g. 0.95 -> 950). Omitted when the provider used the model default.",
23 68
          "maximum": 1000,
24 69
          "minimum": 0,
25 70
          "type": "integer"
26 71
        }
27 72
      },
28 73
      "type": "object"
29 74
    },
30 75
    "main": {
31 76
      "key": "tid",
32 77
      "record": {
33 78
        "properties": {
34 79
          "attestation": {
35 80
            "description": "Strong-ref to a dev.cocore.compute.attestation record published by this provider. completedAt MUST fall within [attestedAt, expiresAt] of that attestation.",
36 81
            "ref": "com.atproto.repo.strongRef",
37 82
            "type": "ref"
38 83
          },
84 +
          "brokerageCountersignature": {
85 +
            "description": "ADR-0004: the session-bound witness of the BROKERAGE (the matchmaking authority the requester routed through — e.g. the advisor). The brokerage live-challenges the machine it dispatches to, so its countersignature proves 'authority X dispatched THIS job to the machine it attested, and that machine served it'. This is what elevates a receipt to `attested-confidential` under the forkable-authority model: a self-published attestation record is NOT sufficient without a trusted brokerage's countersignature. UNLIKE every other field, this is NOT covered by `enclaveSignature` — it is signed by the brokerage, not the provider, and is added after the provider signs (verifiers strip it before checking enclaveSignature, exactly as they strip enclaveSignature and $type). A confidential requester REQUIRES this from an authority in its trust set (default: cocore's brokerage DID); best-effort receipts omit it. Optional / additive.",
86 +
            "ref": "#brokerageCountersignature",
87 +
            "type": "ref"
88 +
          },
39 89
          "completedAt": {
40 90
            "format": "datetime",
41 91
            "type": "string"
42 92
          },
43 93
          "enclaveSignature": {
44 94
            "description": "Secure Enclave P-256 signature (DER) over a sorted-key canonical JSON of every other field in this record. Verified against the publicKey of the strong-reffed attestation. This binding survives PDS migration: the repo-commit signature changes when keys rotate, but the enclaveSignature does not.",
45 95
            "maxLength": 256,
46 96
            "type": "bytes"
47 97
          },
48 98
          "inputCommitment": {
49 99
            "description": "MUST equal job.inputCommitment.",
50 100
            "maxLength": 64,
51 101
            "minLength": 64,
52 102
            "type": "string"
53 103
          },
54 104
          "job": {
55 105
            "description": "Strong-ref to the requester's dev.cocore.compute.job record.",
56 106
            "ref": "com.atproto.repo.strongRef",
57 107
            "type": "ref"
58 108
          },
59 109
          "model": {
60 110
            "maxLength": 256,
61 111
            "type": "string"
62 112
          },
63 113
          "outputCipherCommitment": {
64 114
            "description": "Optional SHA-256 hex over the EXACT encrypted bytes delivered to the requester (the sealed reply). Lets a requester confirm the ciphertext they received is the one the provider's enclaveSignature commits to — defends against an intermediary swapping the delivered bytes. Covered by enclaveSignature like every other field.",
65 115
            "maxLength": 64,
66 116
            "minLength": 64,
67 117
            "type": "string"
68 118
          },
69 119
          "outputCipherURL": {
70 120
            "description": "Optional URL where the encrypted output lives.",
71 121
            "format": "uri",
72 122
            "type": "string"
73 123
          },
74 124
          "outputCommitment": {
75 125
            "description": "SHA-256 hex over the plaintext output bytes — the decrypted result the requester receives. (The earlier 'encrypted output' wording was a doc error; the provider has always committed to the plaintext, which is what a requester can verify after decrypting. Use outputCipherCommitment to commit to the encrypted bytes on the wire.)",
76 126
            "maxLength": 64,
77 127
            "minLength": 64,
78 128
            "type": "string"
79 129
          },
80 130
          "params": {
81 131
            "description": "Optional record of the sampling parameters the provider committed to for this job. Integer-only (canonical JSON forbids floats): temperature/top_p are carried as integer milliunits. Covered by enclaveSignature, so a requester can prove the provider claimed these settings.",
82 132
            "ref": "#generationParams",
83 133
            "type": "ref"
84 134
          },
85 135
          "price": {
86 136
            "description": "MUST be <= job.priceCeiling. Currency MUST match job.priceCeiling.currency.",
87 137
            "ref": "dev.cocore.compute.defs#money",
88 138
            "type": "ref"
89 139
          },
90 140
          "proBono": {
91 141
            "description": "True when the provider served this job pro bono under its `dev.cocore.compute.provider.proBono` election — free, unmetered, no exchange cut. A pro-bono receipt MUST carry `price.amount: 0` and `tokens: { in: 0, out: 0 }`: the work is explicitly not counted, so neither figure is a billing claim. An exchange settling a `proBono: true` receipt takes no fee and moves no balance (`amountCharged`, `providerPayout`, and `exchangeFee` are all 0). Covered by `enclaveSignature` like every other field, so the carve-out is part of the signed, self-verifying record rather than an off-record side channel. Absent/false ≡ a normal metered, billable receipt. Optional / additive; pre-2026-06 readers ignore it and still see a well-formed zero-price receipt.",
92 142
            "type": "boolean"
93 143
          },
94 144
          "reasoningCommitment": {
95 145
            "description": "Optional SHA-256 hex over the plaintext reasoning ('thinking') output bytes the provider produced for this job, separate from outputCommitment which covers only the answer the requester acts on. Present only when the model emitted reasoning on a distinct channel (a sibling reasoning_content field, or inline <think>...</think> tags the provider split out). Lets a requester independently verify the reasoning trace without it perturbing the answer's commitment. Covered by enclaveSignature.",
96 146
            "maxLength": 64,
97 147
            "minLength": 64,
98 148
            "type": "string"
99 149
          },
100 150
          "requester": {
101 151
            "description": "DID of the requester. Denormalized from the job record for indexer convenience; MUST equal the DID owning the job record.",
102 152
            "format": "did",
103 153
            "type": "string"
104 154
          },
105 155
          "sessionKeyCommitment": {
106 156
            "description": "Optional SHA-256 hex over (ephemeralPubKey || sessionNonce) — the per-job ephemeral X25519 key the requester sealed the input to, bound to the request nonce. Present when the job ran under the forward-secret confidential handshake (the enclave minted a fresh ephemeral key, enclave-signed it against the requester's nonce, and the requester sealed to that key after verifying it). Lets a requester prove after the fact that its prompt was sealed to a key the measured enclave controlled for this job, not the long-lived encryptionPubKey. Covered by enclaveSignature.",
107 157
            "maxLength": 64,
108 158
            "minLength": 64,
109 159
            "type": "string"
110 160
          },
111 161
          "sessionNonce": {
112 162
            "description": "Optional lowercase hex of the fresh requester nonce that the ephemeral session key was bound to (the freshness challenge for this job). Pairs with sessionKeyCommitment. Covered by enclaveSignature.",
113 163
            "maxLength": 64,
114 164
            "minLength": 32,
115 165
            "type": "string"
116 166
          },
117 167
          "startedAt": {
118 168
            "format": "datetime",
119 169
            "type": "string"
120 170
          },
121 171
          "tier": {
122 172
            "description": "The confidentiality tier this job actually ran under. Set by the provider to `attested-confidential` only when the input was sealed to a verified, enclave-bound ephemeral session key AND served by a measured native engine under a hardware-attested posture; otherwise `best-effort`. A requester recomputes this from the receipt's attestation + sessionKeyCommitment rather than trusting the field. Optional / additive; absent equivalent to `best-effort`.",
123 173
            "ref": "dev.cocore.compute.defs#tier",
124 174
            "type": "ref"
125 175
          },
126 176
          "tokens": {
127 177
            "ref": "dev.cocore.compute.defs#tokenCounts",
128 178
            "type": "ref"
129 179
          }
130 180
        },
131 181
        "required": [
132 182
          "job",
133 183
          "requester",
134 184
          "model",
135 185
          "inputCommitment",
136 186
          "outputCommitment",
137 187
          "tokens",
138 188
          "startedAt",
139 189
          "completedAt",
140 190
          "price",
141 191
          "attestation",
142 192
          "enclaveSignature"
143 193
        ],
144 194
        "type": "object"
145 195
      },
146 196
      "type": "record"
147 197
    }
148 198
  },
149 199
  "description": "A signed receipt of a single completed compute job. Published by the provider in its own repo. Strong-refs the requester's job and the active attestation. Carries an additional Secure-Enclave-bound signature so it remains verifiable across PDS migrations.",
150 200
  "id": "dev.cocore.compute.receipt",
151 201
  "lexicon": 1
152 202
}

Compare Other Versions

Lexicon Garden

@