From
bafyreiavwroe3n3rwxhbcm3utmnmojmnicyhtm7bpmetlx4tebwic37n2m
indexed 2026-10-29 18:55 UTC
View this version
To
bafyreigoqvyf6ixwd3ggbyduqkn77buvjfih2p6t7vxjm27m4ud6it652u
indexed 2026-11-04 18:12 UTC
View this version
Compatibility
breaking 7 breaking changes, 26 non-breaking changes.
Breaking changes (7)
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#encryptionKey", src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.stage", kind: "prop", name: Some("stage") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#encryptionKey", src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.canRotate", kind: "prop", name: Some("canRotate") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#sealing", src: "at.happyproto.admin.defs#sealing", tgt: "at.happyproto.admin.defs#sealing.remaining", kind: "prop", name: Some("remaining") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#sealing", src: "at.happyproto.admin.defs#sealing", tgt: "at.happyproto.admin.defs#sealing.previousKeyLive", kind: "prop", name: Some("previousKeyLive") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#sealing", src: "at.happyproto.admin.defs#sealing", tgt: "at.happyproto.admin.defs#sealing.unreadable", kind: "prop", name: Some("unreadable") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#keyFailure", src: "at.happyproto.admin.defs#keyFailure", tgt: "at.happyproto.admin.defs#keyFailure.kind", kind: "prop", name: Some("kind") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#keyFailure", src: "at.happyproto.admin.defs#keyFailure", tgt: "at.happyproto.admin.defs#keyFailure.operationId", kind: "prop", name: Some("operationId") }
Non-breaking changes (26)
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.blockedBy" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.canRotate" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.failure" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.operation" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.rotatedAt" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.sealing" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.stage" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure.errorCode" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure.kind" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure.operationId" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing.previousKeyLive" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing.remaining" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing.unreadable" }
- AddedVertex AddedVertex { vertex_id: "at.happyproto.admin.listInstances#operation" }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.blockedBy", kind: "prop", name: Some("blockedBy") }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.failure", kind: "prop", name: Some("failure") }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.operation", kind: "prop", name: Some("operation") }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.rotatedAt", kind: "prop", name: Some("rotatedAt") }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.sealing", kind: "prop", name: Some("sealing") }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey.failure", tgt: "at.happyproto.admin.defs#keyFailure", kind: "ref", name: None }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey.operation", tgt: "at.happyproto.admin.listInstances#operation", kind: "ref", name: None }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#encryptionKey.sealing", tgt: "at.happyproto.admin.defs#sealing", kind: "ref", name: None }
- AddedEdge AddedEdge { src: "at.happyproto.admin.defs#keyFailure", tgt: "at.happyproto.admin.defs#keyFailure.errorCode", kind: "prop", name: Some("errorCode") }
Migration guidance
Added
AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.blockedBy" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.canRotate" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.failure" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.operation" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.rotatedAt" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.sealing" }AddedVertex { vertex_id: "at.happyproto.admin.defs#encryptionKey.stage" }AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure" }AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure.errorCode" }AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure.kind" }AddedVertex { vertex_id: "at.happyproto.admin.defs#keyFailure.operationId" }AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing" }AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing.previousKeyLive" }AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing.remaining" }AddedVertex { vertex_id: "at.happyproto.admin.defs#sealing.unreadable" }AddedVertex { vertex_id: "at.happyproto.admin.listInstances#operation" }
Notes
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#sealing", src: "at.happyproto.admin.defs#sealing", tgt: "at.happyproto.admin.defs#sealing.remaining", kind: "prop", name: Some("remaining") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#sealing", src: "at.happyproto.admin.defs#sealing", tgt: "at.happyproto.admin.defs#sealing.previousKeyLive", kind: "prop", name: Some("previousKeyLive") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#sealing", src: "at.happyproto.admin.defs#sealing", tgt: "at.happyproto.admin.defs#sealing.unreadable", kind: "prop", name: Some("unreadable") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#keyFailure", src: "at.happyproto.admin.defs#keyFailure", tgt: "at.happyproto.admin.defs#keyFailure.kind", kind: "prop", name: Some("kind") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#keyFailure", src: "at.happyproto.admin.defs#keyFailure", tgt: "at.happyproto.admin.defs#keyFailure.operationId", kind: "prop", name: Some("operationId") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#encryptionKey", src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.stage", kind: "prop", name: Some("stage") }
- Breaking: RequiredEdgeAdded { vertex_id: "at.happyproto.admin.defs#encryptionKey", src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.canRotate", kind: "prop", name: Some("canRotate") }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.blockedBy", kind: "prop", name: Some("blockedBy") }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.failure", kind: "prop", name: Some("failure") }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.operation", kind: "prop", name: Some("operation") }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.rotatedAt", kind: "prop", name: Some("rotatedAt") }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey", tgt: "at.happyproto.admin.defs#encryptionKey.sealing", kind: "prop", name: Some("sealing") }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey.failure", tgt: "at.happyproto.admin.defs#keyFailure", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey.operation", tgt: "at.happyproto.admin.listInstances#operation", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#encryptionKey.sealing", tgt: "at.happyproto.admin.defs#sealing", kind: "ref", name: None }
- Non-breaking: AddedEdge { src: "at.happyproto.admin.defs#keyFailure", tgt: "at.happyproto.admin.defs#keyFailure.errorCode", kind: "prop", name: Some("errorCode") }
Changes
11
{22
"$type": "com.atproto.lexicon.schema",33
"defs": {44
"autoscale": {55
"description": "The autoscaler's settings and what it is waiting on.",66
"properties": {77
"blockedBy": {88
"description": "A failed request that holds off new ones until staff retry or cancel it.",99
"type": "string"1010
},1111
"cooldownUntil": {1212
"description": "No new request before this. Absent once it has passed.",1313
"format": "datetime",1414
"type": "string"1515
},1616
"costEur": {1717
"description": "What each host it orders costs a month, in euros, as a decimal string.",1818
"type": "string"1919
},2020
"current": {2121
"ref": "#freeCapacity",2222
"type": "ref"2323
},2424
"enabled": {2525
"description": "On in the provisioner's config, with the GitHub App set up.",2626
"type": "boolean"2727
},2828
"hosts": {2929
"description": "Hosts that are not retired.",3030
"type": "integer"3131
},3232
"inFlight": {3333
"description": "Requests under way: 0 or 1.",3434
"type": "integer"3535
},3636
"lowSince": {3737
"description": "Since when free capacity has been below a threshold. Absent while it is fine.",3838
"format": "datetime",3939
"type": "string"4040
},4141
"maxHosts": {4242
"description": "The most hosts it may bring the fleet to.",4343
"type": "integer"4444
},4545
"paused": {4646
"description": "Paused by staff: no new requests, though one under way carries on.",4747
"type": "boolean"4848
},4949
"pausedAt": {5050
"format": "datetime",5151
"type": "string"5252
},5353
"pausedBy": {5454
"description": "The staff DID that paused it.",5555
"format": "did",5656
"type": "string"5757
},5858
"thresholds": {5959
"ref": "#thresholds",6060
"type": "ref"6161
}6262
},6363
"required": [6464
"enabled",6565
"paused",6666
"current"6767
],6868
"type": "object"6969
},70
"encryptionKey": {71
"description": "An instance's encryption key and where it is in a rotation.",72
"properties": {73
"blockedBy": {74
"description": "Why a rotation cannot start now, when it cannot: the code rotateEncryptionKey would refuse with.",75
"knownValues": [76
"OperationInProgress",77
"RotationInProgress",78
"InstanceStopped",79
"NotLive",80
"RotationUnsupported",81
"AgentUnreachable",82
"NotSettled"83
],84
"type": "string"85
},86
"canRotate": {87
"description": "Whether a rotation can start now.",88
"type": "boolean"89
},90
"failure": {91
"description": "The instance's latest operation, when it failed and the instance with it. Any kind: a KeyMismatch can fail an update or an upgrade too.",92
"ref": "#keyFailure",93
"type": "ref"94
},95
"operation": {96
"description": "The rotate_key or retire_key operation in progress, if any.",97
"ref": "at.happyproto.admin.listInstances#operation",98
"type": "ref"99
},100
"rotatedAt": {101
"description": "When the current key became current. Absent for the key the instance was created with.",102
"format": "datetime",103
"type": "string"104
},105
"sealing": {106
"description": "Only while sealing, and only when the instance's host answered.",107
"ref": "#sealing",108
"type": "ref"109
},110
"stage": {111
"description": "none: one key. rotating: a new key is made but not live yet. sealing: it is live and HappyView is re-sealing what the old key sealed. retiring: the old key is being removed. failed: the instance is failed and its latest operation is a failed rotate_key or retire_key; retrying the instance sends its keys again.",112
"knownValues": [113
"none",114
"rotating",115
"sealing",116
"retiring",117
"failed"118
],119
"type": "string"120
}121
},122
"required": [123
"stage",124
"canRotate"125
],126
"type": "object"127
},70128
"event": {71129
"description": "One line of a request's timeline.",72130
"properties": {73131
"at": {74132
"format": "datetime",75133
"type": "string"76134
},77135
"kind": {78136
"knownValues": [79137
"requested",80138
"dispatched",81139
"step_started",82140
"step_finished",83141
"ordering",84142
"configuring",85143
"verifying",86144
"registered",87145
"failed",88146
"cancelled",89147
"retried",90148
"cancel_requested",91149
"deploy_cancelled"92150
],93151
"type": "string"94152
},95153
"message": {96154
"description": "What happened, in the provisioner's words.",97155
"type": "string"98156
},99157
"runUrl": {100158
"description": "The GitHub Actions run the event came from.",101159
"format": "uri",102160
"type": "string"103161
}104162
},105163
"required": [106164
"at",107165
"kind"108166
],109167
"type": "object"110168
},111169
"freeCapacity": {112170
"description": "Free capacity across the active hosts. An over-committed host counts as none.",113171
"properties": {114172
"freeDiskGb": {115173
"type": "integer"116174
},117175
"freeMemoryMb": {118176
"type": "integer"119177
}120178
},121179
"type": "object"122180
},123181
"hostRequest": {124182
"description": "A tenant host the autoscaler asked for.",125183
"properties": {126184
"cancelRunUrl": {127185
"format": "uri",128186
"type": "string"129187
},130188
"costEur": {131189
"description": "The host's monthly cost in euros, as a decimal string.",132190
"type": "string"133191
},134192
"createdAt": {135193
"format": "datetime",136194
"type": "string"137195
},138196
"currentStep": {139197
"description": "The workflow step running now.",140198
"type": "string"141199
},142200
"deployRunUrl": {143201
"format": "uri",144202
"type": "string"145203
},146204
"dispatchedAt": {147205
"format": "datetime",148206
"type": "string"149207
},150208
"error": {151209
"description": "Why it failed.",152210
"type": "string"153211
},154212
"events": {155213
"description": "Oldest first. Only on a single request.",156214
"items": {157215
"ref": "#event",158216
"type": "ref"159217
},160218
"type": "array"161219
},162220
"finishedAt": {163221
"format": "datetime",164222
"type": "string"165223
},166224
"id": {167225
"description": "A UUID.",168226
"type": "string"169227
},170228
"name": {171229
"description": "The host's name, like tenant-4.",172230
"type": "string"173231
},174232
"requestedBy": {175233
"description": "system, or the staff DID.",176234
"type": "string"177235
},178236
"state": {179237
"knownValues": [180238
"requested",181239
"ordering",182240
"configuring",183241
"verifying",184242
"registered",185243
"failed",186244
"cancelling",187245
"cancelled"188246
],189247
"type": "string"190248
},191249
"trigger": {192250
"ref": "#trigger",193251
"type": "ref"194252
},195253
"updatedAt": {196254
"format": "datetime",197255
"type": "string"198256
},199257
"workflowRunUrl": {200258
"format": "uri",201259
"type": "string"202260
}203261
},204262
"required": [205263
"id",206264
"name",207265
"state",208266
"createdAt"209267
],210268
"type": "object"211269
},270
"keyFailure": {271
"properties": {272
"errorCode": {273
"description": "The provisioner's error code. KeyMismatch: the host refused an apply that would drop the key the instance seals with. It needs an operator, not a retry.",274
"knownValues": [275
"KeyMismatch"276
],277
"type": "string"278
},279
"kind": {280
"description": "The operation's kind, as on #operation.",281
"type": "string"282
},283
"operationId": {284
"type": "string"285
}286
},287
"required": [288
"operationId",289
"kind"290
],291
"type": "object"292
},293
"sealing": {294
"properties": {295
"previousKeyLive": {296
"description": "Whether the instance runs with both keys. False when its rotate_key has not reached it, for instance because it failed: then remaining reads 0 without anything being re-sealed, and retrying the instance sends both keys again.",297
"type": "boolean"298
},299
"remaining": {300
"description": "Values only the old key opens. The old key is retired once this reaches 0.",301
"minimum": 0,302
"type": "integer"303
},304
"unreadable": {305
"description": "Values neither key opens. They were unreadable before the rotation, too.",306
"minimum": 0,307
"type": "integer"308
}309
},310
"required": [311
"previousKeyLive",312
"remaining",313
"unreadable"314
],315
"type": "object"316
},212317
"thresholds": {213318
"description": "When the autoscaler orders a host: free capacity across active hosts below either figure for sustainSecs, and no request in the last cooldownSecs.",214319
"properties": {215320
"cooldownSecs": {216321
"type": "integer"217322
},218323
"freeDiskGb": {219324
"type": "integer"220325
},221326
"freeMemoryMb": {222327
"type": "integer"223328
},224329
"sustainSecs": {225330
"type": "integer"226331
}227332
},228333
"type": "object"229334
},230335
"trigger": {231336
"description": "Free capacity when the request was made, and the thresholds it was below.",232337
"properties": {233338
"freeDiskGb": {234339
"type": "integer"235340
},236341
"freeMemoryMb": {237342
"type": "integer"238343
},239344
"hosts": {240345
"items": {241346
"ref": "#triggerHost",242347
"type": "ref"243348
},244349
"type": "array"245350
},246351
"lowSince": {247352
"format": "datetime",248353
"type": "string"249354
},250355
"thresholds": {251356
"ref": "#thresholds",252357
"type": "ref"253358
}254359
},255360
"type": "object"256361
},257362
"triggerHost": {258363
"properties": {259364
"freeDiskGb": {260365
"type": "integer"261366
},262367
"freeMemoryMb": {263368
"type": "integer"264369
},265370
"name": {266371
"type": "string"267372
}268373
},269374
"type": "object"270375
}271376
},272377
"id": "at.happyproto.admin.defs",273378
"lexicon": 1274379
}