WM11, CK12, EN1 (manifest half): finding stream, the keeper's ask and MAJOR.MINOR version in the manifests of the watchman, the checker and enrolment

Builds: design 47 G §383, §387, §368 (the findings writer half waits for the generated writer of §439)

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 12:14:24 +01:00
parent c3068b15e1
commit 5fc1dbd264
6 changed files with 32 additions and 10 deletions
@@ -41,6 +41,7 @@ type stream struct {
Name string `json:"name"`
Events []string `json:"events"`
MaxAgeDays int `json:"max-age-days,omitempty"`
MaxMiB int `json:"max-mib,omitempty"`
Retention string `json:"retention,omitempty"`
}
@@ -140,7 +141,7 @@ func TestManifestDeclarations(t *testing.T) { // 1678/AC1
// The checker is woken by a build module's report of a toolchain, as the indexer is: the bucket may not exist when it starts.
// And a group's check by the package registry seats' published of its tagged versions (design 51 *Tagged versions*).
if want := []string{"go-package-registry.published", "mesh-build-go.toolchain.reported", "mesh-build-node.toolchain.reported",
"mesh-catalog.catalog-revision", "mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-delivery-assigner.views.assignments", "mesh-delivery-indexer.views.candidates", "mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules",
"mesh-catalog.catalog-revision", "mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-conditions.findings-asked", "mesh-delivery-assigner.views.assignments", "mesh-delivery-indexer.views.candidates", "mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules",
"mesh-delivery-indexer.views.packages", "mesh-delivery-indexer.views.predefined", "mesh-delivery-indexer.views.seat-definitions", "npm-package-registry.published"}; !reflect.DeepEqual(sorted(m.Consumes), want) {
t.Errorf("consumes = %v, want %v", m.Consumes, want)
}
@@ -154,7 +155,7 @@ func TestManifestDeclarations(t *testing.T) { // 1678/AC1
// Its family asks (design 51 *Tagged versions*, design 26): tag-wanted and verdict, seven days, apart from checks so a
// waiter on a verdict does not wake on a tag ask; a stream that keeps its history, the predefined form of an event family
// (ADR 0592 §6, the manifest validator).
if want := []stream{{Name: "checks", Events: []string{"preview.**", "owed.**", "try.**"}}, {Name: "asks", Events: []string{"verdict", "tag-wanted"}, Retention: "history"}}; !reflect.DeepEqual(m.Streams, want) {
if want := []stream{{Name: "checks", Events: []string{"preview.**", "owed.**", "try.**"}}, {Name: "asks", Events: []string{"verdict", "tag-wanted"}, Retention: "history"}, {Name: "mesh-delivery-checker-findings", Events: []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}, MaxAgeDays: 7, MaxMiB: 16}}; !reflect.DeepEqual(m.Streams, want) {
t.Errorf("streams = %+v, want %+v", m.Streams, want)
}
// Only the checker's account publishes try.* on its stream checks: the stream is declared by its owner alone, and no other
+5 -3
View File
@@ -1,6 +1,6 @@
{
"module": "mesh-delivery-checker",
"version": "1",
"version": "0.1",
"slug": "checker",
"claims": [
{
@@ -28,11 +28,13 @@
"mesh-delivery-indexer.views.packages",
"mesh-delivery-indexer.views.predefined",
"mesh-delivery-indexer.views.seat-definitions",
"npm-package-registry.published"
"npm-package-registry.published",
"mesh-conditions.findings-asked"
],
"streams": [
{ "name": "checks", "events": ["preview.**", "owed.**", "try.**"] },
{ "name": "asks", "events": ["verdict", "tag-wanted"], "retention": "history" }
{ "name": "asks", "events": ["verdict", "tag-wanted"], "retention": "history" },
{ "name": "mesh-delivery-checker-findings", "events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"], "max-age-days": 7, "max-mib": 16 }
],
"state": [
{ "name": "asks", "history": 1 },
@@ -57,6 +57,12 @@ type manifest struct {
Consumes []string `json:"consumes"`
Invokes []string `json:"invokes"`
State []state `json:"state"`
Streams []struct {
Name string `json:"name"`
Events []string `json:"events"`
MaxAgeDays int `json:"max-age-days"`
MaxMiB int `json:"max-mib"`
} `json:"streams"`
OwnSecrets map[string]string `json:"own-secrets"`
SecretsOwner string `json:"secrets-owner"`
Resources []map[string]any `json:"resources"`
@@ -103,6 +109,11 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6
if !regexp.MustCompile(`^[0-9]+\.[0-9]+$`).MatchString(m.Version) {
t.Errorf("version = %q, want MAJOR.MINOR", m.Version)
}
// Design 47 G §387: the finding stream, 7 days and 16 MiB, and the keeper's ask.
if len(m.Streams) != 1 || m.Streams[0].Name != "mesh-delivery-watchman-findings" || m.Streams[0].MaxAgeDays != 7 || m.Streams[0].MaxMiB != 16 ||
!reflect.DeepEqual(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) {
t.Errorf("streams = %+v, want the finding stream", m.Streams)
}
// DLV-M5 (ADR 0615 §1): the assigner's wants and the indexer's modules are their owners' states, asked by their read
// tools and followed by their views families, never read.
for _, r := range m.Reads {
@@ -116,7 +127,7 @@ func TestManifestStateAndReads(t *testing.T) { // 1135/AC6
t.Errorf("invokes = %v, want %v", m.Invokes, want)
}
// DLV-M5 its first views, 1585/T20 the indexer's take-in events, and DLV-W1 (ADR 0595 §4): the accepted verdicts and the bus module's created and refused, durably.
if want := []string{"mesh-delivery-assigner.views.wants", "mesh-delivery-indexer.take-in.pending", "mesh-delivery-indexer.take-in.taken", "mesh-delivery-indexer.views.modules", "mesh-catalog.manifest-accepted", "mesh-delivery.source-moved", "mesh-delivery.filling", "mesh-delivery.full", "mesh-delivery.room", "mesh-delivery.record-opened", "mesh-delivery.record-ended", "mesh-catalog.filling", "mesh-catalog.full", "mesh-catalog.room", "mesh-wants.filling", "mesh-wants.full", "mesh-wants.room", "mesh-grants.filling", "mesh-grants.full", "mesh-grants.room", "mesh-pipeline-runner.pipeline-started", "mesh-pipeline-runner.step-started", "mesh-pipeline-runner.step-ended", "mesh-broker.created", "mesh-broker.refused"}; !reflect.DeepEqual(m.Consumes, want) {
if want := []string{"mesh-delivery-assigner.views.wants", "mesh-delivery-indexer.take-in.pending", "mesh-delivery-indexer.take-in.taken", "mesh-delivery-indexer.views.modules", "mesh-catalog.manifest-accepted", "mesh-delivery.source-moved", "mesh-delivery.filling", "mesh-delivery.full", "mesh-delivery.room", "mesh-delivery.record-opened", "mesh-delivery.record-ended", "mesh-catalog.filling", "mesh-catalog.full", "mesh-catalog.room", "mesh-wants.filling", "mesh-wants.full", "mesh-wants.room", "mesh-grants.filling", "mesh-grants.full", "mesh-grants.room", "mesh-pipeline-runner.pipeline-started", "mesh-pipeline-runner.step-started", "mesh-pipeline-runner.step-ended", "mesh-broker.created", "mesh-broker.refused", "mesh-conditions.findings-asked"}; !reflect.DeepEqual(m.Consumes, want) {
t.Errorf("consumes = %v, want %v", m.Consumes, want)
}
// 1952/WM1: the watchman holds the seat mesh-watchdogs at mesh scope, its first seat (novox/hq ADR 0564 §1, §4).
+5 -1
View File
@@ -30,6 +30,9 @@
"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",
@@ -55,7 +58,8 @@
"mesh-pipeline-runner.step-started",
"mesh-pipeline-runner.step-ended",
"mesh-broker.created",
"mesh-broker.refused"
"mesh-broker.refused",
"mesh-conditions.findings-asked"
],
"tools": [
"watchman_findings",
@@ -119,7 +119,7 @@ func theManifestSaysWhatTheCodeDoes(t *testing.T) {
for _, e := range EndEvents {
heard = append(heard, Seat+"."+e)
}
heard = append(heard, assignerModule+".views."+assignmentsState)
heard = append(heard, assignerModule+".views."+assignmentsState, "mesh-conditions.findings-asked") // the keeper's ask (design 47 G §387)
if !slices.Equal(m.Consumes, heard) {
t.Errorf("consumes %v, the end events are %v", m.Consumes, heard)
}
+6 -2
View File
@@ -1,6 +1,6 @@
{
"module": "mesh-enrolment",
"version": "1",
"version": "0.1",
"runs-as": "mesh-enrolment",
"claims": [
{
@@ -16,12 +16,16 @@
]
}
],
"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",
"mesh-node-enroller.enrolment-revoked",
"mesh-node-enroller.enrolment-expired",
"mesh-delivery-assigner.views.assignments"
"mesh-delivery-assigner.views.assignments",
"mesh-conditions.findings-asked"
],
"uses": [
"operator-channel"