Skip to content

docs: the source compile gate passed — it compiles against the platform CI ships, not the one the instance runs - #4313

Merged
meshweaver-cloud[bot] merged 3 commits into
mainfrom
docs/source-nodes-have-no-link-gate-1126
Sep 14, 2026
Merged

meshweaver-cloud[bot] merged 3 commits into
mainfrom
docs/source-nodes-have-no-link-gate-1126

Conversation

@rbuergi

@rbuergi rbuergi commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Conserves the finding that came out of draining #1126 / #1840 / #4314 (the in-mesh compilation family). Doc-only.

Note on the diff: the first commit said "nothing in the fleet gates this direction." Copilot showed that was wrong — a source-level compile gate exists — and checking it produced a sharper claim, so the second commit rewrites the page and renames it (SourceNodesHaveNoLinkGate → CompiledAgainstAnotherPlatform). All six review findings are answered; see the response comment and the two inline threads.

The claim

In-mesh source is compiled in CI, exactly as the mesh compiles it: node-repo-compile-check.yml → compile-check.py, published as compile-check / Compile every NodeType (vs core) and required on most satellites. It runs against the reference set of a resolved platform image.

The gap is one of target, not coverage:

No gate compares the delivered source against the platform image the receiving instance is running. The Module Platform Link Gate does exactly that, for bytes.

The measured window (2026-09-14, memex.meshweaver.cloud)

