Skip to content

PathResolution.Test drops MeshWeaver.AI — and the static-collections guard follows it - #2368

Merged
rbuergi merged 1 commit into
mainfrom
refactor/ai-test-batch-2
Aug 26, 2026
Merged

rbuergi merged 1 commit into
mainfrom
refactor/ai-test-batch-2

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

MeshWeaver.PathResolution.Test loses its MeshWeaver.AI reference — #2276.

The reference was never a code dependency

NoStaticCollectionsTest enumerates MeshWeaver.*.dll from AppContext.BaseDirectory at runtime. It only ever covers the assemblies in the running test's bin — and the ProjectReference existed purely to place AI.dll where the guard would find it.

🚨 Dropping it naively leaves the guard green, having stopped looking at AI. Coverage lost, no signal. So the guard follows its subject: one linked <Compile> into MeshWeaver.AI.Test — no duplicated logic, and it travels with that project when the engine leaves.

Linking it proved itself immediately, twice

It ran and failed, which is the only way to know the link isn't decorative:

  1. I had removed the four MeshWeaver.AI.* allow entries, assuming AI would no longer be scanned anywhere. Wrong — restored; they are legitimate CONST allowances needed wherever AI.dll is scanned.
  2. AI.Test's larger dependency closure brought six assemblies into scope for the first time.

A no-op link would have sat silently green.

The six, verified rather than assumed

symbol shape
NonfileRouteConstraint.ExcludedPrefixes static readonly string[], reads only
PostgreSqlCrossSchemaQueryProvider.ExcludedSchemas static readonly HashSet, .Contains only
PostgreSqlSqlGenerator.AllowedSqlFunctions / NonTextColumns / PropertyMap ditto
PostgreSqlStorageAdapter.TransientPostgresSqlStates ditto

Each is a declaration-with-initializer whose only later uses are reads — the immutable read-only lookups NoStaticState.md permits. The entries record that they were surfaced by widened coverage, not by new code, because six new allow lines otherwise read as weakening a guard.

The moved tests

The two thread cases go to AI.Test as ThreadAddressResolutionTest. Their fixture is not incidental — they build AI.Thread content under a _Thread satellite path and the shape being resolved is that. (I first wired them with AddThreadType(); isolating the failure showed ThreadMessage unregistered, so they use AddAI() as the original fixture did.)

Trade-off worth naming

This widens the guard repo-wide, so this PR classifies six statics unrelated to AI. The narrower option was to record a coverage gap, as #2293 did for the portal hosts' module declarations. Coverage won: leaving AI unguarded is the exact failure this exercise exists to avoid, and the six were trivially verifiable.

Verification

  • both projects -c Release -p:CIRun=true -warnaserror → 0 Error(s)
  • PathResolution.Test: 136/136
  • AI.Test: 4/4, including the linked guard

Refs #2276

🤖 Generated with Claude Code

…guard included

Two thread cases move to MeshWeaver.AI.Test as ThreadAddressResolutionTest. Their fixture is
NOT incidental: they build AI.Thread content under a _Thread satellite path and the shape
being resolved IS that. Substituting a non-AI node type would have changed the scenario, so
they travel with the engine. The resolution mechanism itself is core and its coverage stays
in place — 136/136 there without the reference.

🚨 The ProjectReference was never a code dependency. NoStaticCollectionsTest enumerates
MeshWeaver.*.dll from AppContext.BaseDirectory at RUNTIME, so it only ever covers the
assemblies in the running test's bin — and the reference existed purely to put AI.dll where
the guard would find it. Dropping it naively leaves the guard GREEN having stopped looking
at AI, which is coverage lost with no signal.

So the guard follows its subject: one linked <Compile> into MeshWeaver.AI.Test, no
duplicated logic, and it travels with that project when the engine leaves.

Linking it proved itself immediately, twice. It ran and FAILED — first because the four
MeshWeaver.AI.* allow entries had been removed on the wrong assumption that AI would no
longer be scanned anywhere (restored: they are legitimate CONST allowances needed wherever
AI.dll is scanned), then because AI.Test's larger dependency closure brought six assemblies
into scope for the FIRST time. A no-op link would have sat silently green.

Those six are allow-listed, each verified rather than assumed: every one is a
declaration-with-initializer whose only later uses are reads (.Contains, lookups) — the
immutable read-only lookups NoStaticState.md permits. They were surfaced by WIDENED
COVERAGE, not by new code, and the entries say so.

Note this widens the guard repo-wide, so this PR classifies six statics unrelated to AI. The
narrower option was to record a coverage gap the way #2293 did for the portal hosts' module
declarations; coverage won because leaving AI unguarded is the failure this whole exercise
exists to avoid, and the six were trivially verifiable.

Verified: both projects build -c Release -warnaserror at 0 Error(s); PathResolution.Test
136/136; AI.Test 4/4 including the linked guard.

No What's New entry: test-only refactor.

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 12:28

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

This PR removes an indirect MeshWeaver.AI dependency from MeshWeaver.PathResolution.Test and preserves the “no static collections” architecture guard’s effective coverage by linking that guard into MeshWeaver.AI.Test instead.

Changes:

  • Drop MeshWeaver.AI as a ProjectReference from MeshWeaver.PathResolution.Test and remove the remaining AddAI()-dependent thread path-resolution cases from that suite.
  • Add a new ThreadAddressResolutionTest under MeshWeaver.AI.Test to keep the thread-specific path-resolution scenarios covered with an AI-aware fixture.
  • Extend the static-collections guard allowlist with newly surfaced (read-only) static lookup fields discovered once MeshWeaver.AI.Test’s larger dependency closure is scanned.

Reviewed changes

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

Show a summary per file
File Description
test/MeshWeaver.PathResolution.Test/NoStaticCollectionsTest.cs Updates the allowlist for the static-collections guard to account for newly scanned assemblies/statics.
test/MeshWeaver.PathResolution.Test/MeshWeaver.PathResolution.Test.csproj Removes the MeshWeaver.AI ProjectReference.
test/MeshWeaver.PathResolution.Test/AddressResolutionTest.cs Removes AddAI() and moves the thread-specific cases out of this test suite.
test/MeshWeaver.AI.Test/ThreadAddressResolutionTest.cs Adds AI-fixture-backed thread path-resolution tests moved from PathResolution.Test.
test/MeshWeaver.AI.Test/MeshWeaver.AI.Test.csproj Links NoStaticCollectionsTest.cs into MeshWeaver.AI.Test so the guard continues to scan AI’s bin closure.

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

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

    9 files  ± 0      9 suites  ±0   5m 1s ⏱️ - 1m 16s
2 056 tests +61  2 055 ✅ +63  1 💤  - 2  0 ❌ ±0 
2 608 runs  +61  2 607 ✅ +63  1 💤  - 2  0 ❌ ±0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

This pull request removes 54 and adds 115 tests. Note that renamed tests count towards both.
MeshWeaver.AI.Test.ThreadAgentIntegrationTest ‑ FullFlow_CreateThread_SendMessage_NonStreamingResponse
MeshWeaver.AI.Test.ThreadAgentIntegrationTest ‑ FullFlow_CreateThread_SendMessage_StreamResponse_SaveReply
MeshWeaver.AI.Test.ThreadAgentIntegrationTest ‑ SwitchThread_IsolatesConversationState
MeshWeaver.AI.Test.ThreadComposerRoutingTest ‑ PerNodeComposer_PathAndNodeType_ResolveToTheSameTable
MeshWeaver.AI.Test.ThreadComposerRoutingTest ‑ PerUserComposer_PathAndNodeType_ResolveToTheSameTable
MeshWeaver.AI.Test.ThreadHubSelfReadTest ‑ Activating_thread_node_hub_does_not_self_post_a_contextless_GetDataRequest
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"   \")
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"///\")
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"/\")
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"@/\")
…
MeshWeaver.AI.Test.ThreadAddressResolutionTest ‑ ResolvePath_ThreadMessageNode_ResolvesToFullMessagePath
MeshWeaver.AI.Test.ThreadAddressResolutionTest ‑ ResolvePath_ThreadNode_ResolvesCorrectlyWithChildren
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ ResolveHarness_AcceptsPathAndBareId
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SelectionId_IdOf_NormalizesPathsAndPassesIdsThrough
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ StartThread_WithComposer_CreatesUnderContext_AndEmbedsEmptiedComposer
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SubmitComposer_DrainsDraft_CarriesSelection_AndEmptiesComposer
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SubmitComposer_ExplicitText_OverridesDraft
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SubmitComposer_NothingToSubmit_IsANoOp
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ ThreadComposer_Equality_ComparesAttachmentsBySequence
MeshWeaver.AI.Test.ThreadHubBuildsNoHubTest ‑ ActivatingAThreadHub_BuildsNoHubOfItsOwn
…

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

591 tests   - 2   587 ✅  - 2   18m 5s ⏱️ + 3m 32s
  7 suites ±0     4 💤 ±0 
  7 files   ±0     0 ❌ ±0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

This pull request removes 2 tests.
MeshWeaver.PathResolution.Test.AddressResolutionTest ‑ ResolvePath_ThreadMessageNode_ResolvesToFullMessagePath
MeshWeaver.PathResolution.Test.AddressResolutionTest ‑ ResolvePath_ThreadNode_ResolvesCorrectlyWithChildren

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    9 files  ±0      9 suites  ±0   7m 16s ⏱️ +9s
1 611 tests ±0  1 610 ✅ ±0  1 💤 ±0  0 ❌ ±0 
1 612 runs  ±0  1 611 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

2 048 tests  ±0   1 855 ✅ ±0   8m 22s ⏱️ -1s
    9 suites ±0     193 💤 ±0 
    9 files   ±0       0 ❌ ±0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

2 832 tests  ±0   2 729 ✅ ±0   9m 17s ⏱️ +10s
    9 suites ±0     103 💤 ±0 
    9 files   ±0       0 ❌ ±0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

2 039 tests   - 57   2 036 ✅  - 59   14m 14s ⏱️ + 1m 42s
   10 suites ± 0       3 💤 + 2 
   10 files   ± 0       0 ❌ ± 0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

This pull request removes 111 and adds 54 tests. Note that renamed tests count towards both.
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ ResolveHarness_AcceptsPathAndBareId
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SelectionId_IdOf_NormalizesPathsAndPassesIdsThrough
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ StartThread_WithComposer_CreatesUnderContext_AndEmbedsEmptiedComposer
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SubmitComposer_DrainsDraft_CarriesSelection_AndEmptiesComposer
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SubmitComposer_ExplicitText_OverridesDraft
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ SubmitComposer_NothingToSubmit_IsANoOp
MeshWeaver.AI.Test.ThreadComposerFlowTest ‑ ThreadComposer_Equality_ComparesAttachmentsBySequence
MeshWeaver.AI.Test.ThreadHubBuildsNoHubTest ‑ ActivatingAThreadHub_BuildsNoHubOfItsOwn
MeshWeaver.AI.Test.ThreadIconGeneratorTest ‑ BuildThreadNode_StampsDeterministicIdenticonOnIcon
MeshWeaver.AI.Test.ThreadIconGeneratorTest ‑ BuildThreadWithMessages_StampsDeterministicIdenticonOnIcon
…
MeshWeaver.AI.Test.ThreadAgentIntegrationTest ‑ FullFlow_CreateThread_SendMessage_NonStreamingResponse
MeshWeaver.AI.Test.ThreadAgentIntegrationTest ‑ FullFlow_CreateThread_SendMessage_StreamResponse_SaveReply
MeshWeaver.AI.Test.ThreadAgentIntegrationTest ‑ SwitchThread_IsolatesConversationState
MeshWeaver.AI.Test.ThreadComposerRoutingTest ‑ PerNodeComposer_PathAndNodeType_ResolveToTheSameTable
MeshWeaver.AI.Test.ThreadComposerRoutingTest ‑ PerUserComposer_PathAndNodeType_ResolveToTheSameTable
MeshWeaver.AI.Test.ThreadHubSelfReadTest ‑ Activating_thread_node_hub_does_not_self_post_a_contextless_GetDataRequest
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"   \")
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"///\")
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"/\")
MeshWeaver.AI.Test.ThreadMessageToolTest ‑ A_path_that_normalises_to_nothing_is_ANSWERED_not_thrown(path: \"@/\")
…

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

    53 files  ±0      53 suites  ±0   1h 2m 18s ⏱️ + 4m 19s
11 175 tests ±0  10 870 ✅ ±0  305 💤 ±0  0 ❌ ±0 
11 730 runs  +2  11 425 ✅ +2  305 💤 ±0  0 ❌ ±0 

Results for commit 6fe127b. ± Comparison against base commit d9b59b6.

This pull request removes 2 and adds 2 tests. Note that renamed tests count towards both.
MeshWeaver.PathResolution.Test.AddressResolutionTest ‑ ResolvePath_ThreadMessageNode_ResolvesToFullMessagePath
MeshWeaver.PathResolution.Test.AddressResolutionTest ‑ ResolvePath_ThreadNode_ResolvesCorrectlyWithChildren
MeshWeaver.AI.Test.ThreadAddressResolutionTest ‑ ResolvePath_ThreadMessageNode_ResolvesToFullMessagePath
MeshWeaver.AI.Test.ThreadAddressResolutionTest ‑ ResolvePath_ThreadNode_ResolvesCorrectlyWithChildren

@rbuergi
rbuergi merged commit 8b77345 into main Aug 26, 2026
27 checks passed
rbuergi added a commit that referenced this pull request Aug 26, 2026
…sees AI

CI: "The type or namespace name 'AI' does not exist in the namespace
'MeshWeaver'" at SkillFileParserTest.cs:2-3.

Not merge damage and not a missing reference to restore. Main deliberately
removed MeshWeaver.AI from MeshWeaver.Content.Test as part of #2276 (AI leaves
the platform) — the same direction as #2363 and #2368, which moved AI-dependent
suites out rather than re-adding the reference. This branch added a NEW test to
the project that had just been cut loose.

SkillFileParser is AI code (src/MeshWeaver.AI/Persistence/SkillFileParser.cs), so
its test belongs in MeshWeaver.AI.Test. Moved, namespace updated to match.

Re-adding the ProjectReference would have been the smaller diff and the wrong
one: it reverses deliberate carve-out work to accommodate a test that was in the
wrong project to begin with.

Verified: MeshWeaver.AI.Test and MeshWeaver.Content.Test both build clean under
-c Release -warnaserror; SkillFileParserTest 14/14 green in its new home.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rbuergi
rbuergi deleted the refactor/ai-test-batch-2 branch August 28, 2026 08:56
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