Seat definition format: states replace records, operator-channel's asks first (ADR 0608 §1, ADR 0634 §6; issue 1966)

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-05 12:46:33 +01:00
parent 4d7b2a3778
commit b6c127f237
3 changed files with 97 additions and 26 deletions
+5
View File
@@ -10,6 +10,11 @@ implements its contract, and no holder's code lives here.
- **The definition**, written by hand: `seats/<seat>/seat.json`, its fixtures in `seats/<seat>/fixtures/`, and the
parts several seats include whole in `parts/` (the four registry seats' verbs and events are `parts/registry.json`).
mesh-sdk's `seatdef` is the one reader of the format; the indexer and the generators use it.
- **A state**, in the definition's `states` (ADR 0608 §1, ADR 0634 §6): `{name, template, writer, key-forms, history,
max-age-days, description}`. `template` is one of ADR 0595's six (`state`, `events`, `work-queue`, `log`, `objects`,
`ledger`); `writer` is `holder` (the default) or `caller`; each key form is `{key, value, description}`, the key a
pattern of named parts between angle brackets (`<asker>.<id>`) and the value its JSON Schema. A definition names no
holder module: a reader takes the holder from its own manifest's `reads`. A fixture of a state is `state:<name>/<key>`.
- **The seat set**, generated: `go/seats` (module `git.novox.be/novox/mesh-contracts/go`), every seat's name, scope,
verbs and provision at the seat list's grain (ADR 0625 §2). mesh-sdk's `catalogue` is its only importer in mesh-sdk.
A change of it rebuilds every importer of the seat set. Its npm package is `ts/` (`@novox/mesh-contracts`, the
+79 -20
View File
@@ -130,27 +130,11 @@
},
"description": "the holder's own events listed beside the seat, keeping the holder's subjects (ADR 0620 \u00a72)"
},
"records": {
"states": {
"type": "array",
"description": "the layouts of the state the holder keeps on the bus for the seat (ADR 0608 \u00a71, ADR 0634 \u00a76); a whole definition's. No holder module is named: each reader takes the holder from its own manifest's reads",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]*$"
},
"key": {
"type": "string"
},
"value": {
"type": "object",
"description": "a JSON Schema"
}
}
"$ref": "#/$defs/state"
}
},
"provisions": {
@@ -377,7 +361,7 @@
},
"of": {
"type": "string",
"pattern": "^(verb:[a-z][a-z0-9-]*\\.(input|answer)|accept:[a-z][a-z0-9-]*|event:[a-z][a-z0-9-]*|holder-event:[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)*)$"
"pattern": "^(verb:[a-z][a-z0-9-]*\\.(input|answer)|accept:[a-z][a-z0-9-]*|event:[a-z][a-z0-9-]*|state:[a-z][a-z0-9-]*/.+|holder-event:[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)*)$"
},
"subject": {
"type": "string"
@@ -410,6 +394,81 @@
"uniqueItems": true
}
}
},
"state": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"template",
"key-forms"
],
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]*$"
},
"template": {
"enum": [
"state",
"events",
"work-queue",
"log",
"objects",
"ledger"
],
"description": "ADR 0595 \u00a72"
},
"writer": {
"enum": [
"holder",
"caller"
],
"description": "holder when not given; caller when the seat's callers write their own keys"
},
"key-forms": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/keyForm"
}
},
"history": {
"type": "integer",
"minimum": 0,
"description": "past values a key keeps; the state template only"
},
"max-age-days": {
"type": "integer",
"minimum": 0,
"description": "days a message is kept; the events, work-queue and log templates only"
},
"description": {
"type": "string"
}
}
},
"keyForm": {
"type": "object",
"additionalProperties": false,
"required": [
"key",
"value"
],
"properties": {
"key": {
"type": "string",
"minLength": 1,
"description": "a pattern of named parts between angle brackets, the rest literal: <asker>.<id>"
},
"value": {
"type": "object",
"description": "a JSON Schema"
},
"description": {
"type": "string"
}
}
}
}
}
+13 -6
View File
@@ -172,14 +172,21 @@
"name": "operator-channel.decided",
"max-age-days": 7
},
"records": [
"states": [
{
"name": "asks",
"key": "<asker>.<id>",
"value": {
"type": "object",
"description": "one ask the router holds and how it stands"
}
"template": "state",
"key-forms": [
{
"key": "<asker>.<id>",
"value": {
"type": "object",
"description": "one ask the router holds and how it stands"
},
"description": "one ask the router holds and how it stands"
}
],
"description": "the asks a module raised and the router holds, one key per asker and ask"
}
],
"holder-events": [