diff --git a/contracts/module.json b/contracts/module.json index b024f0d0..1fda11a3 100644 --- a/contracts/module.json +++ b/contracts/module.json @@ -1,6 +1,6 @@ { "module": "mesh-delivery-contracts", - "version": "1", + "version": "0.1", "build": { "artifacts": [ { diff --git a/modules/mesh-delivery-assigner/module.json b/modules/mesh-delivery-assigner/module.json index aaf2d344..dffd8ee6 100644 --- a/modules/mesh-delivery-assigner/module.json +++ b/modules/mesh-delivery-assigner/module.json @@ -1,6 +1,6 @@ { "module": "mesh-delivery-assigner", - "version": "1", + "version": "0.1", "slug": "assigner", "runs-as": "mesh-delivery-assigner", "claims": [ diff --git a/modules/mesh-delivery-builder/module.json b/modules/mesh-delivery-builder/module.json index 09b2ed7d..bf2e4224 100644 --- a/modules/mesh-delivery-builder/module.json +++ b/modules/mesh-delivery-builder/module.json @@ -1,6 +1,6 @@ { "module": "mesh-delivery-builder", - "version": "1", + "version": "0.1", "slug": "builder", "claims": [ { diff --git a/modules/mesh-delivery-forge-bridge/module.json b/modules/mesh-delivery-forge-bridge/module.json index c26d1d23..99fcd8f7 100644 --- a/modules/mesh-delivery-forge-bridge/module.json +++ b/modules/mesh-delivery-forge-bridge/module.json @@ -1,6 +1,6 @@ { "module": "mesh-delivery-forge-bridge", - "version": "1", + "version": "0.1", "slug": "forge-bridge", "consumes": [ "git.pull-updated", diff --git a/modules/mesh-delivery-indexer/internal/index/verdicts_test.go b/modules/mesh-delivery-indexer/internal/index/verdicts_test.go index b72ad051..b19ec0fd 100644 --- a/modules/mesh-delivery-indexer/internal/index/verdicts_test.go +++ b/modules/mesh-delivery-indexer/internal/index/verdicts_test.go @@ -371,8 +371,8 @@ func TestTheIndexerJudgesEveryManifestOnce(t *testing.T) { } } if !slices.Equal(judge.Foundation, []string{"nats", "mesh-grants", "mesh-delivery-indexer", "mesh-delivery-assigner", "node-tools", - "mesh-delivery-builder", "mesh-delivery-checker", "mesh-config", "mesh-vault", "mesh-delivery-pipeline", "gitea", "distribution"}) { - t.Fatalf("the foundation is %v, want exactly the nine of ADR 0619, the pipeline runner (ADR 0666 §4) and the forge and image registry modules (design 47 G §584)", judge.Foundation) + "mesh-delivery-builder", "mesh-delivery-checker", "mesh-config", "mesh-vault", "mesh-delivery-pipeline", "gitea", "distribution", "mesh-host"}) { + t.Fatalf("the foundation is %v, want exactly the nine of ADR 0619, the pipeline runner (ADR 0666 §4) and the forge and image registry modules (design 47 G §584) and the node-engine's module (§627)", judge.Foundation) } late := hold("late", `{"module":"late","version":"1.0","logs":[{"name":"l"}]}`) grants := hold("mesh-grants", `{"module":"mesh-grants","version":"2.0","logs":[{"name":"l"},{"name":"m"}]}`) diff --git a/modules/mesh-delivery-indexer/judge/g_words_test.go b/modules/mesh-delivery-indexer/judge/g_words_test.go index 59e225db..9fac4f0c 100644 --- a/modules/mesh-delivery-indexer/judge/g_words_test.go +++ b/modules/mesh-delivery-indexer/judge/g_words_test.go @@ -22,6 +22,11 @@ func TestTheJudgeReadsMilestoneGsWords(t *testing.T) { `"streams":[{"name":"gitea-findings","events":["finding-written"],"retention":"history"}],"consumes":["mesh-conditions.findings-asked"]}`}, {name: "the image registry is a foundation part too (§584)", raw: `{"module":"distribution","version":"1.0","state":["findings"],` + `"streams":[{"name":"distribution-findings","events":["finding-written"],"retention":"history"}],"consumes":["mesh-conditions.findings-asked"]}`}, + {name: "the node-engine's module is a foundation part (§627)", raw: `{"module":"mesh-host","version":"1.0","state":["findings"],` + + `"streams":[{"name":"mesh-host-findings","events":["finding-written.*","finding-cleared.*","findings-stated.*"],"max-age-days":7,"max-mib":16}],"consumes":["mesh-conditions.findings-asked"]}`}, + {name: "an old state section entry with max-mib in its bounds (§469, §695)", raw: `{"module":"a","version":"1.0","state":[{"name":"s","max-mib":128}]}`}, + {name: "an old state section entry with max-mib at zero (§469)", raw: `{"module":"a","version":"1.0","state":[{"name":"s","max-mib":0}]}`, want: "max-mib"}, + {name: "an old state section entry with max-mib past the bound (§469)", raw: `{"module":"a","version":"1.0","state":[{"name":"s","max-mib":9000}]}`, want: "max-mib"}, {name: "another part's old findings and stream (§529, §577)", raw: `{"module":"a","version":"1.0","state":["findings"],` + `"streams":[{"name":"a-findings","events":["finding-written"],"retention":"history"}],"consumes":["mesh-conditions.findings-asked"]}`, want: "old sections"}, {name: "another part's findings in its requires (§529)", raw: `{"module":"a","version":"1.0","consumes":["mesh-conditions.findings-asked"],"requires":[` + diff --git a/modules/mesh-delivery-indexer/judge/oldsections.go b/modules/mesh-delivery-indexer/judge/oldsections.go index f9157365..506a214b 100644 --- a/modules/mesh-delivery-indexer/judge/oldsections.go +++ b/modules/mesh-delivery-indexer/judge/oldsections.go @@ -20,10 +20,10 @@ var OldSections = []string{"state", "logs", "streams", "objects"} // composition, assignments, build or delivery needs before it can answer (novox/hq ADR 0619 §1, §3, as ADR 0666 §4 changes // them): the bus module, the grants part, the indexer, the assigner, the tool runner, the builder, the checker, mesh-config, // the vault, the pipeline runner, which runs the bus module's own pipeline, and the forge module and the image registry -// module, which its build calls (design 47 G §584). Their new state goes on their old sections +// module, which its build calls (design 47 G §584), and the node-engine's module, which composes every part (§627). Their new state goes on their old sections // too, so a foundation manifest asking bus state in the new form is refused. var Foundation = []string{"nats", "mesh-grants", "mesh-delivery-indexer", "mesh-delivery-assigner", "node-tools", - "mesh-delivery-builder", "mesh-delivery-checker", "mesh-config", "mesh-vault", "mesh-delivery-pipeline", "gitea", "distribution"} + "mesh-delivery-builder", "mesh-delivery-checker", "mesh-config", "mesh-vault", "mesh-delivery-pipeline", "gitea", "distribution", "mesh-host"} // ViewOwners are the two owners whose state every reader reads through their first views and read tools, never by a // `reads` entry (novox/hq ADR 0615 §1): CountOwnerReads counts what is left of those entries. diff --git a/modules/mesh-delivery-indexer/judge/rules.go b/modules/mesh-delivery-indexer/judge/rules.go index 61c48405..3aca3716 100644 --- a/modules/mesh-delivery-indexer/judge/rules.go +++ b/modules/mesh-delivery-indexer/judge/rules.go @@ -5567,6 +5567,11 @@ var seatStreamsKeptUntilMoved = map[string][]string{ // keptUntilMoved is whether a stream of a manifest is one kept until its module moves it: by the module's name, or by a // seat it claims. func keptUntilMoved(m catalogue.Manifest, stream string) bool { + // A foundation part keeps its old sections for good, its streams among them: its findings stream `-findings` + // (design 47 G §529, A-30) and the image registry's `distribution-events` (§584, A-54). + if slices.Contains(Foundation, m.Module) { + return true + } if slices.Contains(streamsKeptUntilMoved[m.Module], stream) { return true } diff --git a/modules/mesh-delivery-indexer/judge/rules_test.go b/modules/mesh-delivery-indexer/judge/rules_test.go index 781103a5..7ff73f7e 100644 --- a/modules/mesh-delivery-indexer/judge/rules_test.go +++ b/modules/mesh-delivery-indexer/judge/rules_test.go @@ -4683,7 +4683,7 @@ func caseTheMeshsOwnSeatsAreStillClaimable(t *testing.T) { // It delivers the bus, so its holder provides the bus — the rule this check now enforces. m := catalogue.Manifest{Module: "nats", Provides: []catalogue.Offer{{Name: "mesh-bus", Scope: catalogue.ScopeMesh, Credential: &catalogue.OfferCredential{Form: catalogue.CredentialFormNone}}}, - Claims: []catalogue.Claim{{Name: "mesh-broker", Scope: catalogue.ScopeMesh, Serves: []string{"snapshot-kept", "restore-kept"}}}} + Claims: []catalogue.Claim{{Name: "mesh-broker", Scope: catalogue.ScopeMesh, Serves: []string{"snapshot-get", "snapshot-restore", "snapshot-restore-cancel", "snapshot-remove"}}}} if got := problemsFor(t, catalogue.Shelf{"nats": m}); got != "" { t.Fatalf("a mesh seat was refused by the derived check: %s", got) } @@ -5121,6 +5121,18 @@ func caseTwoModulesCannotDeclareOneStream(t *testing.T) { if got := PredefinedFormProblems(catalogue.Manifest{Module: "mesh-build-go", Streams: toolchains}); len(got) != 1 { t.Fatalf("a toolchain stream of a module claiming no build seat was kept by its name: %v", got) } + // A foundation part keeps its old streams for good: its findings stream `-findings` (design 47 G §529, A-30) and + // distribution's `distribution-events` (§584, A-54); a part that is no foundation part keeps none. + findings := []catalogue.StreamDeclaration{{Name: "mesh-config-findings", Events: []string{"finding-written.*"}}} + if got := PredefinedFormProblems(catalogue.Manifest{Module: "mesh-config", Streams: findings}); len(got) != 0 { + t.Fatalf("a foundation part's findings stream was refused: %v", got) + } + if got := PredefinedFormProblems(catalogue.Manifest{Module: "distribution", Streams: []catalogue.StreamDeclaration{{Name: "distribution-events", Events: []string{"old-name-closed"}}}}); len(got) != 0 { + t.Fatalf("a foundation part's events stream was refused: %v", got) + } + if got := PredefinedFormProblems(catalogue.Manifest{Module: "mesh-config-b", Streams: []catalogue.StreamDeclaration{{Name: "mesh-config-b-findings", Events: []string{"finding-written.*"}}}}); len(got) != 1 { + t.Fatalf("a findings stream of a part outside the foundation was kept: %v", got) + } } // A seat name meaning two protocols is the failure nobody could diagnose afterwards. diff --git a/modules/mesh-delivery-pipeline/manifest_test.go b/modules/mesh-delivery-pipeline/manifest_test.go index 36894974..8467fb0d 100644 --- a/modules/mesh-delivery-pipeline/manifest_test.go +++ b/modules/mesh-delivery-pipeline/manifest_test.go @@ -53,12 +53,13 @@ func TestManifest(t *testing.T) { {"old state sections", equalSets(states, []string{seat.StatePipelines, seat.StateKept, "aged", "bounds", "toolchains", "findings", "first-views"})}, // §535, §647, A-77, A-104: an ask no holder takes is bound by a key with its own time to live. {"bounds is key-ttl", keyTTL["bounds"]}, - // §27, §85: the step log on an old stream, its outputs in an old objects section. - // RN24 (§383, §387): beside it, the finding stream its findings are said on. - {"old streams section", equalSets(streams, []string{seat.StateStepLog, "mesh-delivery-pipeline-findings"})}, - {"step-log 128 MiB", len(m.Streams) == 2 && m.Streams[0].MaxMiB == 128}, - {"finding stream 7 days 16 MiB", len(m.Streams) == 2 && m.Streams[1].MaxAgeDays == 7 && m.Streams[1].MaxMiB == 16 && - equalSets(m.Streams[1].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"})}, + // §470 (amending §27, §85): the step log is an old logs section kept 100 days, 128 MiB; RN24 (§383, §387): the finding + // stream its findings are said on is the one old stream. + {"old streams section", equalSets(streams, []string{"mesh-delivery-pipeline-findings"})}, + {"step-log an old logs section of 100 days and 128 MiB", len(m.Logs) == 1 && m.Logs[0].Name == seat.StateStepLog && + m.Logs[0].MaxAgeDays == 100 && m.Logs[0].MaxMiB == 128}, + {"finding stream 7 days 16 MiB", len(m.Streams) == 1 && m.Streams[0].MaxAgeDays == 7 && m.Streams[0].MaxMiB == 16 && + equalSets(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"})}, // RN24 (§368): the version as MAJOR.MINOR, 0.1 with none published. {"version 0.1", m.Version == "0.1"}, {"old objects section", equalSets(objects, []string{seat.StateStepOutputs})}, diff --git a/modules/mesh-delivery-pipeline/module.json b/modules/mesh-delivery-pipeline/module.json index 044ee89a..b66b07dd 100644 --- a/modules/mesh-delivery-pipeline/module.json +++ b/modules/mesh-delivery-pipeline/module.json @@ -90,13 +90,6 @@ } ], "streams": [ - { - "name": "step-log", - "events": [ - "step-log.**" - ], - "max-mib": 128 - }, { "name": "mesh-delivery-pipeline-findings", "events": [ @@ -176,5 +169,12 @@ ] } ] - } + }, + "logs": [ + { + "name": "step-log", + "max-age-days": 100, + "max-mib": 128 + } + ] } diff --git a/modules/mesh-delivery-teller/module.json b/modules/mesh-delivery-teller/module.json index 458c778b..4c00a0d3 100644 --- a/modules/mesh-delivery-teller/module.json +++ b/modules/mesh-delivery-teller/module.json @@ -16,24 +16,27 @@ "mesh-conditions.findings-asked", "mesh-delivery-assigner.views.asks" ], - "streams": [ - { - "name": "mesh-delivery-teller-findings", - "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], - "max-age-days": 7, - "max-mib": 16 - } - ], "emits": [ "answered", "ask-ended" ], "state": [ - { "name": "answers", "history": 5 }, - { "name": "asked", "history": 1 }, - { "name": "ends", "history": 1 }, - { "name": "first-views", "history": 1 }, - { "name": "findings", "history": 1 } + { + "name": "answers", + "history": 5 + }, + { + "name": "asked", + "history": 1 + }, + { + "name": "ends", + "history": 1 + }, + { + "name": "first-views", + "history": 1 + } ], "reads": [ "mesh-delivery-gate.asks", @@ -101,5 +104,29 @@ ] } ] - } + }, + "requires": [ + { + "name": "findings", + "storage": "key-value", + "template": "state", + "options": { + "history": 1 + } + }, + { + "name": "finding-events", + "storage": "stream", + "template": "events", + "options": { + "events": [ + "finding-written.*", + "finding-cleared.*", + "findings-stated.*" + ], + "max-age-days": 7, + "max-mib": 16 + } + } + ] } diff --git a/modules/mesh-delivery-view/module.json b/modules/mesh-delivery-view/module.json index 899e9931..feb4694c 100644 --- a/modules/mesh-delivery-view/module.json +++ b/modules/mesh-delivery-view/module.json @@ -37,10 +37,18 @@ "stuck" ], "state": [ - { "name": "answers", "history": 5 }, - { "name": "reach", "history": 1 }, - { "name": "first-views", "history": 1 }, - { "name": "findings", "history": 1 } + { + "name": "answers", + "history": 5 + }, + { + "name": "reach", + "history": 1 + }, + { + "name": "first-views", + "history": 1 + } ], "consumes": [ "mesh-conditions.findings-asked", @@ -51,14 +59,6 @@ "mesh-delivery-indexer.views.candidates", "mesh-delivery-indexer.views.taken" ], - "streams": [ - { - "name": "mesh-delivery-view-findings", - "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], - "max-age-days": 7, - "max-mib": 16 - } - ], "invokes": [ "mesh-delivery-assigner.assigner_read_asks", "mesh-delivery-assigner.assigner_read_differences", @@ -198,5 +198,29 @@ "from": "files" } ] - } + }, + "requires": [ + { + "name": "findings", + "storage": "key-value", + "template": "state", + "options": { + "history": 1 + } + }, + { + "name": "finding-events", + "storage": "stream", + "template": "events", + "options": { + "events": [ + "finding-written.*", + "finding-cleared.*", + "findings-stated.*" + ], + "max-age-days": 7, + "max-mib": 16 + } + } + ] } diff --git a/modules/mesh-delivery-watchman/module.json b/modules/mesh-delivery-watchman/module.json index 44b51e29..d51fa8b9 100644 --- a/modules/mesh-delivery-watchman/module.json +++ b/modules/mesh-delivery-watchman/module.json @@ -30,9 +30,6 @@ "mesh-delivery-indexer.indexer_read_modules", "seat:mesh-hand-acts.hand-act" ], - "streams": [ - { "name": "mesh-delivery-watchman-findings", "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], "max-age-days": 7, "max-mib": 16 } - ], "consumes": [ "mesh-delivery-assigner.views.wants", "mesh-delivery-indexer.take-in.pending", @@ -73,11 +70,22 @@ "watchman_first_view_again" ], "state": [ - { "name": "presence", "history": 20 }, - { "name": "pulse", "key-ttl": true }, - { "name": "stuck", "history": 20 }, - { "name": "findings", "history": 5 }, - { "name": "first-views", "history": 1 } + { + "name": "presence", + "history": 20 + }, + { + "name": "pulse", + "key-ttl": true + }, + { + "name": "stuck", + "history": 20 + }, + { + "name": "first-views", + "history": 1 + } ], "own-secrets": { "broker": "${dir:state}/broker" @@ -146,5 +154,29 @@ ] } ] - } + }, + "requires": [ + { + "name": "findings", + "storage": "key-value", + "template": "state", + "options": { + "history": 5 + } + }, + { + "name": "finding-events", + "storage": "stream", + "template": "events", + "options": { + "events": [ + "finding-written.*", + "finding-cleared.*", + "findings-stated.*" + ], + "max-age-days": 7, + "max-mib": 16 + } + } + ] } diff --git a/modules/mesh-enrolment/module.json b/modules/mesh-enrolment/module.json index 506c568a..1750442f 100644 --- a/modules/mesh-enrolment/module.json +++ b/modules/mesh-enrolment/module.json @@ -16,9 +16,6 @@ ] } ], - "streams": [ - { "name": "mesh-enrolment-findings", "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], "max-age-days": 7, "max-mib": 16 } - ], "consumes": [ "mesh-node-enroller.node-enrolled", "mesh-node-enroller.enrolment-refused", @@ -52,8 +49,7 @@ { "name": "asked", "history": 5 - }, - "findings" + } ], "tools": [ "enrolment_first_views", @@ -94,5 +90,26 @@ ] } ] - } + }, + "requires": [ + { + "name": "findings", + "storage": "key-value", + "template": "state" + }, + { + "name": "finding-events", + "storage": "stream", + "template": "events", + "options": { + "events": [ + "finding-written.*", + "finding-cleared.*", + "findings-stated.*" + ], + "max-age-days": 7, + "max-mib": 16 + } + } + ] } diff --git a/modules/mesh-grants/module.json b/modules/mesh-grants/module.json index e6e28462..7b3efe8b 100644 --- a/modules/mesh-grants/module.json +++ b/modules/mesh-grants/module.json @@ -1,6 +1,6 @@ { "module": "mesh-grants", - "version": "1", + "version": "0.1", "slug": "grants", "reads": [ "mesh-config.resolved", diff --git a/sdk/module.json b/sdk/module.json index 85afe154..c3d5d6b9 100644 --- a/sdk/module.json +++ b/sdk/module.json @@ -1,6 +1,6 @@ { "module": "mesh-delivery-sdk", - "version": "1", + "version": "0.1", "build": { "artifacts": [ {