From b76e52d30a98a43e07e28c6f7c5b2f9a754cbfbb Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 11 Nov 2026 20:45:56 +0100 Subject: [PATCH] K24 (mesh-recovery's hand verbs): take, restore, retry, aside, discard-aside and expire-points, asker and why on every hand verb, one answer form with cancel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builds: design 47 G §682, §691 (§516, §554, §566, §656, §681) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ --- go/seats/meshrecovery/contract.go | 156 ++++++++++- go/seats/meshrecovery/contract_test.go | 34 ++- seats/mesh-recovery/fixtures/verbs.json | 134 ++++++++- seats/mesh-recovery/seat.json | 351 +++++++++++++++++++++++- ts/seats/meshrecovery/index.d.ts | 154 ++++++++++- ts/seats/meshrecovery/index.js | 6 + 6 files changed, 823 insertions(+), 12 deletions(-) diff --git a/go/seats/meshrecovery/contract.go b/go/seats/meshrecovery/contract.go index 7c6a38a..4f1846e 100644 --- a/go/seats/meshrecovery/contract.go +++ b/go/seats/meshrecovery/contract.go @@ -14,6 +14,12 @@ const ( VerbKeptPoints = "kept-points" VerbRestoreAside = "restore-aside" VerbCancel = "cancel" + VerbTake = "take" + VerbRestore = "restore" + VerbRetry = "retry" + VerbAside = "aside" + VerbDiscardAside = "discard-aside" + VerbExpirePoints = "expire-points" ) const ( @@ -28,7 +34,7 @@ const ( // Verbs is every verb the seat serves, in its definition's order: a new copy each call. func Verbs() []string { - return []string{VerbSnapshotKept, VerbRestoreKept, VerbKeptPoints, VerbRestoreAside, VerbCancel} + return []string{VerbSnapshotKept, VerbRestoreKept, VerbKeptPoints, VerbRestoreAside, VerbCancel, VerbTake, VerbRestore, VerbRetry, VerbAside, VerbDiscardAside, VerbExpirePoints} } // Events is every event published on the seat's subject: a new copy each call. @@ -244,6 +250,8 @@ type KeptPointsAnswer struct { // RestoreAsideInput is what restore-aside takes. type RestoreAsideInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` // the aside's id ID string `json:"id"` // the kept data, its local name in the module's manifest @@ -268,18 +276,160 @@ type RestoreAsideAnswer struct { type CancelInput struct { // the act's id Act string `json:"act"` + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` // why, which the hand-act log keeps Why string `json:"why"` } // CancelAnswer is what cancel answers. type CancelAnswer struct { - // the act ended cancelled - Cancelled bool `json:"cancelled,omitempty"` + // accepted: the id of the act it cancelled, whose ending event follows under that id + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` // why not, naming the step an act has begun; set alone Error string `json:"error,omitempty"` } +// TakeInput is what take takes. +type TakeInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` + // the fingerprint whose form the point is taken at + Fingerprint string `json:"fingerprint"` + // the kept data, its local name in the module's manifest + Kept string `json:"kept"` + // the module + Module string `json:"module"` + // why, which the hand-act log keeps + Why string `json:"why"` +} + +// TakeAnswer is what take answers. +type TakeAnswer struct { + // accepted: the act's id, which the ending event carries + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` + // why it was not taken; set alone + Error string `json:"error,omitempty"` +} + +// RestoreInput is what restore takes. +type RestoreInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` + // ask the backup holder for the points directory when the point is missing there; only with snapshot + FromBackup bool `json:"from-backup,omitempty"` + // the kept data, its local name in the module's manifest + Kept string `json:"kept"` + // the module + Module string `json:"module"` + // a keeper's snapshot by its request (design 47 G 681) + Request string `json:"request,omitempty"` + // a restore point's name + Snapshot string `json:"snapshot,omitempty"` + // why, which the hand-act log keeps + Why string `json:"why"` +} + +// RestoreAnswer is what restore answers. +type RestoreAnswer struct { + // accepted: the act's id, which the ending event carries + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` + // why it was not taken; set alone + Error string `json:"error,omitempty"` +} + +// RetryInput is what retry takes. +type RetryInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` + // the kept data, its local name in the module's manifest + Kept string `json:"kept"` + // the module + Module string `json:"module"` + // why, which the hand-act log keeps + Why string `json:"why"` +} + +// RetryAnswer is what retry answers. +type RetryAnswer struct { + // accepted: the act's id, which the ending event carries + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` + // why it was not taken; set alone + Error string `json:"error,omitempty"` +} + +// AsideInput is what aside takes. +type AsideInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` + // the kept data, its local name in the module's manifest + Kept string `json:"kept"` + // the module + Module string `json:"module"` + // why, which the hand-act log keeps + Why string `json:"why"` +} + +// AsideAnswer is what aside answers. +type AsideAnswer struct { + // accepted: the act's id, which the ending event carries + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` + // why it was not taken; set alone + Error string `json:"error,omitempty"` +} + +// DiscardAsideInput is what discard-aside takes. +type DiscardAsideInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` + // the aside's id + ID string `json:"id"` + // the kept data, its local name in the module's manifest + Kept string `json:"kept"` + // the module + Module string `json:"module"` + // why, which the hand-act log keeps + Why string `json:"why"` +} + +// DiscardAsideAnswer is what discard-aside answers. +type DiscardAsideAnswer struct { + // accepted: the act's id, which the ending event carries + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` + // why it was not taken; set alone + Error string `json:"error,omitempty"` +} + +// ExpirePointsInput is what expire-points takes. +type ExpirePointsInput struct { + // who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) + Asker string `json:"asker,omitempty"` + // why, which the hand-act log keeps + Why string `json:"why"` +} + +// ExpirePointsAnswer is what expire-points answers. +type ExpirePointsAnswer struct { + // accepted: the act's id, which the ending event carries + Accepted string `json:"accepted,omitempty"` + // busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event + Busy string `json:"busy,omitempty"` + // why it was not taken; set alone + Error string `json:"error,omitempty"` +} + // EndedEvent is the body of the event ended. type EndedEvent struct { // the id the act was answered accepted with, or a hand act's own id (design 47 G 560) diff --git a/go/seats/meshrecovery/contract_test.go b/go/seats/meshrecovery/contract_test.go index 27e7065..8d7277d 100644 --- a/go/seats/meshrecovery/contract_test.go +++ b/go/seats/meshrecovery/contract_test.go @@ -45,12 +45,42 @@ func TestFixtures(t *testing.T) { decode: func(b []byte) (any, error) { var v RestoreKeptAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "kept-points lists a point, an aside and the act that runs", subject: "", given: "{\"asides\":[{\"id\":\"20261111T121200Z\",\"name\":\"mesh-knowledge_ledger\",\"size\":4096}],\"points\":[{\"at\":\"2026-11-11T10:00:00Z\",\"catch-up\":{\"tool\":\"knowledge_catch_up\"},\"consumers\":[{\"name\":\"c1\",\"sequence\":42,\"stream\":\"KV_x\"}],\"digests\":[{\"digest\":\"sha256:00\",\"name\":\"KV_x\"}],\"fingerprint\":\"0123456789ab\",\"form\":2,\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"size\":2048,\"snapshot\":\"2-0123456789ab\"}],\"running\":{\"act\":\"a-1\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"waiting on the dump\",\"waits-on\":\"item-ended of the bus item\"}}", wire: "{\"asides\":[{\"id\":\"20261111T121200Z\",\"name\":\"mesh-knowledge_ledger\",\"size\":4096}],\"points\":[{\"at\":\"2026-11-11T10:00:00Z\",\"catch-up\":{\"tool\":\"knowledge_catch_up\"},\"consumers\":[{\"name\":\"c1\",\"sequence\":42,\"stream\":\"KV_x\"}],\"digests\":[{\"digest\":\"sha256:00\",\"name\":\"KV_x\"}],\"fingerprint\":\"0123456789ab\",\"form\":2,\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"size\":2048,\"snapshot\":\"2-0123456789ab\"}],\"running\":{\"act\":\"a-1\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"waiting on the dump\",\"waits-on\":\"item-ended of the bus item\"}}", decode: func(b []byte) (any, error) { var v KeptPointsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, - {name: "restore-aside names the aside", subject: "", given: "{\"id\":\"20261111T121200Z\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"an aside left at removed\"}", wire: "{\"id\":\"20261111T121200Z\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"an aside left at removed\"}", + {name: "restore-aside names the aside", subject: "", given: "{\"asker\":\"jochen@shanks\",\"id\":\"20261111T121200Z\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"an aside left at removed\"}", wire: "{\"asker\":\"jochen@shanks\",\"id\":\"20261111T121200Z\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"an aside left at removed\"}", decode: func(b []byte) (any, error) { var v RestoreAsideInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, - {name: "cancel names the act", subject: "", given: "{\"act\":\"a-1\",\"why\":\"the dump waits too long\"}", wire: "{\"act\":\"a-1\",\"why\":\"the dump waits too long\"}", + {name: "cancel names the act", subject: "", given: "{\"act\":\"a-1\",\"asker\":\"jochen@shanks\",\"why\":\"the dump waits too long\"}", wire: "{\"act\":\"a-1\",\"asker\":\"jochen@shanks\",\"why\":\"the dump waits too long\"}", decode: func(b []byte) (any, error) { var v CancelInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "take names the fingerprint whose form the point is taken at", subject: "", given: "{\"asker\":\"jochen@shanks\",\"fingerprint\":\"0123456789ab\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"the operator's hand act\"}", wire: "{\"asker\":\"jochen@shanks\",\"fingerprint\":\"0123456789ab\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"the operator's hand act\"}", + decode: func(b []byte) (any, error) { var v TakeInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "take answers accepted with the act", subject: "", given: "{\"accepted\":\"a-20261111t100000\"}", wire: "{\"accepted\":\"a-20261111t100000\"}", + decode: func(b []byte) (any, error) { var v TakeAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "restore takes a point by its name", subject: "", given: "{\"asker\":\"jochen@shanks\",\"from-backup\":true,\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"snapshot\":\"2-0123456789ab\",\"why\":\"the operator's hand act\"}", wire: "{\"asker\":\"jochen@shanks\",\"from-backup\":true,\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"snapshot\":\"2-0123456789ab\",\"why\":\"the operator's hand act\"}", + decode: func(b []byte) (any, error) { var v RestoreInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "restore takes a keeper's snapshot by its request", subject: "", given: "{\"asker\":\"jochen@shanks\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"request\":\"r-20261111t100000\",\"why\":\"the operator's hand act\"}", wire: "{\"asker\":\"jochen@shanks\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"request\":\"r-20261111t100000\",\"why\":\"the operator's hand act\"}", + decode: func(b []byte) (any, error) { var v RestoreInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "restore answers busy with the act that runs", subject: "", given: "{\"busy\":\"a-20261111t100000\"}", wire: "{\"busy\":\"a-20261111t100000\"}", + decode: func(b []byte) (any, error) { var v RestoreAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "retry names the module and its kept data", subject: "", given: "{\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"a failed take\"}", wire: "{\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"a failed take\"}", + decode: func(b []byte) (any, error) { var v RetryInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "retry answers an error when nothing failed", subject: "", given: "{\"error\":\"nothing to retry\"}", wire: "{\"error\":\"nothing to retry\"}", + decode: func(b []byte) (any, error) { var v RetryAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "aside sets the live kept data aside", subject: "", given: "{\"asker\":\"jochen@shanks\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"the operator's hand act\"}", wire: "{\"asker\":\"jochen@shanks\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"the operator's hand act\"}", + decode: func(b []byte) (any, error) { var v AsideInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "aside answers accepted with the act", subject: "", given: "{\"accepted\":\"a-20261111t100000\"}", wire: "{\"accepted\":\"a-20261111t100000\"}", + decode: func(b []byte) (any, error) { var v AsideAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "discard-aside names the aside", subject: "", given: "{\"asker\":\"jochen@shanks\",\"id\":\"20261111T121200Z\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"the operator's hand act\"}", wire: "{\"asker\":\"jochen@shanks\",\"id\":\"20261111T121200Z\",\"kept\":\"ledger\",\"module\":\"mesh-knowledge\",\"why\":\"the operator's hand act\"}", + decode: func(b []byte) (any, error) { var v DiscardAsideInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "discard-aside answers an error", subject: "", given: "{\"error\":\"no such aside\"}", wire: "{\"error\":\"no such aside\"}", + decode: func(b []byte) (any, error) { var v DiscardAsideAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "expire-points has no field of its own", subject: "", given: "{\"asker\":\"operator\",\"why\":\"the points past 90 days\"}", wire: "{\"asker\":\"operator\",\"why\":\"the points past 90 days\"}", + decode: func(b []byte) (any, error) { var v ExpirePointsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "expire-points answers accepted with the act", subject: "", given: "{\"accepted\":\"a-20261111t100000\"}", wire: "{\"accepted\":\"a-20261111t100000\"}", + decode: func(b []byte) (any, error) { var v ExpirePointsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "cancel answers accepted with the act it cancelled", subject: "", given: "{\"accepted\":\"a-1\"}", wire: "{\"accepted\":\"a-1\"}", + decode: func(b []byte) (any, error) { var v CancelAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, {name: "cancel answers an error naming the step an act has begun", subject: "", given: "{\"error\":\"the act has begun: step restoring\"}", wire: "{\"error\":\"the act has begun: step restoring\"}", decode: func(b []byte) (any, error) { var v CancelAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, + {name: "cancel answers busy with the act that runs", subject: "", given: "{\"busy\":\"a-20261111t100000\"}", wire: "{\"busy\":\"a-20261111t100000\"}", + decode: func(b []byte) (any, error) { var v CancelAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil}, } for _, c := range cases { v, err := c.decode([]byte(c.given)) diff --git a/seats/mesh-recovery/fixtures/verbs.json b/seats/mesh-recovery/fixtures/verbs.json index 71fbe83..65f5c8b 100644 --- a/seats/mesh-recovery/fixtures/verbs.json +++ b/seats/mesh-recovery/fixtures/verbs.json @@ -103,7 +103,8 @@ "module": "mesh-knowledge", "kept": "ledger", "id": "20261111T121200Z", - "why": "an aside left at removed" + "why": "an aside left at removed", + "asker": "jochen@shanks" } }, { @@ -111,7 +112,129 @@ "of": "verb:cancel.input", "given": { "act": "a-1", - "why": "the dump waits too long" + "why": "the dump waits too long", + "asker": "jochen@shanks" + } + }, + { + "name": "take names the fingerprint whose form the point is taken at", + "of": "verb:take.input", + "given": { + "module": "mesh-knowledge", + "kept": "ledger", + "why": "the operator's hand act", + "asker": "jochen@shanks", + "fingerprint": "0123456789ab" + } + }, + { + "name": "take answers accepted with the act", + "of": "verb:take.answer", + "given": { + "accepted": "a-20261111t100000" + } + }, + { + "name": "restore takes a point by its name", + "of": "verb:restore.input", + "given": { + "module": "mesh-knowledge", + "kept": "ledger", + "why": "the operator's hand act", + "asker": "jochen@shanks", + "snapshot": "2-0123456789ab", + "from-backup": true + } + }, + { + "name": "restore takes a keeper's snapshot by its request", + "of": "verb:restore.input", + "given": { + "module": "mesh-knowledge", + "kept": "ledger", + "why": "the operator's hand act", + "asker": "jochen@shanks", + "request": "r-20261111t100000" + } + }, + { + "name": "restore answers busy with the act that runs", + "of": "verb:restore.answer", + "given": { + "busy": "a-20261111t100000" + } + }, + { + "name": "retry names the module and its kept data", + "of": "verb:retry.input", + "given": { + "module": "mesh-knowledge", + "kept": "ledger", + "why": "a failed take" + } + }, + { + "name": "retry answers an error when nothing failed", + "of": "verb:retry.answer", + "given": { + "error": "nothing to retry" + } + }, + { + "name": "aside sets the live kept data aside", + "of": "verb:aside.input", + "given": { + "module": "mesh-knowledge", + "kept": "ledger", + "why": "the operator's hand act", + "asker": "jochen@shanks" + } + }, + { + "name": "aside answers accepted with the act", + "of": "verb:aside.answer", + "given": { + "accepted": "a-20261111t100000" + } + }, + { + "name": "discard-aside names the aside", + "of": "verb:discard-aside.input", + "given": { + "module": "mesh-knowledge", + "kept": "ledger", + "why": "the operator's hand act", + "asker": "jochen@shanks", + "id": "20261111T121200Z" + } + }, + { + "name": "discard-aside answers an error", + "of": "verb:discard-aside.answer", + "given": { + "error": "no such aside" + } + }, + { + "name": "expire-points has no field of its own", + "of": "verb:expire-points.input", + "given": { + "why": "the points past 90 days", + "asker": "operator" + } + }, + { + "name": "expire-points answers accepted with the act", + "of": "verb:expire-points.answer", + "given": { + "accepted": "a-20261111t100000" + } + }, + { + "name": "cancel answers accepted with the act it cancelled", + "of": "verb:cancel.answer", + "given": { + "accepted": "a-1" } }, { @@ -120,5 +243,12 @@ "given": { "error": "the act has begun: step restoring" } + }, + { + "name": "cancel answers busy with the act that runs", + "of": "verb:cancel.answer", + "given": { + "busy": "a-20261111t100000" + } } ] diff --git a/seats/mesh-recovery/seat.json b/seats/mesh-recovery/seat.json index 92ca793..31fff7a 100644 --- a/seats/mesh-recovery/seat.json +++ b/seats/mesh-recovery/seat.json @@ -208,6 +208,10 @@ "why": { "type": "string", "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" } }, "required": [ @@ -253,6 +257,10 @@ "why": { "type": "string", "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" } }, "required": [ @@ -263,10 +271,15 @@ }, "answer": { "type": "object", + "description": "the act cancelled, or busy, or the error; one of the three is set (design 47 G 682, 691)", "properties": { - "cancelled": { - "type": "boolean", - "description": "the act ended cancelled" + "accepted": { + "type": "string", + "description": "accepted: the id of the act it cancelled, whose ending event follows under that id" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" }, "error": { "type": "string", @@ -274,6 +287,338 @@ } } } + }, + { + "name": "take", + "description": "Hand act: take a point of one module's kept data at that fingerprint's form, as snapshot-kept does with no catch-up. Answers accepted, busy or error at once; the point comes on the event ended (design 47 G 682, 554).", + "by-caller": true, + "class": "act", + "input": { + "type": "object", + "properties": { + "module": { + "type": "string", + "description": "the module", + "minLength": 1 + }, + "kept": { + "type": "string", + "description": "the kept data, its local name in the module's manifest", + "minLength": 1 + }, + "fingerprint": { + "type": "string", + "description": "the fingerprint whose form the point is taken at", + "minLength": 1 + }, + "why": { + "type": "string", + "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" + } + }, + "required": [ + "module", + "kept", + "fingerprint", + "why" + ], + "additionalProperties": false + }, + "answer": { + "type": "object", + "description": "the act accepted, or busy with the act that runs, or the error; one of the three is set (design 47 G 554)", + "properties": { + "accepted": { + "type": "string", + "description": "accepted: the act's id, which the ending event carries" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" + }, + "error": { + "type": "string", + "description": "why it was not taken; set alone" + } + } + } + }, + { + "name": "restore", + "description": "Hand act: restore one module's kept data as restore-kept does, from a point by its name or from a keeper's snapshot by its request; exactly one of snapshot and request, and from-backup only with snapshot (design 47 G 682, 681). Answers accepted, busy or error at once; the result comes on the event restored.", + "by-caller": true, + "class": "act", + "input": { + "type": "object", + "properties": { + "module": { + "type": "string", + "description": "the module", + "minLength": 1 + }, + "kept": { + "type": "string", + "description": "the kept data, its local name in the module's manifest", + "minLength": 1 + }, + "snapshot": { + "type": "string", + "description": "a restore point's name", + "minLength": 1 + }, + "request": { + "type": "string", + "description": "a keeper's snapshot by its request (design 47 G 681)", + "minLength": 1 + }, + "from-backup": { + "type": "boolean", + "description": "ask the backup holder for the points directory when the point is missing there; only with snapshot" + }, + "why": { + "type": "string", + "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" + } + }, + "required": [ + "module", + "kept", + "why" + ], + "additionalProperties": false + }, + "answer": { + "type": "object", + "description": "the act accepted, or busy with the act that runs, or the error; one of the three is set (design 47 G 554)", + "properties": { + "accepted": { + "type": "string", + "description": "accepted: the act's id, which the ending event carries" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" + }, + "error": { + "type": "string", + "description": "why it was not taken; set alone" + } + } + } + }, + { + "name": "retry", + "description": "Hand act: ask again the last failed act of that module and kept data, with its fields; the error nothing to retry when its last act did not fail. The result comes on that act's ending event (design 47 G 682).", + "by-caller": true, + "class": "act", + "input": { + "type": "object", + "properties": { + "module": { + "type": "string", + "description": "the module", + "minLength": 1 + }, + "kept": { + "type": "string", + "description": "the kept data, its local name in the module's manifest", + "minLength": 1 + }, + "why": { + "type": "string", + "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" + } + }, + "required": [ + "module", + "kept", + "why" + ], + "additionalProperties": false + }, + "answer": { + "type": "object", + "description": "the act accepted, or busy with the act that runs, or the error; one of the three is set (design 47 G 554)", + "properties": { + "accepted": { + "type": "string", + "description": "accepted: the act's id, which the ending event carries" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" + }, + "error": { + "type": "string", + "description": "why it was not taken; set alone" + } + } + } + }, + { + "name": "aside", + "description": "Hand act: set the live kept data aside without restoring (design 47 G 516, 682). Answers accepted, busy or error at once; the result comes on the event set-aside.", + "by-caller": true, + "class": "act", + "input": { + "type": "object", + "properties": { + "module": { + "type": "string", + "description": "the module", + "minLength": 1 + }, + "kept": { + "type": "string", + "description": "the kept data, its local name in the module's manifest", + "minLength": 1 + }, + "why": { + "type": "string", + "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" + } + }, + "required": [ + "module", + "kept", + "why" + ], + "additionalProperties": false + }, + "answer": { + "type": "object", + "description": "the act accepted, or busy with the act that runs, or the error; one of the three is set (design 47 G 554)", + "properties": { + "accepted": { + "type": "string", + "description": "accepted: the act's id, which the ending event carries" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" + }, + "error": { + "type": "string", + "description": "why it was not taken; set alone" + } + } + } + }, + { + "name": "discard-aside", + "description": "Hand act: remove one aside's directory (design 47 G 682). Answers accepted, busy or error at once; the result comes on the event aside-discarded.", + "by-caller": true, + "class": "act", + "input": { + "type": "object", + "properties": { + "module": { + "type": "string", + "description": "the module", + "minLength": 1 + }, + "kept": { + "type": "string", + "description": "the kept data, its local name in the module's manifest", + "minLength": 1 + }, + "id": { + "type": "string", + "description": "the aside's id", + "minLength": 1 + }, + "why": { + "type": "string", + "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" + } + }, + "required": [ + "module", + "kept", + "id", + "why" + ], + "additionalProperties": false + }, + "answer": { + "type": "object", + "description": "the act accepted, or busy with the act that runs, or the error; one of the three is set (design 47 G 554)", + "properties": { + "accepted": { + "type": "string", + "description": "accepted: the act's id, which the ending event carries" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" + }, + "error": { + "type": "string", + "description": "why it was not taken; set alone" + } + } + } + }, + { + "name": "expire-points", + "description": "Hand act: remove the points past their 90 days now, as the module does by itself (design 47 G 551, 682). Answers accepted, busy or error at once; the result comes on the event expiry-ended.", + "by-caller": true, + "class": "act", + "input": { + "type": "object", + "properties": { + "why": { + "type": "string", + "description": "why, which the hand-act log keeps" + }, + "asker": { + "type": "string", + "description": "who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682)" + } + }, + "required": [ + "why" + ], + "additionalProperties": false + }, + "answer": { + "type": "object", + "description": "the act accepted, or busy with the act that runs, or the error; one of the three is set (design 47 G 554)", + "properties": { + "accepted": { + "type": "string", + "description": "accepted: the act's id, which the ending event carries" + }, + "busy": { + "type": "string", + "description": "busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event" + }, + "error": { + "type": "string", + "description": "why it was not taken; set alone" + } + } + } } ], "events": [ diff --git a/ts/seats/meshrecovery/index.d.ts b/ts/seats/meshrecovery/index.d.ts index 5d98c89..fda42f1 100644 --- a/ts/seats/meshrecovery/index.d.ts +++ b/ts/seats/meshrecovery/index.d.ts @@ -10,6 +10,12 @@ export declare const verbs: { readonly keptPoints: "kept-points"; readonly restoreAside: "restore-aside"; readonly cancel: "cancel"; + readonly take: "take"; + readonly restore: "restore"; + readonly retry: "retry"; + readonly aside: "aside"; + readonly discardAside: "discard-aside"; + readonly expirePoints: "expire-points"; }; export declare const events: { @@ -194,6 +200,8 @@ export interface KeptPointsAnswer { /** is what restore-aside takes. */ export interface RestoreAsideInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; /** the aside's id */ "id": string; /** the kept data, its local name in the module's manifest */ @@ -218,18 +226,160 @@ export interface RestoreAsideAnswer { export interface CancelInput { /** the act's id */ "act": string; + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; /** why, which the hand-act log keeps */ "why": string; } /** is what cancel answers. */ export interface CancelAnswer { - /** the act ended cancelled */ - "cancelled"?: boolean; + /** accepted: the id of the act it cancelled, whose ending event follows under that id */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; /** why not, naming the step an act has begun; set alone */ "error"?: string; } +/** is what take takes. */ +export interface TakeInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; + /** the fingerprint whose form the point is taken at */ + "fingerprint": string; + /** the kept data, its local name in the module's manifest */ + "kept": string; + /** the module */ + "module": string; + /** why, which the hand-act log keeps */ + "why": string; +} + +/** is what take answers. */ +export interface TakeAnswer { + /** accepted: the act's id, which the ending event carries */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; + /** why it was not taken; set alone */ + "error"?: string; +} + +/** is what restore takes. */ +export interface RestoreInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; + /** ask the backup holder for the points directory when the point is missing there; only with snapshot */ + "from-backup"?: boolean; + /** the kept data, its local name in the module's manifest */ + "kept": string; + /** the module */ + "module": string; + /** a keeper's snapshot by its request (design 47 G 681) */ + "request"?: string; + /** a restore point's name */ + "snapshot"?: string; + /** why, which the hand-act log keeps */ + "why": string; +} + +/** is what restore answers. */ +export interface RestoreAnswer { + /** accepted: the act's id, which the ending event carries */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; + /** why it was not taken; set alone */ + "error"?: string; +} + +/** is what retry takes. */ +export interface RetryInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; + /** the kept data, its local name in the module's manifest */ + "kept": string; + /** the module */ + "module": string; + /** why, which the hand-act log keeps */ + "why": string; +} + +/** is what retry answers. */ +export interface RetryAnswer { + /** accepted: the act's id, which the ending event carries */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; + /** why it was not taken; set alone */ + "error"?: string; +} + +/** is what aside takes. */ +export interface AsideInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; + /** the kept data, its local name in the module's manifest */ + "kept": string; + /** the module */ + "module": string; + /** why, which the hand-act log keeps */ + "why": string; +} + +/** is what aside answers. */ +export interface AsideAnswer { + /** accepted: the act's id, which the ending event carries */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; + /** why it was not taken; set alone */ + "error"?: string; +} + +/** is what discard-aside takes. */ +export interface DiscardAsideInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; + /** the aside's id */ + "id": string; + /** the kept data, its local name in the module's manifest */ + "kept": string; + /** the module */ + "module": string; + /** why, which the hand-act log keeps */ + "why": string; +} + +/** is what discard-aside answers. */ +export interface DiscardAsideAnswer { + /** accepted: the act's id, which the ending event carries */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; + /** why it was not taken; set alone */ + "error"?: string; +} + +/** is what expire-points takes. */ +export interface ExpirePointsInput { + /** who asked: the caller the tool runner proved and recorded for the call (who@node, or operator), which the tools bundle's recovery tool passes and a module's process leaves out; the hand-act log names it beside the account the bus proved (design 47 G 682) */ + "asker"?: string; + /** why, which the hand-act log keeps */ + "why": string; +} + +/** is what expire-points answers. */ +export interface ExpirePointsAnswer { + /** accepted: the act's id, which the ending event carries */ + "accepted"?: string; + /** busy: the id of the act that runs; it keeps no queue, so the caller asks again on that act's ending event */ + "busy"?: string; + /** why it was not taken; set alone */ + "error"?: string; +} + /** is the body of the event ended. */ export interface EndedEvent { /** the id the act was answered accepted with, or a hand act's own id (design 47 G 560) */ diff --git a/ts/seats/meshrecovery/index.js b/ts/seats/meshrecovery/index.js index 2ceb51f..dac40f3 100644 --- a/ts/seats/meshrecovery/index.js +++ b/ts/seats/meshrecovery/index.js @@ -10,6 +10,12 @@ export const verbs = { keptPoints: "kept-points", restoreAside: "restore-aside", cancel: "cancel", + take: "take", + restore: "restore", + retry: "retry", + aside: "aside", + discardAside: "discard-aside", + expirePoints: "expire-points", }; export const events = {