From db9be8b9e260bb6302f55f6352b43ef20140be99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20B=C3=BCrgi?= <6334612+rbuergi@users.noreply.github.com> Date: Tue, 27 Oct 2026 10:21:25 +0100 Subject: [PATCH] move(core): the memex test container and the voice gateway leave core for MeshWeaver.Plugins (delete half) src/MeshWeaver.Testcontainers and clients/voice-gateway move to MeshWeaver.Plugins (src/ and clients/). Both were consumed only there: the test container's two consumers already lived in Plugins, and nothing in core built or tested the voice gateway. Their Testcontainers and Testcontainers.PostgreSql pins leave with them; no core project restores either. MeshWeaver.Hosting.AspNetCore and MeshWeaver.Markdown.Export.Contract stay: a satellite's compiled module derives from MeshEndpointProviderAttribute and compiles it from core source, and the contract is pinned by Hosting.AspNetCore alone. clients/python stays: core's python-gate and pandas-gate images COPY it. CarvingProjectsOutOfCore records all three verdicts. Co-Authored-By: Claude Opus 5.5 --- .claude/skills/i18n/SKILL.md | 2 +- .github/scripts/control-image-acceptance.sh | 4 +- .github/workflows/clients.yml | 13 +- .github/workflows/dotnet-test.yml | 2 +- Directory.Packages.props | 4 - MeshWeaver.slnx | 1 - clients/README.md | 38 +- clients/voice-gateway/.gitignore | 5 - clients/voice-gateway/Dockerfile | 19 - clients/voice-gateway/README.md | 116 ---- clients/voice-gateway/docker-compose.yml | 20 - clients/voice-gateway/entrypoint.sh | 16 - .../memex_voice_gateway/__init__.py | 3 - .../memex_voice_gateway/__main__.py | 235 ------- .../memex_voice_gateway/config.py | 227 ------- .../memex_voice_gateway/homeassistant.py | 81 --- .../memex_voice_gateway/musicassistant.py | 77 --- .../memex_voice_gateway/ollama.py | 369 ----------- .../memex_voice_gateway/pipeline.py | 194 ------ .../memex_voice_gateway/router.py | 574 ------------------ .../memex_voice_gateway/satellite.py | 292 --------- .../memex_voice_gateway/session.py | 48 -- .../voice-gateway/memex_voice_gateway/stt.py | 64 -- .../memex_voice_gateway/threads.py | 203 ------- .../voice-gateway/memex_voice_gateway/tts.py | 236 ------- .../voice-gateway/memex_voice_gateway/vad.py | 94 --- clients/voice-gateway/pyproject.toml | 25 - clients/voice-gateway/run-local.sh | 23 - clients/voice-gateway/tests/test_context.py | 202 ------ clients/voice-gateway/tests/test_ollama.py | 127 ---- clients/voice-gateway/tests/test_pipeline.py | 80 --- clients/voice-gateway/tests/test_router.py | 243 -------- clients/voice-gateway/tests/test_streaming.py | 73 --- clients/voice-gateway/tests/test_stt.py | 15 - clients/voice-gateway/tests/test_threads.py | 93 --- clients/voice-gateway/tests/test_vad.py | 47 -- clients/voice-gateway/wakeword/README.md | 19 - clients/voice-gateway/wakeword/hey_memex.json | 18 - .../voice-gateway/wakeword/hey_memex.tflite | Bin 62304 -> 0 bytes clients/voice-gateway/wakeword/phase2_data.py | 135 ---- .../voice-gateway/wakeword/phase2_train.sh | 62 -- .../voice-gateway/wakeword/setup-hey-memex.sh | 33 - .../Architecture/CarvingProjectsOutOfCore.md | 43 +- .../Data/Architecture/DockerHubInCi.md | 2 +- .../DocsFollowTheFunctionality.md | 5 +- .../Data/Architecture/FirstRunSetup.md | 2 +- .../Architecture/InstanceIdentityAndSetup.md | 2 +- .../Architecture/VoiceModelDistribution.md | 4 +- .../MemexContainer.cs | 202 ------ .../MemexReadiness.cs | 183 ------ .../MeshWeaver.Testcontainers.csproj | 21 - src/MeshWeaver.Testcontainers/README.md | 50 -- test/Directory.Packages.props | 1 - 53 files changed, 74 insertions(+), 4573 deletions(-) delete mode 100644 clients/voice-gateway/.gitignore delete mode 100644 clients/voice-gateway/Dockerfile delete mode 100644 clients/voice-gateway/README.md delete mode 100644 clients/voice-gateway/docker-compose.yml delete mode 100644 clients/voice-gateway/entrypoint.sh delete mode 100644 clients/voice-gateway/memex_voice_gateway/__init__.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/__main__.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/config.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/homeassistant.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/musicassistant.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/ollama.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/pipeline.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/router.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/satellite.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/session.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/stt.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/threads.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/tts.py delete mode 100644 clients/voice-gateway/memex_voice_gateway/vad.py delete mode 100644 clients/voice-gateway/pyproject.toml delete mode 100755 clients/voice-gateway/run-local.sh delete mode 100644 clients/voice-gateway/tests/test_context.py delete mode 100644 clients/voice-gateway/tests/test_ollama.py delete mode 100644 clients/voice-gateway/tests/test_pipeline.py delete mode 100644 clients/voice-gateway/tests/test_router.py delete mode 100644 clients/voice-gateway/tests/test_streaming.py delete mode 100644 clients/voice-gateway/tests/test_stt.py delete mode 100644 clients/voice-gateway/tests/test_threads.py delete mode 100644 clients/voice-gateway/tests/test_vad.py delete mode 100644 clients/voice-gateway/wakeword/README.md delete mode 100644 clients/voice-gateway/wakeword/hey_memex.json delete mode 100644 clients/voice-gateway/wakeword/hey_memex.tflite delete mode 100644 clients/voice-gateway/wakeword/phase2_data.py delete mode 100755 clients/voice-gateway/wakeword/phase2_train.sh delete mode 100755 clients/voice-gateway/wakeword/setup-hey-memex.sh delete mode 100644 src/MeshWeaver.Testcontainers/MemexContainer.cs delete mode 100644 src/MeshWeaver.Testcontainers/MemexReadiness.cs delete mode 100644 src/MeshWeaver.Testcontainers/MeshWeaver.Testcontainers.csproj delete mode 100644 src/MeshWeaver.Testcontainers/README.md diff --git a/.claude/skills/i18n/SKILL.md b/.claude/skills/i18n/SKILL.md index f93495b551..92136f8814 100644 --- a/.claude/skills/i18n/SKILL.md +++ b/.claude/skills/i18n/SKILL.md @@ -96,7 +96,7 @@ merge β€” and it is now the ONLY localization guard in this repo. The web clients' catalog lives at **`MeshWeaver.Plugins/clients/react/src/i18n/`**. `044a85618` ("The GUI leaves the platform", 2026-08-25) moved the web clients out; `clients/` in core now holds -only `python/` and `voice-gateway/`, and the six guards the old text and the `Clients` workflow +only `python/` (`voice-gateway/` followed to MeshWeaver.Plugins `clients/` in the core slimming), and the six guards the old text and the `Clients` workflow named β€” `i18n/localize.test.ts`, `render/parity.test.ts`, `ciTrigger.test.ts`, `grpc-web/src/{wire,rest}Contract.test.ts`, `portal-next/e2e` β€” no longer exist **in this repo**. Do not recreate them here; the mirror belongs where the client lives. diff --git a/.github/scripts/control-image-acceptance.sh b/.github/scripts/control-image-acceptance.sh index 38afd00295..bedd55289b 100755 --- a/.github/scripts/control-image-acceptance.sh +++ b/.github/scripts/control-image-acceptance.sh @@ -107,8 +107,8 @@ fi grep 'Database migration completed' "$MIGLOG" | tail -n 1 # boot_and_wait : start the image, wait for /health then /ready inside the budget, -# then stop it. The environment is the chart's self-host minimum (MeshWeaver.Testcontainers' -# MemexBuilder): Postgres for nodes, the filesystem backend, single-node Localhost clustering, no +# then stop it. The environment is the chart's self-host minimum (MeshWeaver.Plugins' +# src/MeshWeaver.Testcontainers MemexBuilder): Postgres for nodes, the filesystem backend, single-node Localhost clustering, no # dev login. Nothing control-specific is passed: the closed type set, the seeded module and the # disabled sweep are properties of the IMAGE, which is exactly what is under test. boot_and_wait() { diff --git a/.github/workflows/clients.yml b/.github/workflows/clients.yml index 14e95dfd82..db170bd51e 100644 --- a/.github/workflows/clients.yml +++ b/.github/workflows/clients.yml @@ -24,8 +24,8 @@ name: Clients # # THIS LIST WAS MUCH LONGER, and most of it is now WRONG rather than merely unused. `044a85618` # ("The GUI leaves the platform: the view packs and the web clients", 2026-08-25) moved the web -# clients to MeshWeaver.Plugins. `clients/` holds only `python/` and `voice-gateway/`, one job -# survives (`python-sdk`), and EVERY test the old inventory named is gone from this repo: +# clients to MeshWeaver.Plugins. `clients/` holds only `python/` (`voice-gateway/` followed in the +# core slimming), one job survives (`python-sdk`), and EVERY test the old inventory named is gone from this repo: # # clients/react/src/i18n/localize.test.ts clients/grpc-web/src/wireContract.test.ts # clients/react/src/render/parity.test.ts clients/grpc-web/src/restContract.test.ts @@ -44,11 +44,10 @@ name: Clients # for the surviving clients, this list is maintained BY HAND and will rot again. If you add a # cross-tree read to `clients/python`, add its path here yourself. # -# 🚨 `clients/voice-gateway` HAS NO JOB HERE β€” this workflow runs `python-sdk` and nothing -# else, so a voice-gateway change triggers a run that does not test it. Adding a path for it would -# make that worse, not better: the run would go green having verified nothing about the thing that -# changed, which is precisely the "fires reliably, checks nothing" state this comment block exists -# to record. If voice-gateway needs CI, it needs a JOB first, and its inputs listed second. +# `clients/voice-gateway` used to sit here with NO job: a change to it triggered a run that tested +# nothing about it. It moved to MeshWeaver.Plugins `clients/voice-gateway` (core slimming), where +# its own `Voice gateway` workflow runs its suite. `clients/python` stays: core's own python-gate and +# pandas-gate images COPY it, and it generates from core's canonical proto. # # The original rationale, still correct and still the reason the protos path is listed: # filtering on "clients/**" alone made every cross-tree guard blind to the side that actually diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/dotnet-test.yml index 6aa66e796c..d5e0cf7942 100644 --- a/.github/workflows/dotnet-test.yml +++ b/.github/workflows/dotnet-test.yml @@ -994,7 +994,7 @@ jobs: # 🚨 This job used to pre-pull `pgvector/pgvector:pg17` from Docker Hub, anonymously, on every # shard. Since the Postgres suites left core (the test-move tranches, #2847 and its successors) # NO core suite starts a container: nothing references Testcontainers.PostgreSql, and the one - # project that named MeshWeaver.Testcontainers (Memex.Portal.Shared.Test, now in + # project that named MeshWeaver.Testcontainers (Memex.Portal.Shared.Test; both now live in # MeshWeaver.Plugins) exercises readiness logic against an in-process host. So the pull fetched an image nothing used β€” and on 2026-10-09 it # was the ONLY red of six shards Γ— several PRs (#6381 among them), Docker Hub answering # `toomanyrequests` to the runner pool's shared egress IP. Retrying a per-IP window is not a diff --git a/Directory.Packages.props b/Directory.Packages.props index 4635600aea..ee78690a83 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -78,10 +78,6 @@ - - - false - A Testcontainers module that starts the memex portal image as a disposable test substrate. - - - - - - - - - - - diff --git a/src/MeshWeaver.Testcontainers/README.md b/src/MeshWeaver.Testcontainers/README.md deleted file mode 100644 index 165ce075e4..0000000000 --- a/src/MeshWeaver.Testcontainers/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# MeshWeaver.Testcontainers β€” a disposable memex as a test substrate - -A [Testcontainers](https://dotnet.testcontainers.org/) module that starts the **portal image the -platform build produced** the way `Testcontainers.PostgreSql` starts a real Postgres: the test is a -client of a real memex, and the platform under test is exactly the image the pipeline promoted β€” no -core source checkout, no in-process mesh, no `MeshWeaver.Fixture`. - -```csharp -await using INetwork network = new NetworkBuilder().Build(); -await using var postgres = new PostgreSqlBuilder("pgvector/pgvector:pg17") - .WithNetwork(network).WithNetworkAliases("postgres") - .WithDatabase("memex").WithUsername("postgres").WithPassword("postgres") - .Build(); -await postgres.StartAsync(ct); -// …then run the memex-migration image of the SAME build once on `network` with -// ConnectionStrings__memex set, and require exit code 0 β€” the portal refuses an unmigrated schema. - -await using var memex = new MemexBuilder() - .WithImage("meshweaver.azurecr.io/memex-portal-ai@sha256:…") // the pinned build under test - .WithNetwork(network) - .WithPostgres("Host=postgres;Port=5432;Database=memex;Username=postgres;Password=postgres") - .Build(); -await memex.StartAsync(ct); - -// memex.BaseAddress, memex.McpEndpoint, memex.HealthEndpoint -``` - -## What the builder sets, and why - -The portal image runs `Memex.Portal.Distributed` (Orleans + Postgres). A throwaway instance is: - -| setting | value | reason | -|---|---|---| -| `Deployment:Backend` | `Filesystem` | Azure-free self-host backend; `Deployment:DataRoot=/tmp/memex-data` (the image runs non-root and cannot create `/data`) | -| `Features:Orleans:Clustering` | `Localhost` | single silo in one container | -| `ConnectionStrings:memex` | **required** β€” `WithPostgres(...)` | the instance's data; reachable *from inside* the container (a network alias, not a host-mapped port). Migrate it first with the `memex-migration` image of the same build β€” `DbVersionGate` refuses an unmigrated schema | -| `Graph:Storage:Type` | `PostgreSql` β€” set by `WithPostgres(...)` | the image bakes no storage type, so without it the container serves the first-run SETUP wizard and composes no mesh (#6037) | -| `Authentication:EnableDevLogin` | `true` (explicit) | the host forces it OFF unless the value is literally `true` | -| wait strategy | `MemexReadiness`: `/health` answers the startup census (`Healthy`/`Degraded`) and `/api/version` is not redirected to `/setup` | the MESH started, not merely the process β€” a probe path's flat `200 ok` is answered by the setup wizard too. A wizard, or a container that exits first, fails `StartAsync` at once with the reason | -| output | stdout/stderr β†’ the test output | the container's log is the test's log | - -`WithImage` is the consumer's: this module never guesses a tag. - -## Where it fits - -- **Black-box and substrate suites** (the Postgres hosting suites, end-to-end flows) use this β€” a - memex on a Postgres, exercised over HTTP/MCP. -- **Engine suites that inject fakes through DI** keep an in-process mesh; that is a different - primitive, not this one. -- The library is test support: `IsPackable=false`, never a NuGet package. diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props index 33f92c5fc5..fd35fdaef0 100644 --- a/test/Directory.Packages.props +++ b/test/Directory.Packages.props @@ -3,6 +3,5 @@ - \ No newline at end of file