From 1b963d6871657582c905249f447a26bc471404fe Mon Sep 17 00:00:00 2001 From: Sam Maassen Date: Sat, 8 Aug 2026 20:52:38 +0200 Subject: [PATCH 1/2] test(t280): run ontology integration in CI Resolve real-ontology tests through MOOS_ONTOLOGY_PATH, add the private ffs0 checkout job, and pin the D10 widened-governs occupancy case. Validation: MOOS_INTEGRATION=1 go test ./internal/operad; go test ./internal/operad; go vet ./internal/operad authored-by: agent:vscode.hp-laptop.wolfram / session:sam.kernel-proper / t280-a5c-t6 --- .github/workflows/go-ci.yml | 23 ++++++++++++++++ internal/operad/integration_ontology_test.go | 29 ++++++++++++++++++++ internal/operad/loader_port_pairs_test.go | 15 +--------- internal/operad/member_of_pair_test.go | 15 +--------- internal/operad/occupancy_test.go | 23 ++++++++++++++++ internal/operad/validate_color_gate_test.go | 15 +--------- 6 files changed, 78 insertions(+), 42 deletions(-) create mode 100644 internal/operad/integration_ontology_test.go diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 2566e6c..8a58edf 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -29,3 +29,26 @@ jobs: run: go vet ./... - name: test run: go test ./... + + ontology-integration: + if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Checkout private ontology source + uses: actions/checkout@v4 + with: + repository: Collider-Data-Systems/ffs0 + path: ffs0 + token: ${{ secrets.FFS0_READ_TOKEN }} + sparse-checkout: kb/superset/ontology.json + sparse-checkout-cone-mode: false + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Test with real ontology + env: + MOOS_INTEGRATION: "1" + MOOS_ONTOLOGY_PATH: ${{ github.workspace }}/ffs0/kb/superset/ontology.json + run: go test ./... diff --git a/internal/operad/integration_ontology_test.go b/internal/operad/integration_ontology_test.go new file mode 100644 index 0000000..622aaea --- /dev/null +++ b/internal/operad/integration_ontology_test.go @@ -0,0 +1,29 @@ +package operad + +import ( + "os" + "testing" +) + +func integrationOntologyPath(t *testing.T) string { + t.Helper() + + if path := os.Getenv("MOOS_ONTOLOGY_PATH"); path != "" { + if _, err := os.Stat(path); err != nil { + t.Fatalf("MOOS_ONTOLOGY_PATH=%q is not readable: %v", path, err) + } + return path + } + + candidates := []string{ + "../../../ffs0/kb/superset/ontology.json", + "../../../../ffs0/kb/superset/ontology.json", + } + for _, path := range candidates { + if _, err := os.Stat(path); err == nil { + return path + } + } + t.Fatalf("MOOS_INTEGRATION=1 but ontology.json not found; set MOOS_ONTOLOGY_PATH or provide one of %v", candidates) + return "" +} diff --git a/internal/operad/loader_port_pairs_test.go b/internal/operad/loader_port_pairs_test.go index 4437078..c5fa205 100644 --- a/internal/operad/loader_port_pairs_test.go +++ b/internal/operad/loader_port_pairs_test.go @@ -120,20 +120,7 @@ func TestLoadRegistry_LoadsRealOntology_WF19Pairs(t *testing.T) { if os.Getenv("MOOS_INTEGRATION") != "1" { t.Skip("set MOOS_INTEGRATION=1 to run ontology integration check") } - candidates := []string{ - "../../../ffs0/kb/superset/ontology.json", - "../../../../ffs0/kb/superset/ontology.json", - } - var path string - for _, c := range candidates { - if _, err := os.Stat(c); err == nil { - path = c - break - } - } - if path == "" { - t.Fatalf("MOOS_INTEGRATION=1 but ontology.json not found at %v", candidates) - } + path := integrationOntologyPath(t) reg, err := LoadRegistry(path) if err != nil { diff --git a/internal/operad/member_of_pair_test.go b/internal/operad/member_of_pair_test.go index c5c18b5..1a39f67 100644 --- a/internal/operad/member_of_pair_test.go +++ b/internal/operad/member_of_pair_test.go @@ -172,20 +172,7 @@ func TestLoadRegistry_DeclaredPairsAllColored_Integration(t *testing.T) { if os.Getenv("MOOS_INTEGRATION") != "1" { t.Skip("set MOOS_INTEGRATION=1 to run the declared-vs-loaded ontology readback") } - candidates := []string{ - "../../../ffs0/kb/superset/ontology.json", - "../../../../ffs0/kb/superset/ontology.json", - } - var path string - for _, c := range candidates { - if _, err := os.Stat(c); err == nil { - path = c - break - } - } - if path == "" { - t.Fatalf("MOOS_INTEGRATION=1 but ontology.json not found at %v", candidates) - } + path := integrationOntologyPath(t) reg, err := LoadRegistry(path) if err != nil { diff --git a/internal/operad/occupancy_test.go b/internal/operad/occupancy_test.go index d2dc380..00c588c 100644 --- a/internal/operad/occupancy_test.go +++ b/internal/operad/occupancy_test.go @@ -165,6 +165,29 @@ func TestCheckAdminCapability_UserActor(t *testing.T) { } } +func TestCheckAdminCapability_WidenedGovernsSet(t *testing.T) { + state := stateWithAdminChain() + for _, agentURN := range []graph.URN{ + "urn:moos:agent:claude-cowork.hp-laptop", + "urn:moos:agent:vscode.hp-laptop.copilot", + } { + state.Nodes[agentURN] = graph.Node{URN: agentURN, TypeID: "agent"} + relationURN := graph.URN("urn:moos:rel:sam.governs." + string(agentURN)) + state.Relations[relationURN] = graph.Relation{ + URN: relationURN, + RewriteCategory: graph.WF02, + SrcURN: "urn:moos:user:sam", + SrcPort: "governs", + TgtURN: agentURN, + TgtPort: "governed-by", + } + } + + if !CheckAdminCapability(state, "urn:moos:session:sam.hp-laptop") { + t.Error("expected D10 agent governance links to coexist with the superadmin grant") + } +} + func TestCheckAdminCapability_GroupActor(t *testing.T) { state := stateWithAdminChain() state.Nodes["urn:moos:group:sam"] = graph.Node{URN: "urn:moos:group:sam", TypeID: "group"} diff --git a/internal/operad/validate_color_gate_test.go b/internal/operad/validate_color_gate_test.go index 56878ea..358112e 100644 --- a/internal/operad/validate_color_gate_test.go +++ b/internal/operad/validate_color_gate_test.go @@ -2,7 +2,6 @@ package operad import ( "os" - "path/filepath" "strings" "testing" @@ -274,19 +273,7 @@ func TestIntegration_ColorGate_CoversAllDeclaredOntologyPairs(t *testing.T) { if os.Getenv("MOOS_INTEGRATION") != "1" { t.Skip("set MOOS_INTEGRATION=1 to run against the sibling ffs0 ontology") } - var path string - for _, cand := range []string{ - filepath.Join("..", "..", "..", "ffs0", "kb", "superset", "ontology.json"), - filepath.Join("..", "..", "..", "..", "ffs0", "kb", "superset", "ontology.json"), - } { - if _, err := os.Stat(cand); err == nil { - path = cand - break - } - } - if path == "" { - t.Fatalf("MOOS_INTEGRATION=1 set but sibling ffs0 ontology.json not found") - } + path := integrationOntologyPath(t) reg, err := LoadRegistry(path) if err != nil { t.Fatalf("LoadRegistry(%s): %v", path, err) From 17132dcc456a8d869048dc5f8168669d51afa3f3 Mon Sep 17 00:00:00 2001 From: Sam Maassen Date: Sat, 8 Aug 2026 20:54:25 +0200 Subject: [PATCH 2/2] ci: gate private ontology checkout on credential Emit an explicit warning when FFS0_READ_TOKEN is unavailable and run the real-ontology integration suite automatically once the read-only secret is provisioned. --- .github/workflows/go-ci.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 8a58edf..294f8bd 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -33,21 +33,29 @@ jobs: ontology-integration: if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} runs-on: ubuntu-latest + env: + FFS0_READ_TOKEN: ${{ secrets.FFS0_READ_TOKEN }} steps: - uses: actions/checkout@v4 + - name: Report missing private-repository credential + if: ${{ env.FFS0_READ_TOKEN == '' }} + run: echo '::warning::FFS0_READ_TOKEN is not configured; real-ontology integration tests were not run.' - name: Checkout private ontology source + if: ${{ env.FFS0_READ_TOKEN != '' }} uses: actions/checkout@v4 with: repository: Collider-Data-Systems/ffs0 path: ffs0 - token: ${{ secrets.FFS0_READ_TOKEN }} + token: ${{ env.FFS0_READ_TOKEN }} sparse-checkout: kb/superset/ontology.json sparse-checkout-cone-mode: false - uses: actions/setup-go@v5 + if: ${{ env.FFS0_READ_TOKEN != '' }} with: go-version-file: go.mod cache: true - name: Test with real ontology + if: ${{ env.FFS0_READ_TOKEN != '' }} env: MOOS_INTEGRATION: "1" MOOS_ONTOLOGY_PATH: ${{ github.workspace }}/ffs0/kb/superset/ontology.json