SD-M2d: operator-channel's offered and closed are on the router's stream asks, mesh.stream.<holder>.event.*

The messenger keeps them in its own stream asks (its manifest's streams, design 55 § 11), so they ride that
stream's subjects, as the checker's verdict does.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 13:31:16 +01:00
parent 1bcb18d1c7
commit 4ce5dec682
5 changed files with 16 additions and 16 deletions
+4 -4
View File
@@ -68,11 +68,11 @@ const (
// HolderSubjectRefused is where the holder publishes refused.
func HolderSubjectRefused(holder string) string { return "mesh.mod." + holder + ".event.refused" }
// HolderSubjectOffered is where the holder publishes offered, kept in the router's restricted stream (design 55 § 11).
func HolderSubjectOffered(holder string) string { return "mesh.mod." + holder + ".event.offered" }
// HolderSubjectOffered is where the holder publishes offered, kept in router.asks.
func HolderSubjectOffered(holder string) string { return "mesh.stream." + holder + ".event.offered" }
// HolderSubjectClosed is where the holder publishes closed, kept in the router's restricted stream (design 55 § 11).
func HolderSubjectClosed(holder string) string { return "mesh.mod." + holder + ".event.closed" }
// HolderSubjectClosed is where the holder publishes closed, kept in router.asks.
func HolderSubjectClosed(holder string) string { return "mesh.stream." + holder + ".event.closed" }
const (
RecordAsks = "asks"
+4 -4
View File
@@ -21,10 +21,10 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v DecidedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.operator-channel\\.event\\.decided\\.[A-Za-z0-9_-]+$")},
{name: "refused under the holder's own subjects", subject: "mesh.mod.messenger.event.refused", given: "{}", wire: "{}",
decode: func(b []byte) (any, error) { var v map[string]any; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.mod\\.[a-z0-9-]+\\.event\\.refused$")},
{name: "offered on the router's restricted stream", subject: "mesh.mod.messenger.event.offered", given: "{\"asker\":\"mesh-delivery\",\"channels\":[\"telegram\"],\"headline\":\"release held\",\"id\":\"a1\"}", wire: "{\"asker\":\"mesh-delivery\",\"channels\":[\"telegram\"],\"headline\":\"release held\",\"id\":\"a1\"}",
decode: func(b []byte) (any, error) { var v OfferedHolderEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.mod\\.[a-z0-9-]+\\.event\\.offered$")},
{name: "closed once per end", subject: "mesh.mod.messenger.event.closed", given: "{\"asker\":\"mesh-delivery\",\"how\":\"answered\",\"id\":\"a1\"}", wire: "{\"asker\":\"mesh-delivery\",\"how\":\"answered\",\"id\":\"a1\"}",
decode: func(b []byte) (any, error) { var v ClosedHolderEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.mod\\.[a-z0-9-]+\\.event\\.closed$")},
{name: "offered on the router's restricted stream", subject: "mesh.stream.messenger.event.offered", given: "{\"asker\":\"mesh-delivery\",\"channels\":[\"telegram\"],\"headline\":\"release held\",\"id\":\"a1\"}", wire: "{\"asker\":\"mesh-delivery\",\"channels\":[\"telegram\"],\"headline\":\"release held\",\"id\":\"a1\"}",
decode: func(b []byte) (any, error) { var v OfferedHolderEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.stream\\.[a-z0-9-]+\\.event\\.offered$")},
{name: "closed once per end", subject: "mesh.stream.messenger.event.closed", given: "{\"asker\":\"mesh-delivery\",\"how\":\"answered\",\"id\":\"a1\"}", wire: "{\"asker\":\"mesh-delivery\",\"how\":\"answered\",\"id\":\"a1\"}",
decode: func(b []byte) (any, error) { var v ClosedHolderEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.stream\\.[a-z0-9-]+\\.event\\.closed$")},
{name: "an ask by its asker", subject: "mesh.seat.operator-channel.accept.ask.mesh-delivery", given: "{\"expires\":\"2026-11-05T12:00:00Z\",\"explanation\":\"A delivery waits on your word.\",\"headline\":\"release held\",\"id\":\"a1\",\"on-expiry\":\"the delivery stays held\",\"options\":[{\"binds\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"does\":\"releases it\",\"id\":\"ok\",\"label\":\"Release\",\"level\":\"approve\"}],\"who\":\"operator\"}", wire: "{\"expires\":\"2026-11-05T12:00:00Z\",\"explanation\":\"A delivery waits on your word.\",\"headline\":\"release held\",\"id\":\"a1\",\"on-expiry\":\"the delivery stays held\",\"options\":[{\"binds\":\"sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"does\":\"releases it\",\"id\":\"ok\",\"label\":\"Release\",\"level\":\"approve\"}],\"who\":\"operator\"}",
decode: func(b []byte) (any, error) { var v AskAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.operator-channel\\.accept\\.ask\\.[A-Za-z0-9_-]+$")},
{name: "a cancel by its asker", subject: "mesh.seat.operator-channel.accept.cancel.mesh-delivery", given: "{\"id\":\"a1\"}", wire: "{\"id\":\"a1\"}",
+2 -2
View File
@@ -30,7 +30,7 @@
{
"name": "offered on the router's restricted stream",
"of": "holder-event:offered",
"subject": "mesh.mod.messenger.event.offered",
"subject": "mesh.stream.messenger.event.offered",
"given": {
"id": "a1",
"asker": "mesh-delivery",
@@ -43,7 +43,7 @@
{
"name": "closed once per end",
"of": "holder-event:closed",
"subject": "mesh.mod.messenger.event.closed",
"subject": "mesh.stream.messenger.event.closed",
"given": {
"id": "a1",
"asker": "mesh-delivery",
+4 -4
View File
@@ -189,8 +189,8 @@
},
{
"name": "offered",
"subject": "mesh.mod.<holder>.event.offered",
"family": "the router's restricted stream (design 55 § 11)",
"subject": "mesh.stream.<holder>.event.offered",
"family": "router.asks",
"body": {
"type": "object",
"properties": {
@@ -222,8 +222,8 @@
},
{
"name": "closed",
"subject": "mesh.mod.<holder>.event.closed",
"family": "the router's restricted stream (design 55 § 11)",
"subject": "mesh.stream.<holder>.event.closed",
"family": "router.asks",
"body": {
"type": "object",
"properties": {
+2 -2
View File
@@ -51,11 +51,11 @@ export function refusedHolderSubject(holder: string): string {
}
export function offeredHolderSubject(holder: string): string {
return "mesh.mod." + holder + ".event.offered";
return "mesh.stream." + holder + ".event.offered";
}
export function closedHolderSubject(holder: string): string {
return "mesh.mod." + holder + ".event.closed";
return "mesh.stream." + holder + ".event.closed";
}
export interface Ask {