when what
2026-09-12T09:30:22Z core c84c6c055 — the image both portals run (rolled 12:34Z as 3.0.0-ci.8411)
2026-09-12T17:28:05Z core #4102 (00fa2b69f9) adds PlanTierRefusal and RegistryPackageSource.ListCatalog
2026-09-14T06:19:40Z MeshWeaver.Plugins#1837 (dd9c96b4c8) changes the in-mesh Code node Store/Publishing/Source/RegistryPackages.cs to call both
— on that commit Compile every NodeType (vs core) is completed/success (48 success, 11 skipped, 0 failures) — MeshWeaver.Plugins resolves the platform per run (resolve-platform.py: the newest sealed set of core's main-cd), which carries #4102
2026-09-14T06:59:28Z the package lane has delivered the source to memex-cloud, still on c84c6c055. First failing compile — forty minutes after the merge

Blast radius from the incident's retained samples (a floor — ten against occurrences: 68): Store/Catalog, Store/Plugin, Store/Enrollment, Store/Provision, Store/Maintenance, Hosting/InstanceRequest; the failing replica's /health read previouslybroken=11. Tracked as #4314; the remedy is a roll, which also unblocks #3432.

What the page adds beyond the anecdote

  • Why Roslyn ran at all. PrebuiltAssemblySeeder adopts the CI bake when the framework identity matches; the bake was against the newer platform, so it was declined and the fallback compiled against the old reference set. Modules:RequirePrebuilt (default OFF) would have made that decline a named install-time error rather than a doomed compile.
  • How to read the diagnostic without going the wrong way. CS1061 on a type that resolved localizes the fault to the platform surface rather than to a source node that never landed — but it does not say which side moved (a removed member, or an out-of-scope extension, read identically). Three confirmation steps, with --is-ancestor labelled an ancestry check rather than a proof.
  • Why the NodeType sweep named none of the six. 8 of N ≥ 200 over M unknown — RLS filtering (no AgenticOffice/* rows for this identity, while /health counts 594 instances of three such types) plus compilationStatus being one shared field over a per-replica compile.
  • The arm that already exists. judge-against-baseline + baseline-image-digest — "what the fleet runs today" — is wired into the platform's satellite-compat lane on core's promote; "a node repo checking its own PR leaves it false."

Verification

$ dotnet build test/MeshWeaver.Documentation.Test/MeshWeaver.Documentation.Test.csproj -c Release -warnaserror
  Build succeeded.  0 Warning(s)  0 Error(s)
$ strings src/MeshWeaver.Documentation/bin/Release/net10.0/MeshWeaver.Documentation.dll | grep -c CompiledAgainstAnotherPlatform   → 3
$ strings … | grep -c SourceNodesHaveNoLinkGate                                                                                  → 0
$ dotnet test … --filter FullyQualifiedName~DocumentationLinkIntegrityTest
  Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: 51 ms

Listed in the Architecture topic map under both Node types and Plugins & content delivery. No src/ code, no workflows, no AGENTS.md, no skills. No What's New entry: nothing a user can notice changed.

🤖 Generated with Claude Code

…# the running image cannot compile

The Module Platform Link Gate measures a module's BYTES against the platform
actually running. An in-mesh Code node is text: nothing probes it, and the first
thing that ever measures its platform requirement is the runtime Roslyn compile.

Measured on memex.meshweaver.cloud, 2026-09-14. Core #4102 (00fa2b6, merged
09-12T17:28:05Z) added PlanTierRefusal and RegistryPackageSource.ListCatalog;
both portals serve c84c6c0, committed 09-12T09:30:22Z — `git merge-base
--is-ancestor 00fa2b6 c84c6c0` is false over 10 /api/version samples.
MeshWeaver.Plugins Store/Publishing/Source/RegistryPackages.cs, an in-mesh Code
node shared into many NodeTypes' source sets, began calling both in dd9c96b4c8
at 09-14T06:19:40Z; the first failing compile is 06:59:28Z. Six distinct
NodeTypes in the incident's retained window (Store/Catalog, Store/Plugin,
Store/Enrollment, Store/Provision, Store/Maintenance, Hosting/InstanceRequest) —
a floor, since ten samples against 68 occurrences is a bounded ring.

The page also records the discriminator, because the two diagnostics are not
equally informative: CS1061 on a PLATFORM type is conclusive (the type resolved,
so the assembly is on the reference set and only the member is missing — no
recompile can cure it), while a bare CS0246 is the same shape as a source node
that never landed. And it records why the NodeType sweep named none of the six:
8 of N >= 200 over M unknown, the envelope carrying no coverage field on this
image, plus compilationStatus being one shared field over a per-replica compile
(/health read previouslybroken=11 on the failing replica against the sweep's 8).

Doc-only. DocumentationLinkIntegrityTest green on the rebuilt assets
(1 passed, 42 ms); build -c Release -warnaserror: 0 Warning(s), 0 Error(s), and
the new resource verified present in the built MeshWeaver.Documentation.dll.

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

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.

🟡 Changes recommended

The documentation requires the six recorded nit corrections before its compatibility claims are accurate.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This documentation-only PR adds an architecture page describing source-node compatibility gaps and indexes it in the architecture map.

Changes:

  • Documents the incident, diagnostics, and runtime compatibility gap.
  • Adds the page under Node types and Plugins & content delivery.
File summaries
File Description Final review findings
src/MeshWeaver.Documentation/Data/Architecture/SourceNodesHaveNoLinkGate.md New architecture documentation Nits: Qualify diagnostic and ancestry conclusions (2 and 3 votes); correct the invalid timestamp (1 vote); document existing CI/prebuilt compilation paths and scope claims to the runtime/per-replica gap (1 vote each).
src/MeshWeaver.Documentation/Data/Architecture.md Adds topic-map entries Nit (1 vote): Scope the index summary to the missing runtime/per-replica link or admission gate.
Review details

Suppressed comments (4)

src/MeshWeaver.Documentation/Data/Architecture.md:257

  • This index summary repeats the page's overstatement: source is also compiled by the CI NodeType gate and may be served from a prebuilt NodeType assembly, so it is not true that nothing measures it until Roslyn. Please scope the summary to the missing runtime/per-replica link or admission gate.
- [Source Nodes Have No Link Gate](SourceNodesHaveNoLinkGate) — the link gate measures a module's BYTES; an in-mesh Code node is text, so nothing measures it until Roslyn does. Six NodeTypes on memex-cloud stopped compiling forty minutes after a satellite merged source calling two core APIs the running image predates, and the `CS1061` on a platform type is what tells that apart from a content bug

src/MeshWeaver.Documentation/Data/Architecture/SourceNodesHaveNoLinkGate.md:104

  • The published page contains 2026-09-14T12:4xZ, which is not a valid timestamp and reads like an unresolved placeholder. Replace it with the measured time or remove the minute-level precision before publishing.
[Search Coverage and Refusal](../SearchCoverageAndRefusal) — answered **8** at 2026-09-14T12:4xZ, all

src/MeshWeaver.Documentation/Data/Architecture/SourceNodesHaveNoLinkGate.md:24

  • The fleet already has a source-level compile gate: node-repo-compile-check.yml runs compile-check.py against the platform image's assemblies, and main-cd.yml invokes it for satellite compatibility; the Plugins module-pack contract also names Compile every NodeType (vs core) as required. That gate does not eliminate the per-replica/runtime admission gap described here, but saying “Nothing in the fleet” and omitting it from the table is inaccurate. Please distinguish “CI compiles source against a selected image” from “the delivered source is checked against every running replica/install target.”
Nothing in the fleet gates this direction:

| gate | what it measures | does it see an in-mesh source node? |
|---|---|---|
| [Module Platform Link Gate](../ModulePlatformLinkGate) | a module assembly's linked types vs. the running platform | **no** — source nodes have no assembly |

src/MeshWeaver.Documentation/Data/Architecture/SourceNodesHaveNoLinkGate.md:18

  • Source nodes are text at authoring time, but the runtime does not always compile them on every replica: PrebuiltAssemblySeeder adopts CI-baked NodeType assemblies when the framework identity matches, and only a missing or declined prebuilt falls back to Roslyn. CI also has a source-level compile check. The actual gap is that neither path verifies member compatibility against the exact running image/replica, so qualify the “compiled at runtime” and “first thing ... Roslyn” claims.
**An in-mesh Code node is not bytes. It is text.** It carries no assembly metadata, nothing probes
it, and it is compiled at runtime, on each replica, against whatever image that replica is running
(see [Node Type Compilation](../NodeTypeCompilation)). So a satellite repository can merge source that
calls a core API, the package lane can deliver it to a portal within the hour, and the first thing
that ever measures the requirement is the Roslyn compile — which fails.
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

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

Comment on lines +72 to +75
**`CS1061` on a PLATFORM type is conclusive.** The type *resolved* — the reference set holds
`MeshWeaver.PluginCatalog`, so the assembly is there — and only the member is missing. That can only
mean the running build of that assembly predates the member. No recompile can cure it, because
recompiling produces the same reference set; only a roll can.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Accepted — and following it produced a better claim than the one it corrected, so the page is rewritten and renamed (SourceNodesHaveNoLinkGate → CompiledAgainstAnotherPlatform).

You are right that CS1061 does not by itself say the running build predates the member. The same text appears when the platform is ahead and the member was removed or renamed with stale content left behind, and an extension method can be missing merely because its declaring class is out of scope.

The page now claims only what the diagnostic supports — the type resolved, so the fault is in the platform assembly's surface rather than in a source node that failed to land, which is the half that separates this from Missing Declared Sources / Install Completeness — and says explicitly, under a 🚨, that it does not establish the direction. "The platform is behind, roll it" is now framed as a conclusion to reach, with three confirmation steps before it: find the commit that added the member (git log -S), read the running commit from /api/version sampled more than once, then compare the surface at that commit (git show <running>:<path>), preferring the instance's own answer where one exists.

```bash
curl -s https://<portal>/api/version # the running commit — sample it more than once
git log -S '<symbol>' --oneline -- src/ # the core commit that added the symbol
git merge-base --is-ancestor <adding> <running> # false ⇒ the image predates the API ⇒ skew

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Accepted. The page no longer treats --is-ancestor as the verdict.

It is now labelled an ancestry check, with both of your cases named: a false also arises from diverged histories or a cherry-pick / equivalent re-introduction, and a true does not prove the member survived to the running commit. Step 3 of the confirmation sequence is therefore to read the surface at the running commit (git show <running>:<path>) and prefer the instance's own answer where one exists, rather than concluding from ancestry alone.

The concrete reading in the page keeps its --is-ancestor line because the direction was independently confirmed there — PlanTierRefusal is a file that 00fa2b69f9 ADDED, and it is absent at c84c6c055 — but the generic procedure no longer tells an operator that the ancestry answer is the finding.

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

262 tests  ±0   262 ✅ ±0   1m 54s ⏱️ -1s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

910 tests  ±0   910 ✅ ±0   3m 28s ⏱️ +6s
  2 suites ±0     0 💤 ±0 
  2 files   ±0     0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 472 tests  ±0   1 472 ✅ ±0   2m 50s ⏱️ -6s
    2 suites ±0       0 💤 ±0 
    2 files   ±0       0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 846 tests  ±0   1 654 ✅ ±0   4m 49s ⏱️ -3s
    4 suites ±0     192 💤 ±0 
    4 files   ±0       0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

♻️ This comment has been updated with latest results.

…rm CI ships, not the one the instance runs

Copilot was right on all six findings, and following them up produced a sharper
claim than the one they corrected. The page is renamed accordingly
(SourceNodesHaveNoLinkGate → CompiledAgainstAnotherPlatform).

What was wrong: "nothing in the fleet gates this direction". A source-level gate
exists — node-repo-compile-check.yml runs compile-check.py over every NodeType's
resolved Source against the reference set of a pinned platform image, and it is a
required context on most satellites. Measured: on dd9c96b4c8 (MeshWeaver.Plugins
#1837, the commit introducing the PlanTierRefusal / ListCatalog calls),
`Compile every NodeType (vs core)` is completed/success — 48 success, 11 skipped,
0 failures. It passed because MeshWeaver.Plugins resolves the platform per run
(scripts/resolve-platform.py: the newest SEALED set of core's main-cd), which
carried #4102; memex-cloud was on c84c6c0, five hours older.

So the gap is one of TARGET, not coverage: no gate compares the delivered source
against the image the receiving instance runs. And the same lane already
implements that reading — `judge-against-baseline` + `baseline-image-digest`,
"what the fleet runs today" — wired into the platform's satellite-compat lane on
core's promote, while "a node repo checking its own PR leaves it false".

Also corrected, all from the review: the runtime does not always Roslyn-compile
(PrebuiltAssemblySeeder adopts the CI bake when the framework identity matches;
here it did not, so the fallback ran) and Modules:RequirePrebuilt would have made
that decline a named error rather than a doomed compile; CS1061 localizes the
fault to the platform SURFACE but does not say which side moved — a removed
member or an out-of-scope extension produce the same text, so the page now asks
for the surface to be confirmed rather than inferred; `--is-ancestor` is labelled
an ancestry check, not a proof (diverged history, cherry-pick, later removal);
and the placeholder 2026-09-14T12:4xZ is now the measured 12:43Z.

DocumentationLinkIntegrityTest green on the rebuilt assets (1 passed, 51 ms);
build -c Release -warnaserror: 0 Warning(s), 0 Error(s), with the new embedded
resource present in MeshWeaver.Documentation.dll and the old one gone.

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

github-actions Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    6 files  ±0      6 suites  ±0   5m 10s ⏱️ -30s
2 183 tests ±0  2 183 ✅ ±0  0 💤 ±0  0 ❌ ±0 
2 187 runs  ±0  2 187 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

♻️ This comment has been updated with latest results.

@rbuergi

rbuergi commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

All six Copilot findings accepted — and the third one changed the thesis, so the page is renamed

SourceNodesHaveNoLinkGate → CompiledAgainstAnotherPlatform ("Compiled Against A Platform The Instance Does Not Run"). The two inline threads are answered in place; this covers the four suppressed ones and the rename.

The finding that changed the page

"The fleet already has a source-level compile gate: node-repo-compile-check.yml runs compile-check.py against the platform image's assemblies … saying 'Nothing in the fleet' and omitting it from the table is inaccurate."

Correct, and checking it produced a stronger claim than the one it replaced. Measured:

So the gap is one of target, not of coverage: no gate compares the delivered source against the image the receiving instance is running. The link gate does exactly that, for bytes.

🚨 And the same lane already implements the missing reading — judge-against-baseline + baseline-image-digest, "the PREVIOUS platform image (digest) — what the fleet runs today", with compat-verdict.py classifying each failure. Core's satellite-compat lane sets it on promote; "a node repo checking its own PR leaves it false and keeps the plain gate." The content half is the one that lands first and reaches portals fastest, and it is the half with no baseline arm. That is now the first option under "What would close this class".

The other five

finding what changed
CS1061 is not conclusive Answered inline. The page now claims only that the type resolved, so the fault is in the platform surface and not a source node that failed to land — and states under a 🚨 that it does not give the direction (a removed/renamed member, or an out-of-scope extension, produce the same text). Three confirmation steps replace the inference.
--is-ancestor is not proof Answered inline. Labelled an ancestry check, with diverged history, cherry-pick and later-removal all named; step 3 reads the surface at the running commit.
the runtime does not always Roslyn-compile New section, "Why Roslyn ran at all": PrebuiltAssemblySeeder adopts the CI bake when the framework identity matches; here the bake was against the newer platform, the identity did not match, the prebuilt was declined and the fallback compiled. It also records that Modules:RequirePrebuilt — default OFF, with its own doc comment saying a production portal should opt in — would have turned that decline into a named install-time error instead of a doomed compile.
2026-09-14T12:4xZ is not a valid timestamp Now the measured 12:43Z.
the index summary repeats the overstatement Both topic-map entries rewritten: the source lane measures against the platform it is about to ship, and judge-against-baseline is wired into core's promote rather than the satellite PR.

Verification on the rewritten page

$ dotnet build test/MeshWeaver.Documentation.Test/… -c Release -warnaserror
  Build succeeded.  0 Warning(s)  0 Error(s)
$ strings src/MeshWeaver.Documentation/bin/Release/net10.0/MeshWeaver.Documentation.dll | grep -c CompiledAgainstAnotherPlatform   → 3
$ strings … | grep -c SourceNodesHaveNoLinkGate                                                                                  → 0   (the rename really landed)
$ dotnet test … --filter FullyQualifiedName~DocumentationLinkIntegrityTest
  Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: 51 ms

🤖 Generated with Claude Code

@rbuergi rbuergi changed the title docs(#1126): source nodes have no link gate — a satellite can merge C# the running image cannot compile docs: the source compile gate passed — it compiles against the platform CI ships, not the one the instance runs Sep 14, 2026
The page tells the reader to settle the direction on the surface rather than on
ancestry, then reported only the ancestry answer for its own case. It now records
the read that was actually taken: PlanTierRefusal.cs is a file 00fa2b6 ADDED,
and `cat-file -e c84c6c0:<that path>` reports it absent at the running commit.

Build -c Release -warnaserror: 0 Warning(s), 0 Error(s);
DocumentationLinkIntegrityTest 1 passed, 64 ms.

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

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

1 092 tests  ±0   1 090 ✅ ±0   6m 10s ⏱️ -11s
    3 suites ±0       2 💤 ±0 
    3 files   ±0       0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

   18 files  ±0     18 suites  ±0   24m 24s ⏱️ -42s
7 765 tests ±0  7 571 ✅ ±0  194 💤 ±0  0 ❌ ±0 
7 769 runs  ±0  7 575 ✅ ±0  194 💤 ±0  0 ❌ ±0 

Results for commit 6b7ff5c. ± Comparison against base commit 8d3c307.

@meshweaver-cloud
meshweaver-cloud Bot added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit e321888 Sep 14, 2026
36 checks passed
@rbuergi
rbuergi deleted the docs/source-nodes-have-no-link-gate-1126 branch October 10, 2026 13:10
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