Skip to content

fix(modules): boot, landing and live swap measure the member half of the link probe (#6007) - #6196

Merged
rbuergi merged 1 commit into
mainfrom
fix/runtime-link-probe-measures-members
Oct 6, 2026
Merged

rbuergi merged 1 commit into
mainfrom
fix/runtime-link-probe-measures-members

Conversation

@rbuergi

@rbuergi rbuergi commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Refs #6007. It is sev:H, so it closes after verification, not when this merges.

Root cause

The runtime link probe checked type references only. Boot (src/MeshWeaver.Mesh.Contract/MeshBuilder.cs, TryLoad), the landing (src/MeshWeaver.PluginCatalog/ModuleLandingService.cs, LinkVerdict / HeadDoesNotLoadHere) and the live swap (src/MeshWeaver.Graph/Configuration/ModuleLiveUpdater.cs, LoadAndCommit) all called ModulePlatformLink.Check with the default ModuleLinkOptions.TypesOnly. ModulePlatformLinkGate.md listed member skew as a known blind spot.

#6007 is exactly that blind spot:

  • OpenAI 1.4.0 calls ReasoningEffortLevels.IsBuiltIn(IEnumerable<string>), which was added to MeshWeaver.AI in Plugins bd2164269.
  • Its hand-typed minMeshVersion admitted it onto images whose AI predated that method.
  • The type probe passed, because ReasoningEffortLevels exists.
  • The module landed, and every chat round through the OpenAI wire threw MissingMethodException. That was about 200 occurrences on memex (2026-10-02 19:42Z to 10-03 06:19Z) and every round on a customer instance running 3.0.0-ci.9606.

Plugins fixed the floor at its source (mesh-floors.py stamps floors). This PR closes the platform's half: the measured gate now sees the member.

Fix

  • Member half on at the three file-backed sites. Boot, the landing (and its head re-check) and the live swap now pass ModuleLinkOptions.WithMembers. Their surface is this process's own files, so the member walk gives a definite answer.
    • A refusal behaves exactly like a type-level refusal: the landing keeps the previous generation, and boot falls back to the previous generation or the image baseline.
    • The roll gate keeps TypesOnly, because its surface is a published document with type names only. Prebuilt NodeType adoption also keeps TypesOnly.
  • New overload ModulePlatformLink.Check(byte[], string, IReadOnlySet<string>, ModulePlatformSurface, ModuleLinkOptions) for the in-memory landing. A bare cref to Check was already ambiguous across the existing four overloads, so this adds no CS0419.
  • A false refusal fixed first. The blast-radius run found that PlatformBasesOf stopped at a generic base defined in the platform assembly itself: a TypeSpec over a TypeDefinition, as in InputBase3 : FormComponentBase3 : … : BlazorView2`.
    • So the image's own MeshWeaver.Blazor.EntityViews read 8 protected BlazorView2` members as "no longer accessible".
    • GenericDefinitionOf now resolves that shape in PlatformBasesOf and in Supertypes.
  • Doc: ModulePlatformLinkGate.md.

Blast radius, measured on real bytes before shipping

Surface: image memex-portal-ai:d205295 (3.0.0-ci.9984, the control instance's image), its /app plus modules/, plus the local shared framework. Modules checked: the 11 image modules and the 4 deployed module bundles of that build's main-cd run (37295575134: AI, Markdown.Collaboration, Maps, Payments.Stripe). About 3,900 member references were checked.

  • 0 refused with this change.
  • 1 refused before the generic-base fix (EntityViews, described above).

Tests

All run locally.

  • ModulePlatformLinkTest.AModuleCallingAMemberThisPlatformLacks_IsRefusedAtLanding_NamingTheMember: the OpenAI chat wire throws MissingMethodException — MeshWeaver.AI.OpenAI deployed against an incompatible MeshWeaver.AI build #6007 shape on the production surface. The real MeshWeaver.Mesh.Contract lacks a member that a stand-in carries.
    • In-test negative control: the type-only verdict admits the same bytes.
  • …_IsParkedAtBoot: the same bytes at boot are parked as IncompatibleModule naming the member, and the sibling module installs.
  • ModulePlatformMemberLinkTest.AProtectedMemberThroughGenericPlatformBases_IsAccessible_AndRuns: the static verdict is Linkable, and the bytes really run.
  • Negative controls (run): reverting the landing site, the boot site and GenericDefinitionOf turns all three tests red (3 of 3 failed).
  • Wider runs:
    • Memex.Portal.Shared.Test with filter Module|LinkVerdict: 411 of 412 pass. The one failure is ReleaseLinkGateTest.ALandedModuleThatLinksAgainstTheTarget_Clears, which threw a Roslyn NullReferenceException inside its own test helper's Compilation.Emit (ModulePlatformSurfaceJsonTest.Emit). That is the roll-gate path, which this PR does not change, and no code in this diff runs there.
    • MeshWeaver.Compiler.Pipeline.Test with filter Module: 169 of 169 pass.

Not established

Pairs-with: none — adds an overload; nothing removed or re-signed.

🤖 Generated with Claude Code

…the link probe (#6007)

The runtime link probe checked TYPE references only. OpenAI 1.4.0 called
ReasoningEffortLevels.IsBuiltIn(IEnumerable<string>) — a member the loaded MeshWeaver.AI
lacked on a type it had — so it landed, loaded, and threw MissingMethodException on every
chat round (memex 2026-10-02/03; every round on a customer instance on ci.9606).

- MeshBuilder.TryLoad (boot), ModuleLandingService (landing + head re-check) and
  ModuleLiveUpdater (live swap) pass ModuleLinkOptions.WithMembers: their surface is this
  process's own files, so the member walk is determinate. A refusal falls back exactly as a
  type-level refusal does. The roll gate (published document, types only) and prebuilt
  NodeType adoption keep TypesOnly.
- ModulePlatformLink.Check(byte[], ..., options) for the in-memory landing.
- Fix a false refusal the blast-radius run found: the derivation walk stopped at a generic
  base defined in the platform assembly itself (InputBase`3 : FormComponentBase`3 : ... :
  BlazorView`2), so the image's own MeshWeaver.Blazor.EntityViews read 8 protected members as
  "no longer accessible". GenericDefinitionOf resolves TypeSpec-over-TypeDefinition bases in
  PlatformBasesOf and Supertypes.
- Measured on image 3.0.0-ci.9984: 11 image modules + 4 deployed bundles, ~3,900 member refs,
  0 refused (1 before the generic-base fix).
- Doc: ModulePlatformLinkGate.

Tests: landing refusal and boot parking of a module calling a member this platform lacks (with
the type-only verdict as in-test negative control); protected member through generic platform
bases is Linkable and runs. Neutralising each fix reds all three.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

    22 files  ±0      22 suites  ±0   44m 31s ⏱️ +56s
10 781 tests +3  10 588 ✅ +3  193 💤 ±0  0 ❌ ±0 
10 794 runs  +3  10 601 ✅ +3  193 💤 ±0  0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

This pull request removes 29 and adds 14 tests. Note that renamed tests count towards both.

   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---, expected: True)
   --- End of inner exception stack trace ---, isDenial: True)
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
 ---> (Inner Exception #1) System.InvalidOperationException: boom<---
 ---> (Inner Exception #1) System.InvalidOperationException: source B is misconfigured<---
 ---> (Inner Exception #1) System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known<---
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
 ---> System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432)
…
Memex.Portal.Shared.Test.InstanceIdRulesMatchTheRegistryTest ‑ TheSetupHostAgreesWithTheRegistry(candidate: "f1a1e9c7-2fe9-466a-a3ee-007ae92f77aa")
Memex.Portal.Shared.Test.ModulePlatformLinkTest ‑ AModuleCallingAMemberThisPlatformLacks_IsParkedAtBoot
Memex.Portal.Shared.Test.ModulePlatformLinkTest ‑ AModuleCallingAMemberThisPlatformLacks_IsRefusedAtLanding_NamingTheMember
Memex.Portal.Shared.Test.ModulePlatformMemberLinkTest ‑ AProtectedMemberThroughGenericPlatformBases_IsAccessible_AndRuns
Memex.Portal.Shared.Test.SessionDenialIsAnAnswerTest ‑ OnlyAVerdictReadsAsADenial(shape: "the same verdict nested, as a late denial dispatch"···, failure: System.InvalidOperationException: write failed
 ---> System.UnauthorizedAccessException: Access denied
   --- End of inner exception stack trace ---, isDenial: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a MIXED aggregate — one transient branch, one genu"···, exception: System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432) (source B is misconfigured)
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) System.InvalidOperationException: source B is misconfigured<---
, expected: False)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a nested aggregate with one genuine leaf", exception: System.AggregateException: One or more errors occurred. (One or more errors occurred. (Failed to connect to 10.42.18.4:5432) (boom)) (Failed to connect to 10.42.18.4:5432)
 ---> System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432) (boom)
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) System.InvalidOperationException: boom<---

   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
, expected: False)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a nested aggregate, all leaves transient", exception: System.AggregateException: One or more errors occurred. (One or more errors occurred. (Failed to connect to 10.42.18.4:5432)) (Failed to connect to 10.42.18.4:5432)
 ---> System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432)
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
, expected: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a reflective wrapper around a transient cause", exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Net.Sockets.SocketException (110): Connection timed out
   --- End of inner exception stack trace ---, expected: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a transient cause UNDER an aggregate branch's wrap"···, exception: System.AggregateException: One or more errors occurred. (wrapped)
 ---> System.InvalidOperationException: wrapped
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---, expected: True)
…

♻️ This comment has been updated with latest results.

@systemorph-com systemorph-com Bot added the thread:pr-systemorph-meshweaver-6196-4c817d https://memex.systemorph.com/Hosting/Triage/_Thread/pr-systemorph-meshweaver-6196 label Oct 6, 2026
@systemorph-com
systemorph-com Bot disabled auto-merge October 6, 2026 07:29
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

  3 files  ±0    3 suites  ±0   3m 10s ⏱️ -15s
566 tests ±0  375 ✅ ±0  191 💤 ±0  0 ❌ ±0 
570 runs  ±0  379 ✅ ±0  191 💤 ±0  0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

    5 files  ±0      5 suites  ±0   3m 59s ⏱️ +6s
1 279 tests ±0  1 279 ✅ ±0  0 💤 ±0  0 ❌ ±0 
1 280 runs  ±0  1 280 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 753 tests  ±0   1 751 ✅ ±0   5m 39s ⏱️ +3s
    4 suites ±0       2 💤 ±0 
    4 files   ±0       0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

2 477 tests  +1   2 477 ✅ +1   7m 28s ⏱️ -1s
    4 suites ±0       0 💤 ±0 
    4 files   ±0       0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    2 files  ±0      2 suites  ±0   8m 41s ⏱️ +21s
1 108 tests ±0  1 108 ✅ ±0  0 💤 ±0  0 ❌ ±0 
1 109 runs  ±0  1 109 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

    4 files  ±0      4 suites  ±0   15m 32s ⏱️ +40s
3 598 tests +2  3 598 ✅ +2  0 💤 ±0  0 ❌ ±0 
3 605 runs  +2  3 605 ✅ +2  0 💤 ±0  0 ❌ ±0 

Results for commit 7749fba. ± Comparison against base commit 8c08fa4.

This pull request removes 29 and adds 13 tests. Note that renamed tests count towards both.

   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---, expected: True)
   --- End of inner exception stack trace ---, isDenial: True)
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
 ---> (Inner Exception #1) System.InvalidOperationException: boom<---
 ---> (Inner Exception #1) System.InvalidOperationException: source B is misconfigured<---
 ---> (Inner Exception #1) System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known<---
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
 ---> System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432)
…
Memex.Portal.Shared.Test.InstanceIdRulesMatchTheRegistryTest ‑ TheSetupHostAgreesWithTheRegistry(candidate: "f1a1e9c7-2fe9-466a-a3ee-007ae92f77aa")
Memex.Portal.Shared.Test.ModulePlatformLinkTest ‑ AModuleCallingAMemberThisPlatformLacks_IsParkedAtBoot
Memex.Portal.Shared.Test.ModulePlatformLinkTest ‑ AModuleCallingAMemberThisPlatformLacks_IsRefusedAtLanding_NamingTheMember
Memex.Portal.Shared.Test.SessionDenialIsAnAnswerTest ‑ OnlyAVerdictReadsAsADenial(shape: "the same verdict nested, as a late denial dispatch"···, failure: System.InvalidOperationException: write failed
 ---> System.UnauthorizedAccessException: Access denied
   --- End of inner exception stack trace ---, isDenial: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a MIXED aggregate — one transient branch, one genu"···, exception: System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432) (source B is misconfigured)
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) System.InvalidOperationException: source B is misconfigured<---
, expected: False)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a nested aggregate with one genuine leaf", exception: System.AggregateException: One or more errors occurred. (One or more errors occurred. (Failed to connect to 10.42.18.4:5432) (boom)) (Failed to connect to 10.42.18.4:5432)
 ---> System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432) (boom)
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) System.InvalidOperationException: boom<---

   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
, expected: False)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a nested aggregate, all leaves transient", exception: System.AggregateException: One or more errors occurred. (One or more errors occurred. (Failed to connect to 10.42.18.4:5432)) (Failed to connect to 10.42.18.4:5432)
 ---> System.AggregateException: One or more errors occurred. (Failed to connect to 10.42.18.4:5432)
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
, expected: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a reflective wrapper around a transient cause", exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.Net.Sockets.SocketException (110): Connection timed out
   --- End of inner exception stack trace ---, expected: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "a transient cause UNDER an aggregate branch's wrap"···, exception: System.AggregateException: One or more errors occurred. (wrapped)
 ---> System.InvalidOperationException: wrapped
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---, expected: True)
MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest ‑ Classifies(shape: "an 'initialization failed' wrapper around a transi"···, exception: System.InvalidOperationException: Hub 'x' initialization failed
 ---> MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432
   --- End of inner exception stack trace ---, expected: True)
…

♻️ This comment has been updated with latest results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

thread:pr-systemorph-meshweaver-6196-4c817d https://memex.systemorph.com/Hosting/Triage/_Thread/pr-systemorph-meshweaver-6196

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant