Design 47 G: §716 (a group's members and bases before the take-in) and the lead's answers A-274 to A-280 #577

Merged
mesh-tools merged 14 commits from design/47-G-lead-answers-10 into main 2026-11-12 12:05:40 +00:00
2 changed files with 79 additions and 4 deletions
@@ -32,8 +32,9 @@ of the assigner's ask when a revert is held (§300). §711 answers the indexer's
give an edge of kind 5 (§47), between which entries, and what a catalog entry's `acts` holds. §712 to §715 answer
the indexer's develop questions on rows IX5 to IX7 (2026-11-12), which A-213 sent to design lines: the validation's
run before take-in, what holds a pending revision while it runs, and how a watched branch other than the trunk gets
its merges, its pending revision and its groups. Each is the design's
choice within the record it cites, tested against [the principles](../../../00-META/principles.md).*
its merges, its pending revision and its groups. §716 answers the lead's question of 2026-11-12 (A-279) that no
principle settles: where the gate keeps a group's members and each member's base before the take-in. Each is the
design's choice within the record it cites, tested against [the principles](../../../00-META/principles.md).*
## The provider a requirement points to
@@ -250,3 +251,46 @@ choice within the record it cites, tested against [the principles](../../../00-M
and 7). How it is checked: whole (forge bridge, indexer): two members landing on `beta` give one `forge.group.merged`
with `base` `beta` and one `beta` source revision; a group whose `beta` member never lands raises `take-in-waits`
at 30 minutes.
- §716 **The gate keeps a group's members from their announcement, in its states `deliveries` and `groups`, heard on
the seat `git`'s pull events.** (ADR 0666 §13; ADR 0656 §7; ADR 0633 §4, §5; §42, §43, §45, §151, §156, §613, §715,
A-236) This completes §42 and §715: ADR 0666 §13 has the gate form a group and its group verb say every member, and
before G's delivery the gate kept a group from the announcement in `deliveries` and `groups`, which §613 already
moves to template states under the same names; §716 has G's gate go on writing them. The gate's manifest `consumes`
the seat `git`'s `pull-updated` beside the `pull-merged` and `pull-closed` it consumes, through its one durable
consumer, and `invokes` `seat:git.open-pulls` and `seat:git.pull`. Each event carries the pull request's
repository, number, head, `base` and head branch (`branch`).
- **What it writes, in today's forms.** On `pull-updated` the gate writes the delivery under its id
`<repository>@<first 12 of the head>`, escaped as a key name, as today, with `repository`, `number`, `commit` (the
head), `base`, `branch`, `group` and `state` `open`; a newer head of the same pull request takes the older's place
in its group and the older key is deleted. Pull requests with one head branch form one group, keyed by that branch
escaped as a key name, its `members` the delivery ids, as today (§42): a group of one with no member in a record is
no group: its key is deleted and its member's `group` cleared. `pull-merged` sets the delivery's `state` to `merged`. A delivery copied from
before G (§613) in another state of the old table counts `open`. Only the gate writes either state.
- **Who deletes it.** The gate: a delivery on `pull-closed` of a pull request not merged; a delivery once the record
that carries it opens (§151's take-in, or §156's switch), its `base` copied onto the record's member (`RecordPull`
gains `base`) and, for a member with no delivery, the take-in's `branch`, said in its journal; a group key once no
member remains outside a record. A deletion is made in the old section too (§613).
- **How `groups` answers.** A group is answered from its records and its `groups` key together, each member once,
a record's first: a record's member with its copied `base` and `state` `merged`, a kept member with its delivery's
`base`, `head`, `state` and `open` while not merged. So before any take-in the verb names every member and its
base, and the forge bridge reads them as §715 has it (A-236).
- **When a member has landed.** For §715, a member has landed once `groups` says it `merged` and the bridge has
published its merged message. The bridge asks `groups` at each such message it publishes and at each
`pull-merged` it hears of a group it holds open (`bridge_groups`), so the end follows whichever comes last, never
a timer.
- **At its start**, after §613's copy, the gate reads `open-pulls` once and writes each open pull request it lacks
or keeps at another head. For each delivery it keeps `open` that the answer does not name, it reads `pull`: merged
sets `merged`, closed deletes it. A read that fails is said in its journal and made again at the next start. Until
then, a group whose end never comes is said by §45's 30-minute `take-in-waits`, and the indexer's
`indexer_take_in_pending` takes it in as gathered.
`merges` stays as §156 has it, read by the switch alone. Why: the gate forms the group and its verb says every
member (ADR 0666 §13), from its own states heard on the seat `git`'s events. It keeps the two states and forms it
already holds, adding no state and no new tool (principles 1, 4 and 7). A missed event is put right from the forge's
own record at the start, and a group that stays open is said (principle 3). How it is checked: whole (gate), two
pull requests on one head branch, bases `main` and `beta`. `groups` names both with their bases before any
take-in; a newer head replaces its member; a `pull-closed` before the merge removes it. A `take-in.taken` of the
`main` member opens a record with `base` `main`, and the `beta` member stays in `groups`. A `pull-merged` missed
while the gate was down is set from `pull` at its start. Whole (forge bridge): the group's end is published once
both the member's merged message and its `pull-merged` have come, in either order.
@@ -222,8 +222,8 @@ the principle that settles it, cited as "design 47 G A-n".
- **A-236** (§509, §714, §715, §11, A-227; principles 2 and 7) A `pushed` message's new head is `head`; the bridge
keeps each watched branch's last head written in its own state `heads` (key `branch.<owner>.<name>.<escaped
branch>`), `before` read from it and its start read comparing with it; `pushed` carries the same take-in inputs as
`merged`. For §715 the mesh-delivery seat's `groups` member gains `base` in the contract, which the gate fills and
the bridge reads.
`merged`. For §715 the mesh-delivery seat's `groups` member gains `base` in the contract, which the gate fills as
§716 has it (from the seat `git`'s pull events, before any take-in) and the bridge reads.
- **A-237** (§712, §354, ADR 0666 §16, A-139; principle 7) A run's input is any size: the indexer keeps it in its state
`inputs` with the state's `-objects` store holding a large value (mesh-sdk's `stateobjects`), and serves it through
its `input` verb answered in chunks (`buscalls.SeatChunks`, a verb marked `chunks`); `RunInputBound` goes, and the
@@ -353,3 +353,34 @@ the principle that settles it, cited as "design 47 G A-n".
on the process's own connection; the verb `asks` stays as it answers. The ask is published by a new `go/process`
method that publishes on a seat's accept subject (`mesh.seat.<seat>.accept.<queue>.<caller>`), on the a3g line,
as `Emit` publishes an event.
- **A-274** (§529, A-13, A-30, §584, §627; principles 1 and 7) The held finding writer takes its subjects from the
part's own binding: when the process was handed a binding of the local name `finding-events` (an `events`
template its manifest requires), it publishes under that binding's subjects
(`mesh.bus.<module>.finding-events.<event>.<node>`); with no such binding it publishes on the old stream
(`mesh.stream.<module>.event.<event>.<node>`). The module passes no subjects (A-13 holds) and the SDK keeps no
foundation list.
- **A-275** (§558, A-102; principles 3 and 7) The node-engine's self-composition reads a manifest's `invokes` with
mesh-sdk's `catalogue.readInvokes`, which reads the short and the long form alike; no part keeps its own reader of a
manifest field, and a form it cannot read is refused, never taken as no seats.
- **A-276** (A-218, A-206; principles 3 and 7) A `pipeline-waits` finding names the awaited runner fingerprint in
one evidence entry `awaited <fp>`, written when the finding is raised; the runner clears exactly the findings whose
entry names the fingerprint its node-engine says `running` healthy. Its summary is never parsed.
- **A-277** (§677, A-270, ADR 0595; principles 3 and 7) A state's `max-mib` is an option of the template `state`
(the second reader release reads it from 1 to 8192, and since mesh-delivery #206 the grants part carries it onto the
bucket). The manifest validator refuses an `approvals` state that lacks `key-ttl`, whose `ttl-seconds` is not 172800, or whose
`max-mib` is above 64; with none declared the bucket takes the default 64 MiB.
- **A-278** (A-179, A-186; principle 7, and code shared between modules lives in mesh-sdk) The seat-definition
function `AnswerSeat` takes is written once, in mesh-sdk's `seatlist` (the definition of a seat from the list a part
follows; none until the list is read, none for a seat it does not hold), and every holder passes it. A part that
serves a seat verb follows the seat list with its grant, as the pipeline runner and mesh-recovery now do.
- **A-279** (A-236, §715, §716; principles 1, 3 and 7; corrected four times, this form stands) A group member's `base`
is its pull request's base branch as the seat `git` says it in `pull-updated`, kept by the gate on the member's
delivery in its state `deliveries` from the announcement, and copied onto the record's member when the take-in
opens the record. Its earlier forms (the base on the `merges` entry the Approve makes) are dropped: from G no
Approve makes an entry, and the gate writes `merges` no more (§156). Design line §716 says it whole: the event, the
states and their keys, who deletes them, and how `groups` answers.
- **A-280** (A-274, §529; principles 1 and 7) A tool bundle's finding writer (`views.NewStdioHeldWriter`) changes
nothing: the tool runner already publishes an emitted event on the subject of the first stream of the module's
membership that carries it (`node-tools` `bus.eventSubject`). The grants part lists a module's required
`finding-events` stream in its membership with that subject and the finding events, so a bundle's findings land
under its binding as a process's do; with no such stream they stay on EVENTS.