diff --git a/contracts/seats/mesh-delivery/fixtures/events.json b/contracts/seats/mesh-delivery/fixtures/events.json new file mode 100644 index 00000000..da3dc7ce --- /dev/null +++ b/contracts/seats/mesh-delivery/fixtures/events.json @@ -0,0 +1,170 @@ +[ + { + "name": "owed is said, a merge", + "of": "event:owed", + "subject": "mesh.seat.mesh-delivery.event.owed.novox/mesh-sdk.178", + "given": { + "id": "merge.feat=47-G.0123456789ab.novox/mesh-sdk#178", + "act": "merge", + "repository": "novox/mesh-sdk", + "number": 178, + "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "group": "feat/47-G", + "ask": "merge.feat=47-G.0123456789ab", + "said": "2026-11-09T20:00:00Z" + } + }, + { + "name": "owed is said, a status", + "of": "event:owed", + "subject": "mesh.seat.mesh-delivery.event.owed.novox/mesh-sdk.178", + "given": { + "id": "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/merge-gate", + "act": "status", + "repository": "novox/mesh-sdk", + "number": 178, + "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "context": "mesh/merge-gate", + "state": "pending", + "description": "waits for the operator's Approve", + "target": "https://forge.test/x" + } + }, + { + "name": "pinned is said", + "of": "event:pinned", + "subject": "mesh.seat.mesh-delivery.event.pinned", + "given": { + "record": "47-G", + "milestone": "47/G", + "catalog": [ + 3610 + ], + "assignment": [ + 1204 + ] + } + }, + { + "name": "freed is said", + "of": "event:freed", + "subject": "mesh.seat.mesh-delivery.event.freed", + "given": { + "record": "47-G", + "milestone": "47/G", + "catalog": [ + 3610 + ], + "assignment": [ + 1204 + ], + "why": "past its retention of 90 days" + } + }, + { + "name": "heads-replaced is said", + "of": "event:heads-replaced", + "subject": "mesh.seat.mesh-delivery.event.heads-replaced", + "given": { + "group": "feat/47-G", + "heads": "0123456789ab", + "repository": "novox/mesh-sdk", + "number": 178, + "head": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "at": "2026-11-09T20:05:00Z" + } + }, + { + "name": "heads-replaced is said for a closed pull request", + "of": "event:heads-replaced", + "subject": "mesh.seat.mesh-delivery.event.heads-replaced", + "given": { + "group": "feat/47-G", + "heads": "0123456789ab", + "repository": "novox/mesh-sdk", + "number": 178, + "closed": true + } + }, + { + "name": "record-opened is said", + "of": "event:record-opened", + "subject": "mesh.seat.mesh-delivery.event.record-opened", + "given": { + "record": "47-G", + "milestone": "47/G", + "at": "2026-11-09T18:00:00Z" + } + }, + { + "name": "record-ended is said", + "of": "event:record-ended", + "subject": "mesh.seat.mesh-delivery.event.record-ended", + "given": { + "record": "47-G", + "milestone": "47/G", + "away": [ + { + "node": "laptop", + "since": "2026-11-09T18:00:00Z" + } + ], + "at": "2026-11-09T21:00:00Z" + } + }, + { + "name": "filling is said", + "of": "event:filling", + "subject": "mesh.seat.mesh-delivery.event.filling", + "given": { + "store": "records", + "bytes": 650000000, + "cap": 805306368 + } + }, + { + "name": "full is said", + "of": "event:full", + "subject": "mesh.seat.mesh-delivery.event.full", + "given": { + "store": "records", + "bytes": 805306368, + "cap": 805306368, + "refused": "the next record" + } + }, + { + "name": "room is said", + "of": "event:room", + "subject": "mesh.seat.mesh-delivery.event.room", + "given": { + "store": "records", + "bytes": 400000000, + "cap": 805306368 + } + }, + { + "name": "main moved to its next source revision", + "of": "event:source-moved", + "subject": "mesh.seat.mesh-delivery.event.source-moved.main", + "given": { + "v": 1, + "branch": "main", + "revision": 3590, + "at": "2026-11-10T10:00:00Z" + } + }, + { + "name": "a recovery merged", + "of": "event:recovery-merged", + "subject": "mesh.seat.mesh-delivery.event.recovery-merged", + "given": { + "v": 1, + "repository": "novox/mesh-sdk", + "commit": "0123456789abcdef0123456789abcdef01234567", + "why": "the live delivery was broken", + "by": "jochen", + "at": "2026-11-11T10:00:00Z" + } + } +] diff --git a/contracts/seats/mesh-delivery/fixtures/states.json b/contracts/seats/mesh-delivery/fixtures/states.json index 0721e1da..b8f7dd9b 100644 --- a/contracts/seats/mesh-delivery/fixtures/states.json +++ b/contracts/seats/mesh-delivery/fixtures/states.json @@ -1,7 +1,7 @@ [ { "name": "the source revision", - "of": "state:source/main", + "of": "state:source/", "given": { "v": 1, "group": "feat/registry", @@ -27,24 +27,6 @@ ] } }, - { - "name": "an ask", - "of": "state:asks/merge..", - "given": { - "v": 1, - "group": "feat/registry", - "heads": [ - { - "repository": "novox/mesh-sdk", - "number": 1, - "head": "cccccccccccccccccccccccccccccccccccccccc" - } - ], - "ask": { - "headline": "merge" - } - } - }, { "name": "an act owed", "of": "state:owed/...", @@ -52,21 +34,5 @@ "v": 1, "act": "view" } - }, - { - "name": "a turn", - "of": "state:turns/", - "given": { - "v": 1, - "repository": "novox/mesh-sdk", - "waiting": [ - { - "group": "feat/registry", - "heads": "0123456789ab", - "approved": "2026-11-05T10:00:00Z", - "since": "2026-11-05T10:01:00Z" - } - ] - } } ] diff --git a/contracts/seats/mesh-delivery/fixtures/verbs.json b/contracts/seats/mesh-delivery/fixtures/verbs.json new file mode 100644 index 00000000..3024eff5 --- /dev/null +++ b/contracts/seats/mesh-delivery/fixtures/verbs.json @@ -0,0 +1,117 @@ +[ + { + "name": "groups asks for one group", + "of": "verb:groups.input", + "given": { + "group": "feat/47-G" + } + }, + { + "name": "groups answers a group with its members and acts", + "of": "verb:groups.answer", + "given": { + "groups": [ + { + "id": "feat/47-G", + "state": "merging", + "why": "novox/mesh-sdk#178 merges first", + "check": "pass", + "members": [ + { + "id": "novox/mesh-sdk#178", + "repository": "novox/mesh-sdk", + "number": 178, + "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "base": "main", + "state": "merging", + "open": true + } + ], + "acts": [ + { + "owed": { + "id": "merge.feat=47-G.0123456789ab.novox/mesh-sdk#178", + "act": "merge", + "repository": "novox/mesh-sdk", + "number": 178, + "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "group": "feat/47-G", + "ask": "merge.feat=47-G.0123456789ab", + "said": "2026-11-09T20:00:00Z" + }, + "outcome": "performed", + "at": "2026-11-09T20:01:00Z" + }, + { + "owed": { + "id": "status.novox/mesh-sdk#178.aaaaaaaaaaaa.mesh/merge-gate", + "act": "status", + "repository": "novox/mesh-sdk", + "number": 178, + "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "context": "mesh/merge-gate", + "state": "pending", + "description": "waits for the operator's Approve", + "target": "https://forge.test/x" + } + } + ] + } + ] + } + }, + { + "name": "groups answers a group it does not know with no groups", + "of": "verb:groups.answer", + "given": {} + }, + { + "name": "source is asked with nothing", + "of": "verb:source.input", + "given": { + "branch": "main" + } + }, + { + "name": "source answers each repository's trunk and head", + "of": "verb:source.answer", + "given": { + "group": "feat/47-G", + "revision": 42, + "repositories": [ + { + "repository": "novox/mesh-sdk", + "trunk": "main", + "head": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + } + ], + "branch": "main" + } + }, + { + "name": "source answers an error when it cannot be read", + "of": "verb:source.answer", + "given": { + "error": "source.main is not readable" + } + }, + { + "name": "recovery names a merge and why", + "of": "verb:recovery.input", + "given": { + "repository": "novox/mesh-sdk", + "commit": "0123456789abcdef0123456789abcdef01234567", + "why": "the live delivery was broken" + } + }, + { + "name": "recovery answers the caller the runtime proved", + "of": "verb:recovery.answer", + "given": { + "repository": "novox/mesh-sdk", + "commit": "0123456789abcdef0123456789abcdef01234567", + "recovery": true, + "by": "jochen" + } + } +] diff --git a/contracts/seats/mesh-delivery/seat.json b/contracts/seats/mesh-delivery/seat.json index dd617cc4..1dd1e613 100644 --- a/contracts/seats/mesh-delivery/seat.json +++ b/contracts/seats/mesh-delivery/seat.json @@ -5,6 +5,7 @@ "grain": "whole", "domain": "Delivery", "decision": "novox/hq ADR 0239", + "description": "The delivery gate: reads and steers deliveries, merges and the checks that decide them; the merge is made on the operator's Approve once both checks passed.", "verbs": [ { "name": "deliveries", @@ -37,20 +38,8 @@ "answer": { "type": "object", "description": "what deliveries answers, as its description says" - } - }, - { - "name": "times", - "description": "Removed in R6 (ADR 0539): refused by name, naming its replacement: the delivery view (nox-delivery): each machine's want and have, and since when", - "optional": true, - "input": { - "properties": {}, - "type": "object" }, - "answer": { - "type": "object", - "description": "what times answers, as its description says" - } + "class": "read" }, { "name": "show", @@ -70,12 +59,14 @@ "answer": { "type": "object", "description": "what show answers, as its description says" - } + }, + "class": "read" }, { "name": "groups", - "description": "Every delivery group: its members in order, why each pair is ordered (declared, built by, version skew, engine before controller, by name), its composed check and its state, derived from its members.", + "description": "Every delivery group: its members in merge order, its check and its state, derived from its members, and the acts the gate said it owes the forge for it, each with its id and its recorded outcome (design 47 *What the gate owes the forge*). With a group, that group alone, and none for a group it does not know: the forge bridge reads a group's members and catches up on what it owes from here, never from the gate's state.", "input": { + "type": "object", "properties": { "all": { "description": "\"true\": the groups that ended too", @@ -84,68 +75,74 @@ "false" ], "type": "string" + }, + "group": { + "type": "string", + "description": "one group's id: that group alone, ended or not" } - }, - "type": "object" + } }, "answer": { "type": "object", - "description": "what groups answers, as its description says" - } - }, - { - "name": "what-if", - "description": "Removed in R6 (ADR 0539): refused by name, naming its replacement: the merge check's composition, which composes every machine a change touches", - "optional": true, - "input": { - "properties": {}, - "type": "object" - }, - "answer": { - "type": "object", - "description": "what what-if answers, as its description says" - } - }, - { - "name": "checks", - "description": "What the mesh's checks said of a pull request's head or of one commit: each of the commit's mesh statuses (mesh/check, the one a main requires from R4e, hq's mesh/repo-check, mesh/delivery, …) with its state, description and when it was set; the merge check's full verdict as the controller said it — each layer's summary, the machine that ran it, when, its build id and its report; and whether the branch's protection would let it merge, every required status being success.", - "optional": true, - "input": { "properties": { - "commit": { - "description": "a commit's sha, or the start of one, instead of a pull request", - "type": "string" + "groups": { + "type": "array", + "items": { + "$ref": "#/defs/Group" + } }, - "number": { - "description": "a pull request's number: its head is read", - "type": "string" - }, - "repository": { - "description": "owner/repository", - "type": "string" + "error": { + "type": "string", + "description": "why it could not answer at all; a group it does not know is answered with no groups, never an error" + } + } + }, + "class": "read" + }, + { + "name": "source", + "description": "One watched branch's source revision (design 47 *Watched branches and the catalog graph per branch*: source. in place of source.main): The source revision the gate holds: every repository it names, its trunk branch and that trunk's head as the gate merged or seeded it, and the group that moved it last. Read, never written: the node-engines read it to call a reverted build's catch-up tool once per repository, never the gate's state (design 47).", + "input": { + "type": "object", + "properties": { + "branch": { + "type": "string", + "description": "the watched branch, escaped as a key name is" } }, "required": [ - "repository" - ], - "type": "object" + "branch" + ] }, "answer": { "type": "object", - "description": "what checks answers, as its description says" - } - }, - { - "name": "table", - "description": "The state table every delivery runs by: each transition with its guard, each state's bound and what healer H2 may do once it has passed; and the machine steps' table.", - "input": { - "properties": {}, - "type": "object" + "properties": { + "group": { + "type": "string", + "description": "the group that moved the source revision last; absent before the first" + }, + "revision": { + "type": "integer", + "description": "the source revision's number on the bus; 0 before the first" + }, + "repositories": { + "type": "array", + "items": { + "$ref": "#/defs/SourceHead" + }, + "description": "every repository the source revision names, by name" + }, + "error": { + "type": "string", + "description": "why it could not be read" + }, + "branch": { + "type": "string", + "description": "the watched branch the source revision is of" + } + } }, - "answer": { - "type": "object", - "description": "what table answers, as its description says" - } + "class": "read" }, { "name": "stalled", @@ -157,137 +154,314 @@ "answer": { "type": "object", "description": "what stalled answers, as its description says" - } + }, + "class": "read" }, { - "name": "recheck", - "description": "Check a rejected or ready delivery again: it goes back to proposed and the controller is asked for its check. With why.", + "name": "recovery", + "class": "act", + "callers": [ + "operator", + "sessions" + ], + "description": "Mark a merge its author names a recovery: the commit and why; the delivery record is marked recovery with the caller the runtime proves, and recovery-merged is said (design 47 G section 305).", "input": { + "type": "object", "properties": { - "id": { - "description": "the delivery's id", - "type": "string" + "repository": { + "type": "string", + "description": "the repository, /" + }, + "commit": { + "type": "string", + "description": "the merge commit" }, "why": { - "description": "why, kept with the transition", - "type": "string" + "type": "string", + "description": "why the merge is a recovery" } }, "required": [ - "id", + "repository", + "commit", "why" - ], - "type": "object" + ] }, "answer": { "type": "object", - "description": "what recheck answers, as its description says" - } - }, - { - "name": "release", - "description": "Removed in R6 (ADR 0539): refused by name, naming its replacement: the assigner's asks (hold, restore, backup, record), answered on the phone or in the delivery view", - "optional": true, - "input": { - "properties": {}, - "type": "object" - }, - "answer": { - "type": "object", - "description": "what release answers, as its description says" - } - }, - { - "name": "stop", - "description": "Removed in R6 (ADR 0539): refused by name, naming its replacement: a bad fingerprint is held and its canary set back by the assigner (ADR 0429 §6, ADR 0539 clause 18)", - "optional": true, - "input": { - "properties": {}, - "type": "object" - }, - "answer": { - "type": "object", - "description": "what stop answers, as its description says" - } - }, - { - "name": "close", - "description": "Healer H2's verb: take the one transition the table names for a delivery held past its bound. Refused for any other.", - "input": { "properties": { - "id": { - "description": "the delivery's id", - "type": "string" + "repository": { + "type": "string", + "description": "the repository" }, - "why": { - "description": "the condition it answers", - "type": "string" + "commit": { + "type": "string", + "description": "the merge commit" + }, + "recovery": { + "type": "boolean" + }, + "by": { + "type": "string", + "description": "the caller the runtime proved" } }, "required": [ - "id", - "why" - ], - "type": "object" + "commit", + "recovery" + ] + } + } + ], + "family": { + "name": "mesh-delivery.events", + "max-age-days": 7 + }, + "events": [ + { + "name": "owed", + "subject": "owed..", + "keep": { + "max-age-days": 7, + "max-mib": 64 }, - "answer": { + "body": { + "$ref": "#/defs/Owed" + } + }, + { + "name": "pinned", + "body": { + "$ref": "#/defs/Pins" + } + }, + { + "name": "freed", + "body": { + "$ref": "#/defs/Pins" + } + }, + { + "name": "heads-replaced", + "body": { "type": "object", - "description": "what close answers, as its description says" + "description": "a candidate's heads replaced or its pull request closed: its graphs mean nothing any more", + "properties": { + "group": { + "type": "string", + "description": "the group" + }, + "heads": { + "type": "string", + "description": "the candidate's heads, 12 hex digits, as its revisions are keyed" + }, + "repository": { + "type": "string", + "description": "the member whose head moved or which closed" + }, + "number": { + "type": "integer", + "description": "its pull request's number" + }, + "head": { + "type": "string", + "description": "its new head; absent when it closed", + "pattern": "^[0-9a-f]{40}$" + }, + "closed": { + "type": "boolean", + "description": "the pull request closed" + }, + "at": { + "type": "string", + "format": "date-time", + "description": "when" + } + }, + "required": [ + "group", + "heads", + "repository", + "number" + ] } }, { - "name": "retire-history", - "description": "Removed in R6 (ADR 0539): refused by name, naming its replacement: nothing to retire: the gate keeps no delivery after its merge", - "optional": true, - "input": { - "properties": {}, - "type": "object" - }, - "answer": { + "name": "record-opened", + "body": { "type": "object", - "description": "what retire-history answers, as its description says" + "description": "a delivery record opened: its merge was taken in, and the watchman times it against 24 hours", + "properties": { + "record": { + "type": "string", + "description": "the record's id" + }, + "milestone": { + "type": "string", + "description": "its milestone" + }, + "forge-made": { + "type": "boolean", + "description": "a merge made at the forge, with no Approve" + }, + "at": { + "type": "string", + "format": "date-time", + "description": "when" + } + }, + "required": [ + "record", + "milestone" + ] } }, { - "name": "settle", - "description": "Ask the operator to settle deliveries held because their merge reached the trunk without a passing check: one ask on the operator's channel for all of them, as an Approve is asked. The verb moves nothing; on the operator's answer each goes to merged, and whether it is on the machines is derived as for any merge (novox/hq ADR 0556). Refused for a delivery not held, or held for another reason, naming why.", - "optional": true, - "input": { - "additionalProperties": false, + "name": "record-ended", + "body": { + "type": "object", + "description": "a delivery record ended: every present node runs its entries", "properties": { - "ids": { - "description": "the held deliveries' ids (owner/repository@commit)", + "record": { + "type": "string", + "description": "the record's id" + }, + "milestone": { + "type": "string", + "description": "its milestone" + }, + "forge-made": { + "type": "boolean", + "description": "a merge made at the forge, with no Approve" + }, + "away": { + "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "node": { + "type": "string", + "description": "a node away" + }, + "since": { + "type": "string", + "format": "date-time", + "description": "since when" + } + }, + "required": [ + "node" + ] }, - "minItems": 1, - "type": "array" + "description": "the nodes away, each with since when; it ends without them" + }, + "at": { + "type": "string", + "format": "date-time", + "description": "when" + } + }, + "required": [ + "record", + "milestone" + ] + } + }, + { + "name": "filling", + "body": { + "$ref": "#/defs/Fill" + } + }, + { + "name": "full", + "body": { + "$ref": "#/defs/Fill" + } + }, + { + "name": "room", + "body": { + "$ref": "#/defs/Fill" + } + }, + { + "name": "source-moved", + "subject": "source-moved.", + "body": { + "type": "object", + "description": "a new source revision of a watched branch (design 47 *The verbs*)", + "properties": { + "v": { + "type": "integer" + }, + "branch": { + "type": "string" }, + "revision": { + "type": "integer" + }, + "group": { + "type": "string", + "description": "the group that moved it, when one did" + }, + "at": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "branch", + "revision" + ] + } + }, + { + "name": "recovery-merged", + "body": { + "type": "object", + "description": "a merge named a recovery, which the teller passes on to every channel (design 47 G section 305)", + "properties": { + "v": { + "type": "integer" + }, + "repository": { + "type": "string", + "description": "the repository" + }, + "commit": { + "type": "string", + "description": "the merge commit" + }, "why": { - "description": "why they may be settled, shown to the operator", - "type": "string" + "type": "string", + "description": "why" + }, + "by": { + "type": "string", + "description": "the caller the runtime proved" + }, + "at": { + "type": "string", + "format": "date-time" } }, "required": [ - "ids", + "v", + "repository", + "commit", "why" - ], - "type": "object" - }, - "answer": { - "type": "object", - "description": "what settle answers, as its description says" + ] } } ], - "description": "The delivery gate: reads and steers deliveries, merges and the checks that decide them; the merge is made on the operator's Approve once both checks passed.", "states": [ { "name": "source", "template": "state", "key-forms": [ { - "key": "main", + "key": "", "value": { "type": "object", "properties": { @@ -313,7 +487,7 @@ ], "description": "every repository's merged head; its revision is the mesh's source revision" }, - "description": "the one key, written by the holder alone by compare-and-set" + "description": "one key per watched branch, written by the holder alone by compare-and-set; deleted when the last registration watching the branch unwatches it" } ], "description": "the mesh's source revision", @@ -393,66 +567,6 @@ "description": "the merges", "history": 10 }, - { - "name": "asks", - "template": "state", - "key-forms": [ - { - "key": "merge..", - "value": { - "type": "object", - "properties": { - "v": { - "type": "integer", - "description": "the layout version" - }, - "group": { - "type": "string" - }, - "heads": { - "type": "array", - "items": { - "type": "object", - "properties": { - "repository": { - "type": "string", - "description": "/" - }, - "number": { - "type": "integer" - }, - "head": { - "type": "string", - "description": "the full commit" - } - }, - "required": [ - "repository", - "number", - "head" - ] - } - }, - "ask": { - "description": "the operator-channel ask as raised" - }, - "asking": { - "type": "integer", - "description": "the number of times it was asked" - } - }, - "required": [ - "group", - "heads", - "ask" - ] - }, - "description": "the ask of the operator for one group at one set of heads" - } - ], - "description": "the asks of the operator for a merge", - "history": 5 - }, { "name": "owed", "template": "state", @@ -496,79 +610,346 @@ ], "description": "the acts the gate owes the forge", "history": 5 - }, - { - "name": "turns", - "template": "state", - "key-forms": [ - { - "key": "", - "value": { - "type": "object", - "properties": { - "v": { - "type": "integer", - "description": "the layout version" - }, - "repository": { - "type": "string" - }, - "waiting": { - "type": "array", - "items": { - "type": "object", - "properties": { - "group": { - "type": "string" - }, - "heads": { - "type": "string" - }, - "ask": { - "type": "string" - }, - "approved": { - "type": "string", - "format": "date-time", - "description": "when (RFC 3339 time)" - }, - "since": { - "type": "string", - "format": "date-time", - "description": "when (RFC 3339 time)" - }, - "waits-for": { - "type": "string" - }, - "waits-since": { - "type": "string", - "format": "date-time", - "description": "when (RFC 3339 time)" - }, - "step": { - "type": "string" - } - }, - "required": [ - "group", - "heads", - "approved", - "since" - ] - } - } - }, - "required": [ - "repository", - "waiting" - ], - "description": "the merges of a repository in the order they wait for their turn" - }, - "description": "the merges waiting on a repository" - } - ], - "description": "which merge waits for which", - "history": 5 } - ] + ], + "defs": { + "Owed": { + "type": "object", + "description": "one act the gate owes the forge, said once under its id and safe to repeat at the forge (design 47 *What the gate owes the forge*); the forge bridge performs it through the seat git's verb of the same act", + "properties": { + "id": { + "type": "string", + "description": "the act's id, the same each time it is said again; a comment and a note line carry it, so the forge holds it once" + }, + "act": { + "type": "string", + "enum": [ + "merge", + "status", + "view", + "comment", + "note" + ], + "description": "the act: merge (the seat git's merge-pull), status, view, comment or note" + }, + "repository": { + "type": "string", + "description": "the repository, /", + "minLength": 1 + }, + "number": { + "type": "integer", + "description": "the pull request's number" + }, + "head": { + "type": "string", + "description": "the pull request's head the act is for", + "pattern": "^[0-9a-f]{40}$" + }, + "group": { + "type": "string", + "description": "the delivery group the pull request is a member of, for a merge" + }, + "ask": { + "type": "string", + "description": "the operator's ask that approved the heads, for a merge" + }, + "commit": { + "type": "string", + "description": "the commit a status or a note line is on; the head when absent", + "pattern": "^[0-9a-f]{40}$" + }, + "context": { + "type": "string", + "description": "a status: its context, such as mesh/merge-gate" + }, + "state": { + "type": "string", + "description": "a status: its state, pending, success, failure or error" + }, + "description": { + "type": "string", + "description": "a status: what it says" + }, + "target": { + "type": "string", + "description": "a status: the page it links to" + }, + "text": { + "type": "string", + "description": "a comment or the view: the text, markdown" + }, + "line": { + "type": "string", + "description": "a note line: the one line" + }, + "said": { + "type": "string", + "format": "date-time", + "description": "when the gate first said it" + } + }, + "required": [ + "id", + "act", + "repository", + "number", + "head" + ] + }, + "Act": { + "type": "object", + "description": "an act the gate said for a group, with its recorded outcome once the forge bridge said one", + "properties": { + "owed": { + "$ref": "#/defs/Owed" + }, + "outcome": { + "type": "string", + "enum": [ + "performed", + "refused", + "could not be performed", + "undecodable", + "dropped" + ], + "description": "the outcome the forge bridge said as owed.ended and the gate recorded; absent while unanswered" + }, + "words": { + "type": "string", + "description": "the forge's own words for a refusal, the error for an act that could not be performed, why one is undecodable or dropped" + }, + "at": { + "type": "string", + "format": "date-time", + "description": "when the outcome was recorded" + } + }, + "required": [ + "owed" + ] + }, + "Member": { + "type": "object", + "description": "one member of a group: a pull request", + "properties": { + "id": { + "type": "string", + "description": "the member's delivery id" + }, + "repository": { + "type": "string", + "description": "the repository, /" + }, + "number": { + "type": "integer", + "description": "the pull request's number" + }, + "head": { + "type": "string", + "description": "its head", + "pattern": "^[0-9a-f]{40}$" + }, + "base": { + "type": "string", + "description": "the branch it merges into" + }, + "state": { + "type": "string", + "description": "the member's delivery state" + }, + "open": { + "type": "boolean", + "description": "the pull request is open: not merged, closed or final" + } + }, + "required": [ + "id", + "repository", + "number", + "head", + "state" + ] + }, + "Group": { + "type": "object", + "description": "one delivery group: its members, its derived state and the acts the gate said for it", + "properties": { + "id": { + "type": "string", + "description": "the group's id, its branch" + }, + "state": { + "type": "string", + "description": "its state, derived from its members" + }, + "why": { + "type": "string", + "description": "why it is in that state" + }, + "check": { + "type": "string", + "description": "the group's check: its verdict, or asked as " + }, + "members": { + "type": "array", + "items": { + "$ref": "#/defs/Member" + }, + "description": "its members in merge order" + }, + "acts": { + "type": "array", + "items": { + "$ref": "#/defs/Act" + }, + "description": "the acts the gate said for it, each with its id and its recorded outcome; an id said and not answered is the forge bridge's to perform" + } + }, + "required": [ + "id", + "state", + "members", + "acts" + ] + }, + "Fill": { + "type": "object", + "description": "the delivery records' ledger's fill against its cap", + "properties": { + "store": { + "type": "string", + "description": "the kept data, by its name in the holder's manifest" + }, + "bytes": { + "type": "integer" + }, + "cap": { + "type": "integer", + "description": "bytes" + }, + "refused": { + "type": "string", + "description": "what full refuses, such as the next record" + }, + "at": { + "type": "string", + "format": "date-time", + "description": "when" + } + }, + "required": [ + "store", + "bytes", + "cap" + ] + }, + "Pins": { + "type": "object", + "description": "the graph revisions a delivery record starts or stops pointing at", + "properties": { + "record": { + "type": "string", + "description": "the record's id" + }, + "milestone": { + "type": "string", + "description": "the record's milestone" + }, + "catalog": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "catalog graph revisions, by their number on the seat mesh-catalog" + }, + "assignment": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "assignment graph revisions, by their number on the seat mesh-wants" + }, + "why": { + "type": "string", + "description": "on freed: the record ended past its retention, or was removed by hand" + } + }, + "required": [ + "record", + "milestone" + ] + }, + "Ask": { + "type": "object", + "description": "the one Approve ask of a milestone (ADR 0493 \u00a79), said apart from each delivery's transition", + "properties": { + "milestone": { + "type": "string", + "description": "the milestone" + }, + "ask": { + "type": "string", + "description": "the ask's id" + }, + "group": { + "type": "string", + "description": "its delivery group" + }, + "heads": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "repository to the head asked" + }, + "answer": { + "type": "string", + "description": "on answered: approve or decline" + }, + "by": { + "type": "string", + "description": "on answered: who answered" + }, + "why": { + "type": "string", + "description": "on withdrawn: why, such as a new head of a member" + }, + "at": { + "type": "string", + "format": "date-time", + "description": "when" + } + }, + "required": [ + "milestone", + "ask", + "group" + ] + }, + "SourceHead": { + "type": "object", + "description": "one repository of the source revision: its trunk branch and that trunk's head", + "properties": { + "repository": { + "type": "string", + "description": "the repository, /" + }, + "trunk": { + "type": "string", + "description": "its trunk branch, such as main" + }, + "head": { + "type": "string", + "description": "the trunk's head the source revision names", + "pattern": "^[0-9a-f]{40}$" + } + }, + "required": [ + "repository", + "trunk", + "head" + ] + } + } }