T-1: the tool runner's manifest says 0.1, the finding stream and the keeper's findings-asked, and follows catalog-revision

Builds: design 47 G §368, §387, §196 (consumes catalog-revision; views.modules goes with T-2's first view)
Held: waits (§426) goes with the every-event part, which removes the code reading it.

Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
2026-11-11 12:04:32 +01:00
parent 447a8d0359
commit a5b8ae1a72
2 changed files with 23 additions and 2 deletions
@@ -21,10 +21,18 @@ func TestTheManifestNamesTheFirstFamiliesOneByOne(t *testing.T) {
Module string `json:"module"`
Waits []string `json:"waits"`
Consumes []string `json:"consumes"`
Streams []struct {
Name string `json:"name"`
Events []string `json:"events"`
} `json:"streams"`
}
if err := json.Unmarshal(raw, &m); err != nil {
t.Fatal(err)
}
if len(m.Streams) != 1 || m.Streams[0].Name != "node-tools-findings" ||
!reflect.DeepEqual(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) {
t.Errorf("the finding stream is %+v, want node-tools-findings with the three finding events (design 47 G §387)", m.Streams)
}
want := []string{"mesh-knowledge.reviewed", "mesh-delivery-gate.transition", "gitea.forge.status",
"mesh-self-check.checked", "operator-channel.decided.claude-code"}
if m.Module != "node-tools" || !reflect.DeepEqual(m.Waits, want) {
@@ -37,7 +45,10 @@ func TestTheManifestNamesTheFirstFamiliesOneByOne(t *testing.T) {
}
// A wait is no consumer (ADR 0367 §2): what it consumes is the four views families of its first views (ADR 0615 §5, issue
// 1966 TLS-5) and the two events of the seat that serves the seat list (ADR 0636 §4), and nothing else.
wantConsumes := []string{"mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-delivery-assigner.views.assignments", "mesh-delivery-assigner.views.seat-holders",
// Design 47 G §196, §387: the catalog half by `catalog-revision` (never the indexer's `views.modules`), and the keeper's
// `findings-asked`; the finding stream below. `views.modules` goes with the first view that follows it (T-2).
wantConsumes := []string{"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-assigner.views.seat-holders",
"mesh-delivery-indexer.views.manifests", "mesh-delivery-indexer.views.modules"}
if !reflect.DeepEqual(m.Consumes, wantConsumes) {
t.Errorf("the tool runner consumes %v, want %v", m.Consumes, wantConsumes)
+11 -1
View File
@@ -1,6 +1,6 @@
{
"module": "node-tools",
"version": "2",
"version": "0.1",
"slug": "node-tools",
"tool-runner": true,
"invokes": [
@@ -71,13 +71,23 @@
"findings"
],
"consumes": [
"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-assigner.views.seat-holders",
"mesh-delivery-indexer.views.manifests",
"mesh-delivery-indexer.views.modules"
],
"streams": [
{
"name": "node-tools-findings",
"events": ["finding-written.*", "finding-cleared.*", "findings-stated.*"],
"max-age-days": 7,
"max-mib": 16
}
],
"reads": [
"mesh-provisioner.provisions",
"mesh-provisioner.plans"