Skip to content

Resolve the fabriq brain by port, and split the e2e suite into its own module - #39

Merged
juicycleff merged 6 commits into
mainfrom
core-module-split
Sep 3, 2026
Merged

juicycleff merged 6 commits into
mainfrom
core-module-split

Conversation

@juicycleff

Copy link
Copy Markdown
Contributor

Draft, because it does not compile yet, and the reason is outside this repo. See the blocker at the bottom.

Two things, and the second is why the first was needed.

The fabriq brain resolves by port

injectFabric used to reach into the container for a concrete facade. It now asks for query.Fabric and the entity registry by name, so a remote engine resolves exactly the way a local one does.

The two ways that can fail are not the same failure and are no longer treated as one. No facade in the container means the app does not use fabriq, which is ordinary and stays quiet. A facade present but its registry missing means fabriq is wired wrong, so that one is logged before the brain degrades to a no-op. Losing a working brain silently is the outcome worth being noisy about.

The e2e suite moves into its own module

inttest/ is a nested module now, and the root module is ninety-nine lines of go.mod lighter for it. Testcontainers, elasticsearch and clickhouse belong to an integration suite, not to the dependency graph of everybody who imports cortex. make test-integration runs it.

What rebasing changed

This branch sat behind main by a hundred and three commits, so both go.mod files here are what go mod tidy produces against current main rather than what it produced in June.

inttest also gained a replace for integrations/fabriq. That became a module of its own while this branch sat, so the root replace no longer reached it, and without the new one the suite would have been exercising a published version of the integration rather than the tree it ships beside.

The blocker

integrations/fabriq builds on main and does not build here:

./wire.go:81:65: undefined: registry.ServiceName
./wire.go:84:66: undefined: registry.ServiceName

registry.ServiceName exists in the working copy of fabriq at ../../TwinOS/fabriq and in no published version of github.com/xraph/fabriq, which is what integrations/fabriq/go.mod requires. So this needs a fabriq release carrying core/registry.ServiceName before it can go green, and the version bump is a one line change once there is one.

Worth deciding separately: inttest/go.mod replaces github.com/xraph/fabriq with ../../../../TwinOS/fabriq, a path outside this repository. That works on one machine and nowhere else, CI included. Fine for a suite gated behind a build tag and run by hand, and worth knowing about before anyone expects the target to work on their own checkout.

What does pass

go build ./... and go test ./... on the root module, with the usual mongo container failures that fail on main too. golangci-lint is clean. The inttest module vets under -tags integration.

Note on the other branch

di-inject-query-fabric held the first two of these four commits and nothing else, so it is contained in this branch entirely. Nothing is lost by deleting it.

EngineOption and EngineOptions named *fabriq.Fabriq to look the facade up
in the container. buildToolkit already took an interface, so that one
type parameter was the only thing dragging in fabriq's composition root,
and with it ClickHouse, Elasticsearch, pgx, go-redis and Trove. The build
graph was 1421 packages.

Injecting core/query.Fabric takes it to 258 with every driver gone. An
engine reached over the wire registers *remote.Fabric under the same key
and nothing here changes.

The registry now arrives as its own argument rather than off the facade.
query.Fabric has no Registry() method on purpose: entity specs are
declared client-side and a remote engine cannot serve them.

Splitting it out created a failure the old code could not have, where the
fabric resolves but the registry does not. That is fabriq wired wrong,
not fabriq absent, and it is logged before the brain degrades to a no-op.
An empty container stays quiet, since an app with no fabriq in it is not
a misconfiguration.

go.sum barely moves, because the integration test still opens a real
embedded engine and a test-only import counts fully against the module
graph. Splitting core out into its own module is what would fix that.

The replace directive is local dev. Repin to a released fabriq and drop
it before this merges.
The preceding commit swapped the concrete facade for the port interface but
left go.mod untidied, so the tree would not build: go refused every command
asking for a tidy first. This is that tidy.

Testcontainers moves to v0.44.0 and stays direct, since the conformance
suite drives real postgres and mongo containers. Build, vet and the full
race suite pass, containers included.
The test opens a real embedded engine, which is the right thing for it
to do and the reason cortex kept requiring root fabriq. go mod tidy
counts a test import at full weight, so one file held the whole driver
set in our go.sum.

It lives in inttest/ now with its own go.mod. The main module requires
fabriq/core and nothing else. The replaces are local development only.
The integration test in inttest/fabriqbrain_e2e_test.go lives in its own
nested module, so nothing in this repo ran it: there was no
test-integration target at all before this, unlike kgkit and fabriq.

make test-integration now cds into inttest and runs it with the
integration tag. CI here delegates build/test/lint to the shared
xraph/workflows/.github/workflows/go-ci.yml reusable workflow, which the
comment in ci.yml says probes for Makefile targets; that workflow lives in
a separate repository outside this change, so whether it picks the new
target up on its own could not be checked from here.
Rebasing onto main moved the dependency graph under this branch, so both
go.mod files are what go mod tidy produces now rather than what it
produced in June. The root module loses ninety-nine lines of it, which
is the point of the split: testcontainers, elasticsearch and clickhouse
belong to the integration suite rather than to anyone importing cortex.

inttest also gained a replace for integrations/fabriq. That became its
own module while this branch sat, so the root replace no longer reached
it, and without one the suite would have been testing a published
version of the integration instead of the tree it ships with.
registry.ServiceName is published now, so integrations/fabriq compiles
against a real release rather than a working copy. fabriq also split
core into its own module, so the parent goes up with it: holding the old
parent alongside the new core made every core import ambiguous.

The two replace directives pointing outside this repository are gone
with it. They existed because ServiceName was unreleased, and while
they were there the integration suite could only build on one machine.
It vets under -tags integration on a clean checkout now, so CI can
finally run it.
@juicycleff
juicycleff marked this pull request as ready for review September 3, 2026 13:40
@juicycleff

Copy link
Copy Markdown
Contributor Author

Unblocked and out of draft.

fabriq 1.6.4 publishes core/registry.ServiceName, so integrations/fabriq compiles against a release rather than a working copy. fabriq also split core into its own module, so the parent had to go up alongside it: holding the old parent next to the new core made every core/... import ambiguous.

Both replace directives pointing outside this repository are gone with it. They only existed because ServiceName was unreleased, and while they were there the integration suite could build on exactly one machine. inttest vets under -tags integration on a clean checkout now, so CI can run it.

Rebased onto current main, which includes the a2a work from #37.

go build ./... and go test ./... pass on the root module, integrations/fabriq builds and tests, inttest vets under its tag, and golangci-lint is clean. The only failure is store/mongo on container startup, which fails on main too.

@juicycleff
juicycleff merged commit 648e127 into main Sep 3, 2026
11 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant