Skip to content

refactor(test): split the AI-menu pin so the portal suite stops referencing MeshWeaver.AI - #2340

Merged
rbuergi merged 2 commits into
mainfrom
refactor/ai-menu-test-split
Aug 26, 2026
Merged

rbuergi merged 2 commits into
mainfrom
refactor/ai-menu-test-split

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Closes the last unparked test project holding a compile-time ProjectReference to src/MeshWeaver.AI — the exact edge #2276 exists to remove.

Why it was there

Memex.Portal.Shared.Test referenced the module for one file. AiMenuNewThreadTest asserted both halves of the AI (✨) menu in the same test methods:

  • the portal's ONE compiled imperative entry (MemexConfiguration.AiMenuItems — the "New thread" click-action sentinel), and
  • MeshWeaver.AI's seeded UiContribution nodes (Threads / Models / Tiers / Providers / Agents / Skills).

Three of its six methods spanned the boundary, which is what forced the reference — and an InternalsVisibleTo("Memex.Portal.Shared.Test") grant on the module so the suite could read the internal Seeds list.

The seam already existed in the data

The portal's imperative entry is Order 0; every AI seed is Order > 0. The menu aggregator dedupes on (Order, Label, Area) via ImmutableSortedSet, so entries drawn from disjoint Order ranges can never collide. That makes the split lossless: each side asserts its own half plus its half of the ordering invariant, and the whole contract still follows — with neither test referencing the other's assembly.

side pins
Memex.Portal.Shared.Test the single compiled entry; Order 0; the language-neutral ➕ glyph; the absent Href (it stays imperative); the /User/{me}/Chat destination
MeshWeaver.AI.Test (new AiMenuContributionsTest) every seed is Order > 0; the AI context; Href + LabelKey present; unique keys

Coverage goes up, not down — six methods become eight, because each cross-boundary assertion splits into a per-side one.

Also dropped, with the coupling

  • the ProjectReference in Memex.Portal.Shared.Test.csproj
  • InternalsVisibleTo("Memex.Portal.Shared.Test") on MeshWeaver.AI — it existed solely for this suite

Verification

  • dotnet build -c Release -p:CIRun=true -warnaserror on both projects: 0 Warning(s), 0 Error(s)
  • both halves run green: 3 (AI) + 5 (portal)

No What's New entry — test-only refactor, no user-visible effect.

Refs #2276

🤖 Generated with Claude Code

…encing the module

Memex.Portal.Shared.Test was the last unparked test project holding a compile-time
ProjectReference to src/MeshWeaver.AI — the exact edge #2276 exists to remove. It was
there for one file: AiMenuNewThreadTest asserted BOTH the portal's compiled imperative
entry AND MeshWeaver.AI's seeded UiContribution nodes in the same test methods.

Split along the seam that already existed in the data: the portal's "New thread" entry is
Order 0 and every AI seed is Order > 0. Disjoint Order ranges mean the aggregator (which
dedupes on (Order, Label, Area) via ImmutableSortedSet) can never collide entries drawn
from the two lists, so asserting each half separately proves the same whole contract with
neither side referencing the other's assembly.

- Memex.Portal.Shared.Test keeps the portal's half: the single compiled entry, its Order 0,
  the language-neutral glyph, the absent Href, and the /User/{me}/Chat destination.
- MeshWeaver.AI.Test gains AiMenuContributionsTest for the seeds' half: Order > 0, the AI
  context, Href + LabelKey present, and unique keys.

Coverage goes UP, not down — the six methods become eight, because the two cross-boundary
assertions each split into a per-side one.

Drops with the coupling:
- the ProjectReference from Memex.Portal.Shared.Test.csproj,
- the InternalsVisibleTo("Memex.Portal.Shared.Test") grant on MeshWeaver.AI, which existed
  solely so that suite could read the internal Seeds list.

Verified: both projects build -c Release -warnaserror with 0 Warning(s)/0 Error(s), and
both halves run green (3 + 5 tests).

No What's New entry: test-only refactor, no user-visible effect.

Refs #2276

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 26, 2026 08:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors AI menu pinning tests to remove Memex.Portal.Shared.Test’s compile-time ProjectReference to src/MeshWeaver.AI, by splitting assertions between portal-side (compiled “New thread” sentinel) and AI-side (seeded UiContribution navigation entries).

Changes:

  • Added MeshWeaver.AI.Test.AiMenuContributionsTest to pin the seeded navigation contributions (Order > 0, Href/LabelKey present, uniqueness).
  • Removed MeshWeaver.AI project reference from Memex.Portal.Shared.Test and narrowed AiMenuNewThreadTest to portal-only invariants.
  • Dropped InternalsVisibleTo("Memex.Portal.Shared.Test") from MeshWeaver.AI.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/MeshWeaver.AI.Test/AiMenuContributionsTest.cs New AI-side test suite asserting the seeded AI menu navigation contributions.
test/Memex.Portal.Shared.Test/Memex.Portal.Shared.Test.csproj Removes the test project’s compile-time dependency on MeshWeaver.AI.
test/Memex.Portal.Shared.Test/AiMenuNewThreadTest.cs Updates portal-side tests to assert only the compiled “New thread” sentinel contract.
src/MeshWeaver.AI/InternalsVisibleTo.cs Removes portal test friend access to MeshWeaver.AI internals.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/MeshWeaver.AI/InternalsVisibleTo.cs Resolved
@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

    9 files  ± 0      9 suites  ±0   5m 43s ⏱️ -18s
1 810 tests +33  1 805 ✅ +34  5 💤  - 1  0 ❌ ±0 
2 359 runs  +33  2 354 ✅ +34  5 💤  - 1  0 ❌ ±0 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

This pull request removes 581 and adds 614 tests. Note that renamed tests count towards both.
MeshWeaver.AI.Test.AiSettingsTest ‑ BuildDefaults_EnabledHarnesses_AreTheRegisteredHarnessIds_OrderedByDefinitionOrder
MeshWeaver.AI.Test.AiSettingsTest ‑ Effective_EmptyFieldsFallBackToDefaults_PerField
MeshWeaver.AI.Test.AiSettingsTest ‑ Effective_NullNode_ReturnsDefaults
MeshWeaver.AI.Test.AiSettingsTest ‑ ResolveQueries_SubstitutesPresentTokens_AndDropsTemplatesWithEmptyTokens
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_AmbiguousMatch_ThrowsAmbiguousAnchor_WithOccurrenceCount
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_Code_ReplacesCode_PreservingConfiguration
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_Markdown_ReplacesAndRerenders_PreservingMetadata
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_NonTextContent_ThrowsInvalidOperation
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_RawString_Replaces
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_ReplaceAll_ReplacesEveryOccurrence
…
MeshWeaver.AI.Test.AiResolutionSeamAuditTest ‑ AllowList_NamesOnlyFilesThatExist_WithAReason
MeshWeaver.AI.Test.AiResolutionSeamAuditTest ‑ EveryResolutionEntryPoint_GoesThroughTheSeam
MeshWeaver.AI.Test.AiResolutionSeamAuditTest ‑ NoResolutionLiteral_OutsideTheAllowList
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Defaults_AreNamedAndDescribed_ForEveryKind
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Defaults_ReproduceTheHistoricalQueries_Exactly
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Expand_DropsWhenAPlaceholderHasNoValue_NeverHalfExpanded
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Expand_RefusesUnanchoredAndUnknownPlaceholders
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Expand_SubstitutesNewAndLegacyPlaceholders
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ MergePackageSources_AppendNamedRows_WhenTheUserMaintainsNamedSources
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ PlatformModelPath_IsLabeledMeshWeaverOpenRouter_WithTheDisclosureAndTermsLink
…
This pull request removes 2 skipped tests and adds 1 skipped test. Note that renamed tests count towards both.
MeshWeaver.AI.Test.TypedErrorPropagationTest ‑ UnregisteredDiscriminator_SurfacesDeserializationException_OnSubscribe
MeshWeaver.AI.Test.UseWithoutSeeResolverTest ‑ Read_GrantsUse_NoRead_FailsClosed
MeshWeaver.AI.Test.ConnectStrategyTest ‑ RealClaudeSetupToken_Gated_BehindEnvFlag

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

   10 files  ±0     10 suites  ±0   5m 30s ⏱️ - 1m 23s
1 310 tests ±0  1 309 ✅ ±0  1 💤 ±0  0 ❌ ±0 
1 311 runs  ±0  1 310 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

1 206 tests  ±0   1 206 ✅ +1   14m 49s ⏱️ + 2m 20s
    9 suites ±0       0 💤 ±0 
    9 files   ±0       0 ❌  - 1 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 819 tests  ±0   1 819 ✅ ±0   9m 17s ⏱️ -4s
   10 suites ±0       0 💤 ±0 
   10 files   ±0       0 ❌ ±0 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

3 435 tests   - 1   3 435 ✅  - 1   9m 31s ⏱️ ±0s
    8 suites ±0       0 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

This pull request removes 2 and adds 1 tests. Note that renamed tests count towards both.
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ AiMenu_Entries_Are_Uniquely_Keyed
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ Every_Other_AiMenu_Entry_Navigates_By_Href
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ Only_The_Imperative_Entry_Stays_Compiled

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

2 172 tests   - 30   1 873 ✅  - 31   12m 32s ⏱️ -17s
    9 suites ± 0     299 💤 + 1 
    9 files   ± 0       0 ❌ ± 0 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

This pull request removes 614 and adds 584 tests. Note that renamed tests count towards both.
MeshWeaver.AI.Test.AiResolutionSeamAuditTest ‑ AllowList_NamesOnlyFilesThatExist_WithAReason
MeshWeaver.AI.Test.AiResolutionSeamAuditTest ‑ EveryResolutionEntryPoint_GoesThroughTheSeam
MeshWeaver.AI.Test.AiResolutionSeamAuditTest ‑ NoResolutionLiteral_OutsideTheAllowList
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Defaults_AreNamedAndDescribed_ForEveryKind
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Defaults_ReproduceTheHistoricalQueries_Exactly
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Expand_DropsWhenAPlaceholderHasNoValue_NeverHalfExpanded
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Expand_RefusesUnanchoredAndUnknownPlaceholders
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ Expand_SubstitutesNewAndLegacyPlaceholders
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ MergePackageSources_AppendNamedRows_WhenTheUserMaintainsNamedSources
MeshWeaver.AI.Test.AiSourceCatalogTest ‑ PlatformModelPath_IsLabeledMeshWeaverOpenRouter_WithTheDisclosureAndTermsLink
…
MeshWeaver.AI.Test.AiMenuContributionsTest ‑ Every_Seed_Navigates_By_Href_And_Localizes_Its_Label
MeshWeaver.AI.Test.AiMenuContributionsTest ‑ Every_Seed_Sorts_After_The_Imperative_Entry
MeshWeaver.AI.Test.AiMenuContributionsTest ‑ Seeds_Are_Uniquely_Keyed
MeshWeaver.AI.Test.AiSettingsTest ‑ BuildDefaults_EnabledHarnesses_AreTheRegisteredHarnessIds_OrderedByDefinitionOrder
MeshWeaver.AI.Test.AiSettingsTest ‑ Effective_EmptyFieldsFallBackToDefaults_PerField
MeshWeaver.AI.Test.AiSettingsTest ‑ Effective_NullNode_ReturnsDefaults
MeshWeaver.AI.Test.AiSettingsTest ‑ ResolveQueries_SubstitutesPresentTokens_AndDropsTemplatesWithEmptyTokens
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_AmbiguousMatch_ThrowsAmbiguousAnchor_WithOccurrenceCount
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_Code_ReplacesCode_PreservingConfiguration
MeshWeaver.AI.Test.AnchoredEditContentTest ‑ ApplyAnchoredEdit_Markdown_ReplacesAndRerenders_PreservingMetadata
…
This pull request removes 1 skipped test and adds 2 skipped tests. Note that renamed tests count towards both.
MeshWeaver.AI.Test.ConnectStrategyTest ‑ RealClaudeSetupToken_Gated_BehindEnvFlag
MeshWeaver.AI.Test.TypedErrorPropagationTest ‑ UnregisteredDiscriminator_SurfacesDeserializationException_OnSubscribe
MeshWeaver.AI.Test.UseWithoutSeeResolverTest ‑ Read_GrantsUse_NoRead_FailsClosed

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

    55 files  ±0      55 suites  ±0   57m 25s ⏱️ +17s
