From 24753bfc2c029965acf941ff6e89ca3c7461c7b9 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 23 Oct 2026 14:48:41 +0200 Subject: [PATCH] Grant gitea_contains in the indexer's invokes and test every called forge tool is granted (issue 1900) --- .../mesh-delivery-indexer/manifest_test.go | 37 +++++++++++++++++-- modules/mesh-delivery-indexer/module.json | 3 +- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/modules/mesh-delivery-indexer/manifest_test.go b/modules/mesh-delivery-indexer/manifest_test.go index ce9784a..0c28769 100644 --- a/modules/mesh-delivery-indexer/manifest_test.go +++ b/modules/mesh-delivery-indexer/manifest_test.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "reflect" + "regexp" "slices" "strings" "testing" @@ -94,9 +95,10 @@ func TestManifestDeclarations(t *testing.T) { // 1238/AC1, 1444 (reads the build if m.SecretsOwner != "mesh-delivery-indexer" { t.Errorf("secrets-owner = %q", m.SecretsOwner) } - // One invoke: the forge's trees with the named paths' objects, since the indexer is the one reader of a manifest's paths - // (ADR 0499 clauses 2 and 3, ADR 0495 clause 1, the lead's decision L8 of R4e). - if want := []string{"gitea.gitea_commit_trees"}; !reflect.DeepEqual(m.Invokes, want) { + // Two invokes: the forge's trees (the named paths' objects, since the indexer is the one reader of a manifest's paths: + // ADR 0499 clauses 2 and 3, ADR 0495 clause 1; and the module directories of the trunk, issue 1900) and whether a + // commit is in another (issue 1900). + if want := []string{"gitea.gitea_commit_trees", "gitea.gitea_contains"}; !reflect.DeepEqual(m.Invokes, want) { t.Errorf("invokes = %v, want %v", m.Invokes, want) } // No emits, no streams, no bus, no seat, no tool (ADR 0437 ยง4). @@ -169,3 +171,32 @@ func TestServesNoRequestSubjectAndHoldsNoTicker(t *testing.T) { // 1238/AC9 (ADR t.Fatalf("read %d source files, want the program's", files) } } + +// Every forge tool the program calls is granted in invokes, or the bus refuses the call (issue 1900). +func TestEveryGiteaToolTheCodeCallsIsInInvokes(t *testing.T) { + m, _ := load(t) + files, err := filepath.Glob("cmd/mesh-delivery-indexer/*.go") + if err != nil || len(files) == 0 { + t.Fatalf("no program files: %v", err) + } + re := regexp.MustCompile(`gitea\.gitea_[a-z_]+`) + seen := 0 + for _, f := range files { + if strings.HasSuffix(f, "_test.go") { + continue + } + src, err := os.ReadFile(f) + if err != nil { + t.Fatal(err) + } + for _, tool := range re.FindAllString(string(src), -1) { + seen++ + if !slices.Contains(m.Invokes, tool) { + t.Errorf("%s calls %s, which invokes does not grant", f, tool) + } + } + } + if seen < 2 { + t.Errorf("found %d tool names in the program, want at least the two it calls", seen) + } +} diff --git a/modules/mesh-delivery-indexer/module.json b/modules/mesh-delivery-indexer/module.json index 706ee06..755eaea 100644 --- a/modules/mesh-delivery-indexer/module.json +++ b/modules/mesh-delivery-indexer/module.json @@ -21,7 +21,8 @@ "mesh-delivery-gate.source" ], "invokes": [ - "gitea.gitea_commit_trees" + "gitea.gitea_commit_trees", + "gitea.gitea_contains" ], "own-secrets": { "broker": "${dir:state}/broker"