Repository navigation
Delete Blazor and the portal GUI from core - #2293
Conversation
Core no longer contains any GUI. The three Blazor projects, the portal's razor,
and the hosts that serve them move to MeshWeaver.Plugins, where the view packs
already live.
src/MeshWeaver.Blazor 112 files
src/MeshWeaver.Blazor.Portal 102
src/MeshWeaver.Hosting.Blazor 10
memex/Memex.Portal.Shared 29 GUI files (77 platform files STAY)
memex/Memex.Portal.Monolith ┐
memex/aspire/Memex.Portal.Distributed ├ hosts
memex/aspire/Memex.AppHost ┘
test/MeshWeaver.Hosting.Blazor.Test 32 files (it tests deleted code)
🚨 The test sweep was WRONG THREE TIMES before it was right, and the wrong
versions all looked reasonable.
Selecting test files by "imports a Blazor namespace" is a proxy for "is a view
test", and the two are different sets. That predicate selected 27 files; the
compiler says only 16 of them actually need a view type. Among the 11 it would
have exiled for an unused `using`:
OrleansTopLevelPartitionGuardTest — the top-level partition guard. It imports
Blazor.Portal for silo wiring whose extensions (ConfigureMeshWeaverServer,
UseOrleansMeshServer) all live in CORE. It compiles fine without the import.
Eight MeshWeaver.Hosting.PostgreSql.Test files were the same shape. Name-matching
fared no better: it misses MessageBubbleState, CompletionItem and
MarkdownCellEditing, which are view types that do not end in View or Page.
What works is neither: strip the import and let the COMPILER classify. Every
file that stays here lost one stale `using` and nothing else.
Two checks earned their place, both suggested in review:
• test COUNT diff across the eight affected suites — -244 removed against 244
expected, exact. It took three attempts to measure correctly (a wrong
checkout, then obj/ copies), and each wrong version showed a suite GAINING
tests from a deletion, which is the only reason I caught them.
• guard/ratchet name check — it named the partition guard before the compiler
would have.
Also verified: NodeTypeDeclarationSelfTypingTest STAYS in core and still runs
(build exit=0 then 2/2 passed). It guards a defect measured at 3.2 failures per
second on every serving pod, its absence is silent by construction, and it was
one predicate away from being swept out.
And two stragglers no source-level check could see: MSBuild <Content Include>
items in Acme.Test copying CSS out of the deleted projects. Only a full-solution
build surfaces those.
Full solution builds clean: -c Release -warnaserror, 0 warnings, 0 errors.
…rojects CI's clean checkout caught what my local build could not: two MSB3030 failures copying src/MeshWeaver.Blazor/wwwroot/standard-page-layout.css and src/MeshWeaver.Blazor.Portal/Layout/PortalLayoutBase.razor.css, both of which this change deletes. 🚨 The fix existed locally and never reached the commit. I edited the csproj AFTER the last `git add`, then collapsed the WIP history with `git reset --soft` — which preserves STAGED content and leaves working-tree edits behind. The local build then passed against a tree the commit did not contain. That is the same shape as the stale-DLL trap earlier tonight: a green signal measuring something other than what was about to ship. The remedy is the same — the authority is the clean build, not the one with my uncommitted work in it.
…ucture-out-of-blazor' into feat/delete-blazor-and-gui-from-core
|
🚧 Back to draft — this must not merge yet. It deletes 77 test files plus Remaining before it is mergeable:
The core-side deletion itself is verified and unchanged: full solution builds clean under |
…ucture-out-of-blazor' into feat/delete-blazor-and-gui-from-core # Conflicts: # test/Memex.Portal.Shared.Test/AppleAuthenticationTest.cs
Test Results (shard 3) 9 files ± 0 9 suites ±0 5m 24s ⏱️ -20s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 54 and adds 267 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results (shard 0)593 tests - 613 589 ✅ - 617 14m 34s ⏱️ - 2m 21s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 832 and adds 219 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results (shard 5) 9 files - 1 9 suites - 1 7m 5s ⏱️ +17s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 77 and adds 379 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results (shard 4)2 064 tests - 108 2 061 ✅ +188 12m 32s ⏱️ +35s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 575 and adds 467 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results (shard 1)2 046 tests +216 1 853 ✅ + 23 8m 9s ⏱️ - 1m 19s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 405 and adds 621 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results (shard 2)2 831 tests - 605 2 728 ✅ - 708 9m 11s ⏱️ -34s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 781 and adds 176 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results 53 files - 2 53 suites - 2 56m 57s ⏱️ - 3m 43s Results for commit 2e83a93. ± Comparison against base commit f98a96b. This pull request removes 595 tests.♻️ This comment has been updated with latest results. |
The deletion took MemexConfiguration.cs with the GUI, but it is not GUI. It is 1644 lines referenced by 7 core test projects (AI, Content, ContentCollections, GitSync, Hosting.Monolith, Hosting.PostgreSql, PluginCatalog) and by core src — Documentation, AI/Connect, Graph configuration, Mesh.Contract FeatureFlags. Portal.Shared splits rather than moving: the ~29 GUI files (razor/css/png) leave, the platform half stays. This restores the one non-GUI file the deletion caught. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…d-gui-from-core # Conflicts: # memex/Memex.Portal.Monolith/appsettings.json # memex/Memex.Portal.Shared/Authentication/EaGraphAuth.cs # memex/aspire/Memex.Portal.Distributed/Program.cs # memex/aspire/Memex.Portal.Distributed/RequiredModulesHealthCheck.cs # memex/aspire/Memex.Portal.Distributed/appsettings.json # src/MeshWeaver.Blazor.Portal/Chat/ThreadChatView.razor.cs # src/MeshWeaver.Blazor.Portal/MeshWeaver.Blazor.Portal.csproj # src/MeshWeaver.Blazor/Components/DispatchView.razor # src/MeshWeaver.Blazor/Components/LayoutAreaView.razor # src/MeshWeaver.Blazor/wwwroot/standard-page-layout.css # test/Memex.Portal.Shared.Test/RequiredModulesHealthCheckTest.cs
…goes Portal.Shared splits rather than moving wholesale, so this file has to split too. It was the portal's composition root AND the mesh configuration entry point; only the second is what core uses. Moves out with the portal host (they had ZERO remaining callers in core — the callers were the deleted Monolith/Distributed Program.cs): ConfigureMemexServices 402 lines ASP.NET + Blazor service wiring StartMemexApplication<TApp> 429 lines Blazor HTTP pipeline (TApp : IComponent) ConfigureMemexPortal 60 lines per-circuit portal hub config AddMeshViews 21 lines razor page assemblies AiMenuItems + registration 35 lines click-sentinel resolved in the circuit Stays, untouched, because 7 core test projects and core src use it: ConfigureMemexMesh, plus ValidateContentStorageDurability, ReportUnloadedActivatedModules and the If<T> helper. 1644 -> 691 lines. Two things the portal GUI module must now contribute, both via MeshNodeProviderAttribute rather than core naming a Blazor type: • the portal address type (was .AddPortalType() inside ConfigureMemexMesh) • the AI top-bar "New thread" entry (was AiMenuItems) A grep for "Blazor" said ConfigureMemexMesh was already clean. It was not — PortalLayoutBase and AddPortalType carry no "Blazor" in the name, and only the compiler found them. Classify by compiler, not by name. Verified: solution build -c Release -warnaserror --no-incremental, 117 projects, 0 Warning(s) 0 Error(s), 138s — a real compile, not an up-to-date no-op. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deleting the GUI takes two of this repo's three surface-manifest hosts with it: Memex.Portal.Monolith and Memex.Portal.Distributed move to MeshWeaver.Plugins, leaving only MeshWeaver.PluginTester here. So CanonicalContentSurface_IsRecordedByEverySurfaceManifestHost failed on its HaveCountGreaterThan(1) — correctly. Its own reason says a run that finds one project "has verified nothing", and that is exactly what happened. This matters more than a red test. That assertion is the pin for #1814, where mw-plugin-test and memex-portal-ai resolved different framework identities, every bake published to an address nobody read, publication stayed GREEN, and pods recompiled everything at boot — two hours of course covers on a fallback card. Those two hosts are precisely the pair the GUI move puts in separate repos, so the split recreates that topology and no single-repo test can compare them again. Relaxing >1 to >0 was the wrong fix twice over: it reads as a pass for a broken discovery, and it silently drops the invariant instead of relocating it. Instead the check splits along the same line the code did — each repo asserts ITS hosts carry the complete canonical surface, and the two halves together are the old check: here every surface-manifest host in this tree is complete, and the tester is pinned BY NAME so a broken discovery cannot pass by matching some other csproj plugins the identical closure check against its portal host — owed by the PR that brings the portal in (#674), and required before #2293 can land Verified: 23/23 in MeshWeaver.Graph.Test, fresh trx. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AiResolutionSeamAuditTest asserts every AI-resolution entry point goes through AiSourceCatalog rather than reading nodes directly. One of its entry points — src/MeshWeaver.Blazor.Portal/Chat/ThreadChatView.razor.cs, pinned on ObserveResolvedModels( — moves to MeshWeaver.Plugins with the GUI, so the audit fails with "Entry point moved or vanished". That assertion is doing real work and must not simply be dropped: it is what stops direct node access creeping back into the chat view's model resolution. Verified the invariant still HOLDS at the destination before touching this — ObserveResolvedModels( is present in that repo's copy of the file — so what changes is where it is asserted, not whether it is true. Same treatment as the surface-manifest pin: this list stays authoritative for the entry points still in THIS repo, and the plugins-side audit owns the one that left. Neither half alone is the old check. 18/18 in MeshWeaver.AI.Test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ucture-out-of-blazor' into feat/delete-blazor-and-gui-from-core # Conflicts: # memex/Memex.Portal.Shared/Authentication/EaGraphAuth.cs
PortalOverlayLayeringTest asserts the layering contract between the portal header and the toast container, reading PortalLayoutBase.razor.css and standard-page-layout.css. Both stylesheets left with the GUI, and this PR had already removed the Content links that fed them to the test — so the test was failing here on a subject that no longer exists in this repo. Deleted only AFTER the destination was confirmed, not on the assumption that "the GUI moved": Plugins#693 is merged, the test runs there against both stylesheets (3/3, PortalCss/ populated in the output). Verified by presence in plugins main, then removed here. The reverse order — delete first, port later — is how the same split silently lost the dark-mode render-error fix earlier tonight: the code reached the destination while the check that verifies it stayed behind, and the destination looked complete because the file was there. Acme.Test builds -c Release -warnaserror, 0 warnings, 0 errors. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Memex.Portal.Shared still carried PackageReferences to Microsoft.FluentUI.AspNetCore.Components and .Components.Icons. Nothing uses them: the razor that did left with the GUI, and zero .cs files in the project reference the namespace. Proven rather than assumed — removing them and rebuilding -c Release -warnaserror --no-incremental gives 0 warnings, 0 errors, which a live dependency could not. This is the literal goal: no GUI packages on core. After it, core's tracked tree contains zero .razor, .razor.cs and .razor.css files, and zero tracked files under MeshWeaver.Blazor, MeshWeaver.Blazor.Portal and MeshWeaver.Hosting.Blazor (the directories left on disk are stale bin/obj from earlier builds). MeshWeaver.Hosting.AspNetCore was already clean: its only match for Microsoft.AspNetCore.Components is a COMMENT explaining that these projects were Blazor-free, which is what made lifting the portal infrastructure into it possible in the first place. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ErrorPageRouteTest reflects over typeof(ErrorRoutes).Assembly — core's
Memex.Portal.Shared — and asserts the exception-handler path is served by a
routable component. This PR deletes every routable component from that assembly
while ErrorRoutes stays, so after the deletion the test reflects over an assembly
with the constant and no components. It cannot pass, and worse, its sibling
assertion ("a path no component serves is absent from the route templates") would
pass VACUOUSLY over an empty set — the exact shape a reviewer flagged on the
plugins side.
🚨 This is the one relocation in this change where "verify the destination by
RUNNING it" could NOT be satisfied, and I am recording that rather than implying
otherwise. Memex.Portal.Gui does not compile against core main today: the move
COPIED SeoHead/Onboarding/MainLayout/PlatformUpdateIndicator without deleting the
originals, so both copies land in one compilation (RZ9985 "Multiple components
use the tag", CS0436) — measured on the plugins side, and all four are on this
PR's deletion list. THIS deletion is what unblocks that build.
So the order is forced and the window is real:
1. plugins #674 merges — GUI broken-but-inert, nothing compiles it
2. THIS PR lands — the duplicates die, Gui becomes buildable
3. the plugins-side job + relocated ErrorPageRouteTest land — first compile of
the moved hosts, and the first run of this guard at its destination
Between 2 and 3 the guard runs nowhere. That is inherent to the ordering, not an
oversight: it cannot run before the assembly it targets can build. It is carried
on the plugins branch feat/portal-hosts-tested-v2 and lands at step 3, where both
directions get proven — route deleted ⇒ red, and component set non-empty so it is
aimed at Memex.Portal.Gui rather than vacuously green.
Memex.Portal.Shared.Test builds -c Release -warnaserror, 0 warnings, 0 errors.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Heads-up: this PR silently drops MeshWeaver.AI from the imageNot a review of the Blazor removal itself — a specific consequence I found while working #2276, with the fix.
What happens then:
Net: a green rollout of a portal with no AI — chat, agents, models absent, no failing probe. The fix — one line, your choice of twoBoth are legitimate; which one depends on where you intend AI to come from after the split:
(1) is the smaller step and keeps this PR self-contained; (2) is where #2276 ends up eventually. You will not have to remember thisI have opened #2347, a guard that fails CI naming exactly this. Once it lands, your branch goes red with the message above rather than merging quietly — so please expect it, and treat it as the checklist rather than an obstacle. I verified it genuinely fails by simulating your deletion locally: red on both hosts, green again when restored. I have deliberately not pushed the one-line fix into your branch — where AI ships from is your call, and this PR is stacked on |
…ureSubset The lane inventory in MeshModulesPublish.targets is shared, but a host may narrow the CLOSURE half with MeshModulesClosureSubset — the targets remove every @(MeshModuleClosure) the subset does not name. Reading it globally credited a host with modules its own publish drops: a guard passing on evidence belonging to a different host, which is the one thing a guard must never do. The thin lane @(MeshModule) is not narrowed by the subset, so only the closure half is filtered. No host sets a subset today, so this closes the hole before it opens rather than fixing a live miss. Re-verified both directions: green on the tree, and still red on BOTH hosts when the Blazor.Portal reference is removed to simulate #2293. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # memex/Memex.Portal.Shared/MemexConfiguration.cs # src/MeshWeaver.Blazor.Portal/Layout/PortalLayoutBase.razor.cs # test/Memex.Portal.Shared.Test/AiMenuNewThreadTest.cs
Conflict was in the weight table only. Resolved by keeping THIS branch's re-measured weights and applying main's removals on top — never the other way round, which would have silently reverted merged work: * 2e83a93 removed MeshWeaver.MemexTemplate.Test (the template generator and its six projects left the repo); * #2293 removed MeshWeaver.Hosting.Blazor.Test (delete-blazor). Both rows dropped. Table now reconciles EXACTLY against the tree — 52 entries, 52 test projects, no stale row and none falling through to DEFAULT_WEIGHT. Sum 2792 -> 2758, so the split rule's worked example in the header is updated to 2758 ÷ 6 ≈ 460 s. Loads: 460 460 460 459 459 459.
#2293 deleted memex/aspire/Memex.Portal.Distributed from this repo. Three workflows still named it, so main-cd failed at its very first step for every commit on main: VERSION=$(dotnet msbuild memex/aspire/Memex.Portal.Distributed/... -getProperty:Version) ##[error]Process completed with exit code 1 promote is all-or-nothing, so NOTHING published. Production stayed up on the images it already had — stable, but frozen, including on the deletion itself. Repointed in main-cd.yml, edge-images.yml and release-images.yml: 1. Each checks out MeshWeaver.Plugins (path plugins-repo) and publishes the host from there, resolving the platform through -p:MeshWeaverRoot=${{ github.workspace }}. 2. `ref: ${{ vars.MW_PLUGINS_REF || 'main' }}` — default main, overridable by a repo variable, mirroring the plugins lane's own MW_PLATFORM_REF. This does NOT decouple "which plugins commit shipped with which core commit"; it makes that coupling steerable, so pinning to a known-good plugins commit during an incident is a variable change rather than editing a workflow under pressure. 3. VERSION now reads src/MeshWeaver.Mesh.Contract — a project that STAYS here. It must be computed in THIS repo: the same property resolves to 1.0.0 in the plugins tree against 3.0.0-rc8.ci.<n> here, and an install's self-updater compares that monotonically, so a plugins-derived version would roll every install BACKWARDS past VersionSelect's monotonic-build-number assumption. Verified any core project yields the identical value. It stays `-getProperty:` rather than a grep of Directory.Build.props, deliberately: a regex keeps returning a plausible, well-formed, WRONG number after the definition moves, and that number gets published. And it now REFUSES on empty instead of continuing — an empty version becomes `:` or `latest` downstream, which is the failure where a tag exists and points at the wrong thing. Root cause worth stating: this was a known-open item ("CD repoint for memex-portal-ai's build source") that was not sequenced before the deletion merged. The question "what does the world look like BETWEEN the two merges?" was asked of the COMPILE pairing and verified three ways; it was never asked of the delivery pipeline. Right question, one system too narrow. Verified: all three files parse; every `dotnet publish` of the host resolves to plugins-repo/src/... and carries MeshWeaverRoot; no workflow still reads Version from a moved project; no reference to the deleted path remains anywhere under .github/workflows.
#2293 deleted memex/aspire/Memex.Portal.Distributed from this repo. Three workflows still named it, so main-cd failed at its very first step for every commit on main: VERSION=$(dotnet msbuild memex/aspire/Memex.Portal.Distributed/... -getProperty:Version) ##[error]Process completed with exit code 1 promote is all-or-nothing, so NOTHING published. Production stayed up on the images it already had — stable, but frozen, including on the deletion itself. Repointed in main-cd.yml, edge-images.yml and release-images.yml: 1. Each checks out MeshWeaver.Plugins (path plugins-repo) and publishes the host from there, resolving the platform through -p:MeshWeaverRoot=${{ github.workspace }}. 2. `ref: ${{ vars.MW_PLUGINS_REF || 'main' }}` — default main, overridable by a repo variable, mirroring the plugins lane's own MW_PLATFORM_REF. This does NOT decouple "which plugins commit shipped with which core commit"; it makes that coupling steerable, so pinning to a known-good plugins commit during an incident is a variable change rather than editing a workflow under pressure. 3. VERSION now reads src/MeshWeaver.Mesh.Contract — a project that STAYS here. It must be computed in THIS repo: the same property resolves to 1.0.0 in the plugins tree against 3.0.0-rc8.ci.<n> here, and an install's self-updater compares that monotonically, so a plugins-derived version would roll every install BACKWARDS past VersionSelect's monotonic-build-number assumption. Verified any core project yields the identical value. It stays `-getProperty:` rather than a grep of Directory.Build.props, deliberately: a regex keeps returning a plausible, well-formed, WRONG number after the definition moves, and that number gets published. And it now REFUSES on empty instead of continuing — an empty version becomes `:` or `latest` downstream, which is the failure where a tag exists and points at the wrong thing. Root cause worth stating: this was a known-open item ("CD repoint for memex-portal-ai's build source") that was not sequenced before the deletion merged. The question "what does the world look like BETWEEN the two merges?" was asked of the COMPILE pairing and verified three ways; it was never asked of the delivery pipeline. Right question, one system too narrow. Verified: all three files parse; every `dotnet publish` of the host resolves to plugins-repo/src/... and carries MeshWeaverRoot; no workflow still reads Version from a moved project; no reference to the deleted path remains anywhere under .github/workflows.
#2367: a developer following the local-dev docs from a core checkout got a portal with no login UI and no control views. The docs said `dotnet run --project memex/Memex.Portal.Monolith` and `memex/aspire/Memex.AppHost` -- paths #2293 deleted, together with the login pages, when the GUI extraction moved the hosts to MeshWeaver.Plugins. Eight files carried those commands: AGENTS.md, Readme.md, Deployment.md, LocalDevWorkflow.md, MacLocalStack.md and three more. Every occurrence now points at `../MeshWeaver.Plugins/src/Memex.Portal.Monolith` / `.../Memex.AppHost`, which runs UNCHANGED from the documented working directory under the standard sibling layout -- plugins' src/Directory.Build.props defaults MeshWeaverRoot to `../MeshWeaver`. A note at the top of LocalDevWorkflow.md says where the hosts went, why a core checkout alone cannot run a portal, and how to override the root if the layout differs. The second half of #2367 (DefaultViews/GraphViews reaching a deployment only as registry bundles) is #2169 Phase B2's decision and is not a docs matter; it is left open there. DocumentationLinkIntegrityTest passes.
The csproj said "Blazor.Portal REMAINS a compiled reference for now — it is SHELL infrastructure (PortalLayoutBase, auth, viewport), tracked for extraction as #2169 Phase B3." #2293 completed that extraction, so the sentence became false at merge. Caught in review ON #2293 and merged knowingly rather than fixed there: main was red on `Landed modules compile against this PR` (the additive half of the move had landed while the deletion half stayed open), three unrelated PRs were blocked behind it, and a comment-only push costs a full CI cycle with main red throughout. The trade was one wrong sentence against other people's blocked work; this is the other half of it, landing immediately as promised on the thread. Worth the commit rather than a silent resolve, because this is the same failure the same PR corrected twice in ContinuousDeliveryContract.md: prose describing intent as if it were state, sitting next to the code and outliving it. That file predicted "moving the generator does not help" and asserted a compile gate lived somewhere it did not — one of which cost me an afternoon and a wrong escalation to another session. A comment nobody re-reads after the change it describes is how that happens.
#2293 deleted memex/aspire/Memex.Portal.Distributed from this repo. Three workflows still named it, so main-cd failed at its very first step for every commit on main: VERSION=$(dotnet msbuild memex/aspire/Memex.Portal.Distributed/... -getProperty:Version) ##[error]Process completed with exit code 1 promote is all-or-nothing, so NOTHING published. Production stayed up on the images it already had — stable, but frozen, including on the deletion itself. Repointed in main-cd.yml, edge-images.yml and release-images.yml: 1. Each checks out MeshWeaver.Plugins (path plugins-repo) and publishes the host from there, resolving the platform through -p:MeshWeaverRoot=${{ github.workspace }}. 2. `ref: ${{ vars.MW_PLUGINS_REF || 'main' }}` — default main, overridable by a repo variable, mirroring the plugins lane's own MW_PLATFORM_REF. This does NOT decouple "which plugins commit shipped with which core commit"; it makes that coupling steerable, so pinning to a known-good plugins commit during an incident is a variable change rather than editing a workflow under pressure. 3. VERSION now reads src/MeshWeaver.Mesh.Contract — a project that STAYS here. It must be computed in THIS repo: the same property resolves to 1.0.0 in the plugins tree against 3.0.0-rc8.ci.<n> here, and an install's self-updater compares that monotonically, so a plugins-derived version would roll every install BACKWARDS past VersionSelect's monotonic-build-number assumption. Verified any core project yields the identical value. It stays `-getProperty:` rather than a grep of Directory.Build.props, deliberately: a regex keeps returning a plausible, well-formed, WRONG number after the definition moves, and that number gets published. And it now REFUSES on empty instead of continuing — an empty version becomes `:` or `latest` downstream, which is the failure where a tag exists and points at the wrong thing. Root cause worth stating: this was a known-open item ("CD repoint for memex-portal-ai's build source") that was not sequenced before the deletion merged. The question "what does the world look like BETWEEN the two merges?" was asked of the COMPILE pairing and verified three ways; it was never asked of the delivery pipeline. Right question, one system too narrow. Verified: all three files parse; every `dotnet publish` of the host resolves to plugins-repo/src/... and carries MeshWeaverRoot; no workflow still reads Version from a moved project; no reference to the deleted path remains anywhere under .github/workflows.
…link that leaves the repo Review on #2380 caught what the first pass missed: my rewrite matched the run/watch forms of the portal-host path and not the build/publish ones, so LocalDevWorkflow.md's step 3 rebuild, the AKS publish in DeploymentAKS.md and LocalColimaMac.md, and a DebuggingMessageFlow.md table row still named memex/aspire/Memex.Portal.Distributed -- a path #2293 deleted. Every occurrence now points at the sibling MeshWeaver.Plugins checkout, and step 3 says so in prose so a reader in a core checkout knows why the command leaves it. samples/Graph/README.md linked to ../../../MeshWeaver.Plugins/... -- a relative link that leaves the repository renders broken on GitHub. Now an absolute URL. Prose that cites old src/MeshWeaver.Blazor.Portal/... file paths as the location of PAST fixes is left as history; only runnable commands were rewritten.
… deliberate Review: "gone from this repo entirely" overstated it. The MeshWeaver.Blazor.Portal PROJECT left in #2293; the assembly NAME remains in InternalsVisibleTo on purpose, because that assembly now builds in MeshWeaver.Plugins and needs the same internals it always had. A comment that says "gone entirely" invites the next reader to delete a grant that is load-bearing.
The Blazor.Portal comment described a state #2293 ended
#2367: a developer following the local-dev docs from a core checkout got a portal with no login UI and no control views. The docs said `dotnet run --project memex/Memex.Portal.Monolith` and `memex/aspire/Memex.AppHost` -- paths #2293 deleted, together with the login pages, when the GUI extraction moved the hosts to MeshWeaver.Plugins. Eight files carried those commands: AGENTS.md, Readme.md, Deployment.md, LocalDevWorkflow.md, MacLocalStack.md and three more. Every occurrence now points at `../MeshWeaver.Plugins/src/Memex.Portal.Monolith` / `.../Memex.AppHost`, which runs UNCHANGED from the documented working directory under the standard sibling layout -- plugins' src/Directory.Build.props defaults MeshWeaverRoot to `../MeshWeaver`. A note at the top of LocalDevWorkflow.md says where the hosts went, why a core checkout alone cannot run a portal, and how to override the root if the layout differs. The second half of #2367 (DefaultViews/GraphViews reaching a deployment only as registry bundles) is #2169 Phase B2's decision and is not a docs matter; it is left open there. DocumentationLinkIntegrityTest passes.
…link that leaves the repo Review on #2380 caught what the first pass missed: my rewrite matched the run/watch forms of the portal-host path and not the build/publish ones, so LocalDevWorkflow.md's step 3 rebuild, the AKS publish in DeploymentAKS.md and LocalColimaMac.md, and a DebuggingMessageFlow.md table row still named memex/aspire/Memex.Portal.Distributed -- a path #2293 deleted. Every occurrence now points at the sibling MeshWeaver.Plugins checkout, and step 3 says so in prose so a reader in a core checkout knows why the command leaves it. samples/Graph/README.md linked to ../../../MeshWeaver.Plugins/... -- a relative link that leaves the repository renders broken on GitHub. Now an absolute URL. Prose that cites old src/MeshWeaver.Blazor.Portal/... file paths as the location of PAST fixes is left as history; only runnable commands were rewritten.
Stacked on #2285 (the infrastructure lift), which has to land first — this deletes the projects
that lift empties of platform code.
Core ends up with no GUI at all. 389 files, 54,428 lines deleted.
🚨 The test sweep was wrong three times before it was right
Selecting test files by "imports a Blazor namespace" is a proxy for "is a view test", and the two
are different sets. That predicate selected 27 files. The compiler says 16 actually need a
view type. Among the 11 it would have exiled for an unused
using:Eight
MeshWeaver.Hosting.PostgreSql.Testfiles were the same shape. Name-matching fared nobetter — it misses
MessageBubbleState,CompletionItemandMarkdownCellEditing, view typesthat don't end in
VieworPage.What works is neither: strip the import and let the compiler classify. Every file that stays lost
one stale
usingand nothing else — which is why the diff showsPartitionAccessTest.cs | 1 -rather than a deletion.
Two checks that earned their place
It took three attempts to measure correctly (wrong checkout, then
obj/copies) — and each wrongversion showed a suite gaining tests from a deletion, which is the only reason I caught them.
The ratchet that was one predicate away
NodeTypeDeclarationSelfTypingTeststays in core and still runs — verifiedbuild exit=0, then2/2 passed (an earlier run reported "Passed" while the build had exited 1, i.e. against a stale DLL;
that result was discarded). It guards a defect measured at 3.2 failures/second on every serving
pod, and its absence is silent by construction.
Two stragglers no source-level check could see
MSBuild
<Content Include>items inAcme.Testcopying CSS out of the deleted projects. Notusings, notProjectReferences, not C# — only a full-solution build surfaces them.Verification
Full solution:
-c Release -warnaserror, 0 warnings, 0 errors. The final pass was incremental,so CI's clean checkout remains the real test of a from-scratch build.
No What's New entry: no user-visible change — the portal builds from a different repo and nothing
about it changes for a viewer.