11 752 tests +2  11 447 ✅ +3  305 💤 ±0  0 ❌  - 1 
12 302 runs  +2  11 997 ✅ +3  305 💤 ±0  0 ❌  - 1 

Results for commit ed88b95. ± Comparison against base commit e5ce962.

This pull request removes 2 and adds 4 tests. Note that renamed tests count towards both.
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ AiMenu_Entries_Are_Uniquely_Keyed
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ Every_Other_AiMenu_Entry_Navigates_By_Href
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ Only_The_Imperative_Entry_Stays_Compiled
MeshWeaver.AI.Test.AiMenuContributionsTest ‑ Every_Seed_Navigates_By_Href_And_Localizes_Its_Label
MeshWeaver.AI.Test.AiMenuContributionsTest ‑ Every_Seed_Sorts_After_The_Imperative_Entry
MeshWeaver.AI.Test.AiMenuContributionsTest ‑ Seeds_Are_Uniquely_Keyed

♻️ This comment has been updated with latest results.

@rbuergi

rbuergi commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Re-running on a current base — the red is not reachable from this diff

MeshWeaver Build and Test failed on:

MeshWeaver.Hosting.Orleans.Test.OrleansMeshTests.HubWorksAfterDisposal(id: "HubFactory")
[CI] MeshWeaver.Hosting.Orleans.Test exit=1 TESTFAIL

Can this diff reach it?

The PR touches four files: the AI-menu test in Memex.Portal.Shared.Test, that project's csproj, a new test in MeshWeaver.AI.Test, and the removal of one InternalsVisibleTo grant — Memex.Portal.Shared.Test. The grant MeshWeaver.Hosting.Orleans.Test holds is untouched, and a grant naming assembly A cannot affect assembly B.

Nothing here is on the path of an Orleans hub-disposal test.

Why merge main rather than just assert that

The branch was 21 commits behind, and among what it lacked is #2335 — "Close the #2013 blocking-bridge residue that recurred today". A test named HubWorksAfterDisposal failing on a tree that predates a blocking-bridge/disposal fix is precisely the stale-branch case: the branch re-samples a flake main may already have fixed, and it reads as a defect in the change.

So: merged origin/main (clean, no conflicts) and pushed. Revert-check with three dots confirms the branch still contributes only its own four files —

src/MeshWeaver.AI/InternalsVisibleTo.cs                    |  5 --
test/Memex.Portal.Shared.Test/AiMenuNewThreadTest.cs       | 57 +++-----
test/Memex.Portal.Shared.Test/Memex.Portal.Shared.Test.csproj | 4 --
test/MeshWeaver.AI.Test/AiMenuContributionsTest.cs         | 64 ++++++++++

— so the merge has not silently reverted anyone's work.

🚨 To be explicit about what this is not: I am not re-running to see whether it passes this time. The base changed, and it changed in a way that plausibly bears on the failing test. If it reds again on the new base, that is a different and much more interesting signal, and I will treat it as one.

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.

2 participants