Skip to content
quarry Artifact [d15796b585]
Login

Artifact [d15796b585]

Artifact d15796b585214a57107e29be2687fcd09cccf233551f1b56458a79d38ecb29f8:


// Package arch holds quarry's structural assertions. This test enforces the
// ops-seam rule from docs/rfcs/0001-quarry-forge.md §9: only internal/ops
// may import the data planes. It runs `go list` over the module, so it needs
// no dependencies and cannot drift from the real build graph.
package arch

import (
	"encoding/json"
	"os/exec"
	"strings"
	"testing"
)

// dataPlanePrefixes are import-path prefixes only internal/ops may reach.
// Grow this list as data planes land (SQLite driver, forge OLTP, the zit
// subprocess wrapper). The zero state still verifies the mechanism.
var dataPlanePrefixes = []string{
	"github.com/ncruces/go-sqlite3",
	"github.com/nats-io/nats-server",
	"github.com/nats-io/nats.go",
	"craftdesign.group/quarry/internal/zitcli",
	"craftdesign.group/quarry/internal/index",
	"craftdesign.group/quarry/internal/events",
	"craftdesign.group/quarry/internal/oltp",
	"craftdesign.group/quarry/internal/xfer",
	"craftdesign.group/quarry/internal/lease",
	"craftdesign.group/quarry/internal/chat",
	"craftdesign.group/quarry/internal/notify",
}

// allowedImporters may import data-plane packages directly. internal/api
// is here because RegisterAll is the wiring point where op Run closures
// over the data planes are built — the seam invariant is that data
// reaches HTML and API responses only through registered ops, and this
// list is what makes web/, cmd/, and everything else unable to shortcut.
var allowedImporters = []string{
	"craftdesign.group/quarry/cmd/quarry",       // composition root: builds the object graph
	"craftdesign.group/quarry/internal/harness", // test harness: stands the system up from nothing
	"craftdesign.group/quarry/internal/ops",
	"craftdesign.group/quarry/internal/api",
	"craftdesign.group/quarry/internal/ingest",
	"craftdesign.group/quarry/internal/zitcli",
	"craftdesign.group/quarry/internal/index",
	"craftdesign.group/quarry/internal/events",
	"craftdesign.group/quarry/internal/oltp",
	"craftdesign.group/quarry/internal/xfer",   // sync fronting: execs zit itself (0001 §7)
	"craftdesign.group/quarry/internal/lease",  // single-writer coordination (0001 §3)
	"craftdesign.group/quarry/internal/chat",   // per-repo chat plane (0001 §5)
	"craftdesign.group/quarry/internal/notify", // notification trigger edge (0001 §5)
}

type pkg struct {
	ImportPath string
	Imports    []string
	Deps       []string
}

func TestOnlyOpsImportsDataPlanes(t *testing.T) {
	out, err := exec.Command("go", "list", "-json", "./...").Output()
	if err != nil {
		t.Fatalf("go list: %v", err)
	}

	dec := json.NewDecoder(strings.NewReader(string(out)))
	for dec.More() {
		var p pkg
		if err := dec.Decode(&p); err != nil {
			t.Fatal(err)
		}
		if isAllowed(p.ImportPath) {
			continue
		}
		for _, imp := range p.Imports {
			for _, plane := range dataPlanePrefixes {
				if strings.HasPrefix(imp, plane) {
					t.Errorf("%s imports data plane %s directly; route through internal/ops", p.ImportPath, imp)
				}
			}
		}
	}
}

func isAllowed(path string) bool {
	for _, a := range allowedImporters {
		if path == a || strings.HasPrefix(path, a+"/") {
			return true
		}
	}
	return false
}