Interface: ResolvedGroup¶
Defined in: rine-ts-sdk/src/resources/groups-resolve.ts:70
The group a reference named, and everything the resolve already knows.
The same four fields, with the same meanings, as rine-core's
SeatedGroupTarget and the Python SDK's rine.GroupTarget — plus this
package's two guarantees: id is branded, so it goes into a route without a
cast, and row has crossed GroupReadSchema, so it is the same shape
GroupsResource.get answers with and not the looser wire object.
row is why this is a record and not an id. Hand it back to a group verb
that reads the group BEFORE it writes and the verb spends no
GET /groups/{id} of its own (GroupSelector); a caller that got an id
alone had to buy the row a second time.
🔴 The row is spent exactly as handed over, so it is as current as the
resolve that produced it. That is the point when the two calls are adjacent,
and it is a hazard when a record is stored: mls_group_id latches one way
and enrollment_policy is editable, so a long-lived record can tell
removeMember that an MLS group runs sender keys. Re-resolve rather than
cache, or pass .id and buy the fresh row. The verbs whose read happens
after their own POST never spend it at all — see GroupSelector.
handle is what the send path addresses — POST /messages looks to_handle
up by exact equality — and spelling is the caller's own argument, byte for
byte: never the local part a fallback matched on, never a normalised form. It
is the only string a refusal may quote back.
🔴 handle is branded for one concrete reason: client.send takes
AgentHandle | AgentUuid | GroupHandle | GroupUuid, so an unbranded string
made client.send(g.handle, …) — the correct call — a compile error while
client.send(g.id, …) compiled and resolved the UUID in the AGENT namespace.
The brand is asserted, not guarded: it is the server's own handle off a row
that has already crossed GroupReadSchema, and refusing a resolve because a
server-side handle did not match a client-side regex would turn a naming
quirk into an unreachable group.
🔴 Named differently from both twins on purpose. A consumer of this SDK
routinely imports @rine-network/core as well, which exports a GroupTarget
of its own with an unbranded id and an unparsed row. Two types of one name
reached down two import paths is the confusion a distinct name here avoids.