Skip to content

chore: land the core batch as one merge — four green PRs, one queue cycle - #2853

Closed
rbuergi wants to merge 9 commits into
mainfrom
integration/core-batch
Closed

rbuergi wants to merge 9 commits into
mainfrom
integration/core-batch

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Batches four individually-green PRs into a single merge so they cost one queue cycle instead of four.

PR what
#2848 docs: the fleet test shape
#2849 the install no longer waits 30s for a node documented as optional
#2850 memex build project — compile a csproj against the container, no SDK, no NuGet
#2852 a FATAL is never silent; the repo sweep skips unreadable files loudly

🚨 #2842 was REMOVED from this batch — it is the cause, not a passenger

The first cut of this batch included #2842 and failed CompileFinishAndDisposeTest on shard 2 three times, deterministically, including on a freshly-rebased base with the merge queue empty. I misread that as base-dependence. It was not.

meshweaver-61 proved the mechanism (core #2842, issuecomment-5472066551) — a four-part interlock:

  1. fix: a successful in-mesh compile's diagnostics reach its ACTIVITY #2842 funnels successful-compile warnings into the activity log (DocumentationMode.Diagnose was always on), so an undocumented public record yields CS1591s.
  2. Its own comment — "Warning never flips Finish's terminal status" — is false: Finish is MAX(floor, fold).
  3. Dual-terminal-writer split-brain: the activity-node writer pins Succeeded while result.Log carries the folded Warning.
  4. Which of the two the response surfaces depends on Adopted prebuilt build's source stamp is refused by MergeGuard — IsDirty never converges (the gate now names it compile-status-unrecorded, #2649) #2463's stamp-write-back race — that is the coin-flipper; fix: a successful in-mesh compile's diagnostics reach its ACTIVITY #2842's inconsistency is the two-headed coin.

Hence: green in isolation on a quiet machine, red under CI load. #2842 returns once it carries the writer-consistency fix and a rebase.

The #2850 / #2851 conflict, resolved deliberately

#2851 landed on main while #2850 sat queued, and both touch src/MeshWeaver.Cli/BuildPluginCommand.cs. The resolution keeps #2851's ComposeModulesFromSeed (now trunk content) and drops the PullImage that #2850 moved into the new ImageRunner.cs — verified the move had actually landed (ImageRunner.PullImage exists; BuildPluginCommand calls _runner.PullImage) before deleting anything.

Two defects in the first resolution attempt, both caught by building rather than reading: a duplicated /// <summary> (the original tag sat above the conflict marker as shared context) and a Capture call needing qualification to ImageRunner.Capture.

Verification

Full solution build on the merged tree: 90 projects, 0 Warning(s), 0 Error(s) under -warnaserror.

Each constituent PR carries its own tests and evidence; this changes none of them.

🤖 Generated with Claude Code

rbuergi and others added 5 commits August 30, 2026 23:53
… ours

Maintainer, 2026-08-30: "we are about to remove all nuget dependencies — for
tests. All repos. Check plugins how we do it."

Checked and measured rather than assumed. The Plugins idiom is stricter than
"no xUnit": across all 206 in-mesh test node sets, `using Xunit` occurs ZERO
times, and so does every other assertion library — including our own
Reactive.Assertions. A test is plain C# that throws, with a local four-line
Expect(bool, string) helper owned by the file; a TestsArea enumerates
(name, Action) cases and renders the pass/fail table, registered with a
LITERAL .WithView("Tests", …) because the gate reads that field as text; the
gate executes it on a probe instance and the Tests-area ratchet holds the
population.

So a test compiles against exactly what the image's framework provides plus
its own type's Source: nothing to restore, nothing to version, nothing that
can drift against the framework under test. What retires with the compiled
test projects is the whole test-dependency graph — xUnit v3, FluentAssertions,
the runner, the .trx machinery, and the restore step feeding them — not just
MeshWeaver.Fixture.

Deliberately-given-up list stated so it is a decision, not a discovery:
parametrised theories, runner-process isolation, IDE test explorer, .trx
artifacts. The gate log and the rendered table are the record; the trade has
been paid 206 times in production without a request for any of the four back.

This also RESOLVES the doc's own open question ("deciding what the in-mesh
unit-test surface is" for module tests): the surface exists, it is this, and
it has 206 production instances.

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

`PackageInstaller` waited up to 30 s for a partition's cover grant while the
wait's own doc comment called that grant optional — "a partition whose node
type does not gate never writes it". On the shape the code itself called
*normal* the query can never emit, so every install burned the entire budget
and then reported success, leaving one Information line worded to cover both
outcomes. Measured in `MeshWeaver.PluginCatalog.Test`: 30.25 s / 30.29 s /
30.33 s / 30.24 s per install and 60.28 s for the test that installs twice —
181 s of a 336 s suite. `PackageInstaller.Install` is the production install
path, so a live mesh paid the same 30 s per non-gating package.

Core cannot ask a node type whether it gates (`Store/Plugin`, `PluginContent`
and `AddPluginGating` live in MeshWeaver.Plugins), which is why the grant is a
well-known PATH. It does not have to: `EnsureDeclaredAccess` is the ONE
access-establishment step of an install and already states, per manifest,
whether it published the partition or left it gated. `DeclaredAccessMarker` is
null exactly when it wrote nothing — the commercial branch — and that is the
only shape a gating pass owes a cover grant. `CoverGrantExpected` is that, and
the watch now runs only there.

- `GatingSettleTimeout` (30 s) → `GatingDetectorBudget` (5 s), renamed for what
  it now is. Justified by measurement: when a grant IS owed it is observable in
  44–55 ms (`GatingDetectorTest` measures the real write→observe latency on a
  live mesh), and phase 1 has already paid the activation, so the only
  outstanding work is one access-table write.
- The two outcomes stop looking identical: the expiry is a WARNING naming the
  missing path and the consequence (the partition denies every viewer,
  including on the Subscribe cover that would sell it); "nothing owed" is Debug.
  Warning, not Error — the expiry proves the grant is not there yet, not that
  it never will be, and `VerifyDeclaredAccess` owns the Error verdict for
  access core itself promised to write.
- Still never fatal, and the query is unchanged: `path:{grant}` exact,
  empty-on-absent, never a stream read (#2229) and never a children listing.

`GatingDetectorTest` pins all three outcomes and is mutation-proven: downgrading
the warning, disabling `CoverGrantExpected`, or restoring the 30 s budget each
turns it red.

Suite: 707/707 green, 5 m 36 s → 2 m 49 s.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…er, no SDK, no NuGet

Maintainer directive, 2026-08-30: "the platform builds dll completely without any external
dotnet kit or nuget."

`memex build project <csproj|dir> --image <image>` compiles a .NET project with NO dotnet SDK
and NO NuGet restore, against the assemblies of a MeshWeaver image. The CLI half is only the
trip into the container — it shares ImageRunner (pull retry, digest pin, process launch) with
`build plugin` rather than carrying a second copy. The work is `mw-plugin-test build-project`,
three types in the tool already in the image:

* ProjectFile — evaluates the .csproj WITHOUT MSBuild: properties, items, the default **/*.cs
  glob minus bin/obj, Compile Include/Remove, ProjectReference, PackageReference, implicit
  usings, the target-framework symbol ladder, the SDK's own default NoWarn (1701;1702), the
  nearest Directory.Build.props/.targets/Directory.Packages.props, and every <Import> whose
  condition holds. Anything it cannot reproduce FAILS the load by name; --accept acknowledges
  one. A silently dropped Nullable or NoWarn is a green build that is not the SDK's build.

* ContainerReferenceSet — the C# port of MeshWeaver.Plugins/scripts/container-refs.py, read
  from /app instead of an extracted image: the image's own .deps.json for versions and the
  binding identity, /app plus the container's shared frameworks for the assemblies. Fails
  closed on an unreadable /app, a missing or ambiguous .deps.json, or MeshWeaver assemblies
  that disagree on their binding identity (MeshWeaver#143, caught in the image rather than at
  run time). A package is matched by the ASSEMBLY FILE on disk, never by its id alone; one the
  container does not supply is an ADDITIONAL library, reported by name and never skipped.

* ProjectBuild — sequences the ProjectReference graph on the existing Cascade (a cycle is
  refused up front and named), compiles with Roslyn, and emits through the platform's own
  EmitPipeline. It builds its OWN CSharpCompilationOptions and never touches
  CreateCompilationOptions, which feeds GeneratedInputIdentity.OptionsFingerprint. Every
  progress line and diagnostic is streamed into an ActivityLog (ActivityCategory.Compilation)
  as it is produced; the console is a rendering of that stream.

Measured against memex-portal-ai@sha256:15c49ee over MeshWeaver.Plugins/src: 12 of 54 non-test
projects green, including MeshWeaver.Import (90 sources, 0 warnings under warnings-as-errors)
with ClosedXML + CsvHelper as --extra-refs. The rest are named limitations: Razor/Blazor (15),
SDK source generators (15), <Protobuf> (3), additional libraries (5), portal hosts (3).

Also here: BuildPluginCommand's docker plumbing moves to ImageRunner (and gains `--init`, the
convention every workflow already uses), and MeshWeaver.Compiler grants InternalsVisibleTo to
mw-plugin-test so the emit is SHARED rather than re-implemented.

51 new tests, executed: csproj evaluation (globs, Remove, Directory.Build.props inheritance,
the condition grammar, every loud refusal), reference resolution (assembly-on-disk matching,
the metapackage case, the additional-library case, all five fail-closed paths), ProjectReference
ordering and cycle detection, and the diagnostic standard — an unresolvable cref and an unused
local are asserted to be REPORTED, and the emitted assembly is LOADED and invoked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/MeshWeaver.Cli/BuildPluginCommand.cs
…r kills the whole build

The first real `mw-plugin-test build` run on a dev machine died with exit 70
and ZERO bytes on stdout and stderr. Two defects compounded.

Every early fatal was mute: Print lives at the end of Finish, which only the
successful pipeline reaches — LoadSync throwing, no packages, an unknown
package id, LoadExternalModules refusing, and Run's outer Catch all returned
their Report straight to Program, which turned it into an exit code and
nothing else. Run now guarantees at its one seam that a FatalError report
prints (full exception, stack included) and writes report.json when asked;
Finish never sets FatalError, so nothing prints twice.

With the silence fixed the real cause self-identified: LocalNodeRepo.Sweep
eagerly reads EVERY file under the repo root and died on a dead Playwright
symlink (e2e/.auth/profile/RunningChromeVersion) — gitignored, so invisible
to every CI checkout, fatal for exactly the local no-dotnet loop the verb
exists for. The sweep now skips an unreadable file loudly and continues;
such a file crashed both bake paths before, so the shared swept-content
contract cannot fork.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoG4USP5fd8wsxCD7e9q4x
Copilot AI lite review requested due to automatic review settings August 30, 2026 22:55

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 batches multiple previously-green changes into one merge, spanning compiler diagnostics surfacing, plugin install readability (cover-grant stall detection), a new “build project without SDK/NuGet” workflow (CLI + in-image builder), and supporting documentation.

Changes:

  • Surface successful in-mesh compile warnings into the compile Activity log (via EmitPipeline → EmittedArtifact → MeshNodeCompilationService).
  • Replace the install “wait for optional cover grant” with a bounded detector that only engages when a cover grant is actually owed, plus tests/docs.
  • Add memex build project and mw-plugin-test build-project to compile a .csproj against an image’s /app reference set (no SDK/restore), plus supporting tests.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/MeshWeaver.PluginTester/README.md Documents the new build-project verb and its constraints.
tools/MeshWeaver.PluginTester/ProjectBuild.cs Implements the in-image .csproj build pipeline (graph discovery, reference resolution, diagnostics streaming, emit).
tools/MeshWeaver.PluginTester/Program.cs Adds argv parsing/dispatch for build-project.
tools/MeshWeaver.PluginTester/LocalNodeRepo.cs Makes repo sweep resilient to unreadable files by skipping loudly.
tools/MeshWeaver.PluginTester/ContainerReferenceSet.cs Reads container /app + deps.json + shared frameworks to form the reference set for builds.
tools/MeshWeaver.PluginTester/CascadeBuild.cs Ensures fatals print and report output is written for early failures.
test/MeshWeaver.PluginTester.Test/ProjectFileTest.cs Pins the csproj evaluator behavior (items/properties/conditions/imports/refusals).
test/MeshWeaver.PluginTester.Test/ProjectBuildTest.cs End-to-end tests for building projects against an /app-shaped reference set and loading the output DLL.
test/MeshWeaver.PluginTester.Test/ContainerReferenceSetTest.cs Tests fail-closed reference-set construction and package→assembly matching semantics.
test/MeshWeaver.PluginCatalog.Test/InstallGatingHandshakeTest.cs Updates the doc/pin around the cover-grant path contract and the detector behavior.
test/MeshWeaver.PluginCatalog.Test/GatingDetectorTest.cs Adds tests for the gating-stall detector outcomes and budget expectations.
test/MeshWeaver.Graph.Test/EmitPipelineAccess.cs Provides test access to internal compiler option factories/warning formatting.
test/MeshWeaver.Graph.Test/CompileWarningsReachTheActivityTest.cs Pins warning collection/capping/ordering and ensures warnings are reported even on successful compiles.
src/MeshWeaver.PluginCatalog/PackageInstaller.cs Implements cover-grant “owed vs not owed” discriminator and bounded stall detection (instead of unconditional waiting).
src/MeshWeaver.Graph/Configuration/MeshNodeCompilationService.cs Carries compile warnings up into the compile Activity log on success paths.
src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-31-installs-no-longer-wait-30-seconds-for-a-node-that-is-optional.md Adds What’s New entry describing the install gating detector change.
src/MeshWeaver.Documentation/Data/Architecture/Plugins.md Links plugin architecture doc to install readability guidance.
src/MeshWeaver.Documentation/Data/Architecture/InstallReadability.md Adds a new architecture page describing the two “readability doors” and the detector.
src/MeshWeaver.Documentation/Data/Architecture/InMeshBuildAndTest.md Expands documentation on test shape and adds the “build project without SDK” section.
src/MeshWeaver.Documentation/Data/Architecture.md Adds “Install Readability” to the architecture index table.
src/MeshWeaver.Compiler/MeshWeaver.Compiler.csproj Grants IVT access to mw-plugin-test so it can reuse emit internals.
src/MeshWeaver.Compiler/EmittedArtifact.cs Extends emitted artifact metadata to carry successful-compile warnings.
src/MeshWeaver.Compiler/EmitPipeline.cs Adds warning collection/formatting/capping and attaches warnings to emitted artifacts.
src/MeshWeaver.Cli/README.md Documents memex build project usage and options.
src/MeshWeaver.Cli/Program.cs Adds the memex build project subcommand wiring.
src/MeshWeaver.Cli/ImageRunner.cs Introduces shared docker pull/digest pin + run plumbing for CLI build verbs.
src/MeshWeaver.Cli/BuildProjectCommand.cs Implements the host-side “trip into container” for memex build project.
src/MeshWeaver.Cli/BuildPluginCommand.cs Refactors plugin build to reuse the new ImageRunner helper.
Suppressed comments (23)

src/MeshWeaver.Cli/ImageRunner.cs:57

  • This await adds an async continuation in src, which in this repo is a common source of deadlocks (parked scheduler) and AccessContext loss across thread hops. Consider refactoring the image/CLI IO boundary to be reactive (IObservable) or strictly synchronous here.
                var digest = await Capture("docker",

src/MeshWeaver.Cli/ImageRunner.cs:63

  • Async/await in src is risky here because continuations may resume on a different thread, which can drop AsyncLocal state (AccessContext) and can park single-threaded schedulers when invoked from hub-adjacent code paths. Prefer composing an IObservable pipeline or moving the async boundary behind IIoPool.
                    await output.WriteLineAsync(

src/MeshWeaver.Cli/ImageRunner.cs:72

  • This await adds an async boundary in src; in this repo, async boundaries can wedge turn-based schedulers and/or lose AsyncLocal context. Prefer a reactive pipeline or move retry delay handling behind IIoPool (or make the operation synchronous at the CLI layer).
                await error.WriteLineAsync(

src/MeshWeaver.Cli/ImageRunner.cs:74

  • Using await Task.Delay here introduces an async scheduling boundary in src; this repo generally avoids this because it can park schedulers and lose AsyncLocal context. Consider expressing retry as an IObservable timer/composition, or keep the CLI path synchronous.
                await Task.Delay(TimeSpan.FromSeconds(10), ct);

src/MeshWeaver.Cli/ImageRunner.cs:77

  • This await introduces another async continuation in src; across this codebase async continuations are a frequent cause of lost AccessContext (AsyncLocal) and scheduler parking. Prefer a reactive surface (IObservable) or move the async work behind IIoPool.
        await error.WriteLineAsync(

src/MeshWeaver.Cli/ImageRunner.cs:123

  • Async/await in src: this introduces a continuation that can hop threads and drop AsyncLocal state, and it’s unsafe when called from any turn-based scheduler. Prefer a reactive pipeline or keep this code synchronous.
        if ((await Capture("docker", ["image", "inspect", image, "--format", "{{.Id}}"], ct))

src/MeshWeaver.Cli/ImageRunner.cs:126

  • This await adds another async continuation in src; repository practice is to avoid awaits here to prevent scheduler wedges and AccessContext loss. Consider refactoring to a reactive/synchronous process runner abstraction.
            await error.WriteLineAsync(

src/MeshWeaver.Cli/ImageRunner.cs:131

  • Async/await in src: this introduces a continuation hop and the same scheduler/context risks (parked turn-based schedulers; AsyncLocal AccessContext loss). Prefer reactive composition or a synchronous CLI boundary.
        await output.WriteLineAsync(

src/MeshWeaver.Cli/ImageRunner.cs:146

  • This await introduces async/await in src for process execution; in this repo, async continuations are a common source of context loss and scheduler parking. Prefer an IObservable-based process runner or make Exec synchronous and keep async out of src.
        await output.WriteLineAsync($"$ {file} {string.Join(' ', psi.ArgumentList)}");

src/MeshWeaver.Cli/ImageRunner.cs:150

  • Async/await in src: this adds another continuation boundary with the same risks (AsyncLocal state loss, parked scheduler if invoked from hub-like code). Consider moving process startup/execution behind IIoPool or using a reactive pipeline.
            await error.WriteLineAsync($"error: could not start '{file}' — is it installed and on PATH?");

src/MeshWeaver.Cli/ImageRunner.cs:153

  • Awaiting process exit here introduces async continuations in src, which this codebase generally avoids due to scheduler wedge risk and AsyncLocal context loss. Prefer a reactive boundary or synchronous waiting at the CLI edge.
        await p.WaitForExitAsync(ct);

src/MeshWeaver.Cli/ImageRunner.cs:169

  • This await introduces another Task-based continuation in src, with the usual risks in this repo (scheduler parking, AsyncLocal AccessContext loss). Consider changing Capture to a reactive/synchronous implementation and keeping Task APIs out of core code paths.
        var stdout = await p.StandardOutput.ReadToEndAsync(ct);

src/MeshWeaver.Cli/ImageRunner.cs:170

  • Async/await in src: awaiting WaitForExitAsync introduces a continuation boundary and the same context/scheduler risks. Prefer a reactive/synchronous process execution abstraction (or run true async IO behind IIoPool).
        await p.WaitForExitAsync(ct);

src/MeshWeaver.Cli/BuildProjectCommand.cs:61

  • Async/await in src here introduces a continuation boundary; in this codebase, that risks scheduler wedges and AsyncLocal context loss. Consider refactoring this command’s IO surface to be reactive (IObservable) or strictly synchronous at the CLI edge.
            await error.WriteLineAsync(

src/MeshWeaver.Cli/BuildProjectCommand.cs:96

  • This await introduces an async boundary in src; repository guidance avoids awaits to prevent deadlocks on turn-based schedulers and loss of AsyncLocal AccessContext. Prefer a reactive pipeline or move async work behind IIoPool.
                await error.WriteLineAsync(

src/MeshWeaver.Cli/BuildProjectCommand.cs:106

  • Awaiting Exec here introduces Task continuations in src, which is discouraged in this repo due to scheduler and AsyncLocal-context hazards. Consider switching the process runner to an IObservable-based API or synchronous execution at the boundary.
            return await _runner.Exec(InImageBuilder, local, ct);

src/MeshWeaver.Cli/BuildProjectCommand.cs:110

  • Async/await in src: this await adds a continuation hop with the usual risks (parked schedulers; AsyncLocal AccessContext loss). Prefer reactive composition or keep this command’s logic synchronous and confine async to a dedicated boundary.
            ? await _runner.UseLocalImage(image, ct)

src/MeshWeaver.Cli/BuildProjectCommand.cs:111

  • This await introduces another Task-based continuation in src; in this repo that’s a frequent root cause of wedges and lost identity across thread hops. Consider making PullImage/UseLocalImage reactive or synchronous.
            : await _runner.PullImage(image, ct);

src/MeshWeaver.Cli/BuildProjectCommand.cs:113

  • This await adds async/await in src (output write). Even seemingly harmless awaits create continuation boundaries that can lose AsyncLocal state and are avoided in this repo’s core code paths. Prefer a reactive pipeline or synchronous writes here.
        await output.WriteLineAsync($"image: {pinned}");

src/MeshWeaver.Cli/BuildProjectCommand.cs:114

  • Async/await in src: this introduces a continuation boundary; this repository generally avoids awaits because of scheduler parking and AccessContext propagation risks. Consider keeping logging/output synchronous or moving async work behind IIoPool.
        await output.WriteLineAsync($"source root: {root} → /repo; project: /repo/{relative}");

src/MeshWeaver.Cli/BuildProjectCommand.cs:121

  • This await in src introduces Task-based continuation. In this repo, such continuations can lose AsyncLocal context and can deadlock when executed on turn-based schedulers. Prefer a reactive/synchronous IO surface.
                await error.WriteLineAsync(

src/MeshWeaver.Cli/BuildProjectCommand.cs:132

  • Awaiting RunInImage here introduces another async boundary in src. Repository guidance generally prefers IObservable composition (or a dedicated async boundary like IIoPool) to avoid scheduler wedges and AsyncLocal context loss.
        var exit = await _runner.RunInImage(pinned, mounts, [], builderArgs, ct);

src/MeshWeaver.Cli/BuildProjectCommand.cs:134

  • This await adds async/await in src for console output; in this repo, awaits are avoided in core code paths due to continuation/context hazards. Consider making this path synchronous or moving output streaming behind a reactive boundary.
            await output.WriteLineAsync($"assemblies: {outputDirectory}");

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

{
for (var attempt = 1; attempt <= PullAttempts; attempt++)
{
if (await Exec("docker", ["pull", image], ct) == 0)
var entry = Path.GetFullPath(options.ProjectPath);
if (!File.Exists(entry) && !Directory.Exists(entry))
{
await error.WriteLineAsync($"error: '{entry}' is neither a project file nor a directory.");
@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

792 tests  ±0   788 ✅ ±0   4m 13s ⏱️ -3s
  7 suites ±0     4 💤 ±0 
  7 files   ±0     0 ❌ ±0 

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 002 tests  +51   1 002 ✅ +51   4m 25s ⏱️ -55s
    7 suites ± 0       0 💤 ± 0 
    7 files   ± 0       0 ❌ ± 0 

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 145 tests  +60   1 144 ✅ +59   5m 7s ⏱️ -14s
    7 suites ± 0       0 💤 ± 0 
    7 files   ± 0       1 ❌ + 1 

For more details on these failures, see this check.

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    8 files  ± 0      8 suites  ±0   4m 23s ⏱️ - 1m 35s
1 481 tests  - 52  1 480 ✅  - 52  1 💤 ±0  0 ❌ ±0 
2 174 runs   - 52  2 173 ✅  - 52  1 💤 ±0  0 ❌ ±0 

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

3 025 tests  ±0   2 833 ✅ ±0   5m 55s ⏱️ -3s
    8 suites ±0     192 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

1 181 tests  ±0   1 181 ✅ ±0   7m 44s ⏱️ -17s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   44 files  ± 0     44 suites  ±0   31m 50s ⏱️ - 3m 7s
8 626 tests +59  8 428 ✅ +58  197 💤 ±0  1 ❌ +1 
9 319 runs  +59  9 121 ✅ +58  197 💤 ±0  1 ❌ +1 

For more details on these failures, see this check.

Results for commit 40e832e. ± Comparison against base commit 0ebc13b.

♻️ This comment has been updated with latest results.

@rbuergi
rbuergi force-pushed the integration/core-batch branch from ba8f06a to 40e832e Compare August 31, 2026 00:01
@rbuergi rbuergi changed the title chore: land the core batch as one merge — five green PRs, one queue cycle chore: land the core batch as one merge — four green PRs, one queue cycle Aug 31, 2026
@rbuergi

rbuergi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Superseded — three of the four members landed individually, so the batch no longer saves a cycle

This existed to spend one queue cycle instead of four. That rationale is gone:

member state
#2848 docs: the fleet test shape MERGED
#2849 the install no longer waits 30 s MERGED
#2852 a FATAL is never silent MERGED
#2850 memex build project still open

Only #2850 remains, so there is nothing left to batch — and keeping this open is actively risky rather than merely redundant. It is DIRTY, so it runs no CI at all, and its branch now carries three commits whose content is already on main. A branch holding an already-merged commit reads CLEAN on the PR page and comes back UNMERGEABLE from the queue, because the speculative merge sees that content arriving twice — which is a confusing hour to spend for no benefit.

#2850 should land on its own. It is DIRTY too and needs its conflicts with main resolved before it runs any CI; I am looking at that next.

Closing rather than deleting the analysis: the RCA in the body — why #2842 was removed from this batch, and the four-part interlock behind CompileFinishAndDisposeTest — is worth keeping readable, and #2842 is now rebased onto a main that carries #2859, which is the fix that interlock depended on.

@rbuergi rbuergi closed this Aug 31, 2026
auto-merge was automatically disabled August 31, 2026 05:56

Pull request was closed

rbuergi added a commit that referenced this pull request Aug 31, 2026
…d CLI conflict as #2850

This PR was DIRTY, so it was running no CI at all.

Its branch is built on integration/core-batch (#2853), so it carries #2850's
ImageRunner extraction and hit the identical conflict in
src/MeshWeaver.Cli/BuildPluginCommand.cs — one 159-line block with an empty
"ours" side, holding TWO unrelated things:

  * PullImage, which this history relocated to src/MeshWeaver.Cli/ImageRunner.cs;
  * main's ComposeSealedModules (#2851, #2858), which is genuinely new.

"Take theirs" duplicates PullImage; "take ours" silently deletes main's method.
Split at the seam instead: dropped 39 lines (relocated), kept 120 (main's new).
Then the same two follow-ons the compiler names — ImageRunner.Capture is static
so main's auto-merged call needed qualifying, and the split orphaned PullImage's
`/// <summary>` opener (CS1570).

🚨 Verified neither side was lost, not just that it builds:
    ComposeSealedModules/StageModuleBundle present   5 references
    PullImage defined once — ImageRunner 1, BuildPluginCommand 0

    MeshWeaver.Cli / PluginTester / PluginTester.Test  -c Release -warnaserror, 0/0
    MeshWeaver.PluginTester.Test                       229/229

Note #2853 is now closed — three of its four members landed individually — so
this branch's core-batch ancestry is history rather than a live dependency.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rbuergi added a commit that referenced this pull request Aug 31, 2026
…ompat red was a BASE artefact

This PR was DIRTY (no CI at all) and additionally red on
"Public surface (binary compatibility)". Both are addressed by merging main.

── the conflict (same as #2850/#2860) ──
One 159-line block in src/MeshWeaver.Cli/BuildPluginCommand.cs holding TWO
unrelated things: PullImage (relocated to ImageRunner.cs by this lane) and main's
new ComposeSealedModules (#2851, #2858). Split at the seam — dropped 39 lines
relocated, kept 120 of main's — then qualified ImageRunner.Capture (now static)
and removed the `/// <summary>` opener the split orphaned.

── the binary-compat failure was measured against the WRONG BASE ──
The gate said:

    Comparing against merge base ... branch integration/core-batch
    ✗ tools/MeshWeaver.PluginTester/ProjectFile.cs
        record Model — arity: primary constructor went from 21 to 22 parameter(s)
    🚨 1 binary-breaking record change(s)

That is a correct verdict about the wrong comparison. `ProjectFile.cs` DOES NOT
EXIST ON MAIN — the Model record is introduced by #2850's lane, and the gate was
comparing against integration/core-batch (#2853), where it existed at arity 21.
Against main the record is NEW, so there is no prior signature to break.

Not suppressed and NOT added to scripts/record-signatures.allow: an allow entry
would assert a deliberate break where there is none, and would then go stale the
moment #2850 lands (the shape that has blocked unrelated PRs before). Re-basing
onto main is the fix; the gate re-runs against main and should now pass on its
own. If it does not, the break is real and belongs in the allow file with a
reason — but that is not what this data shows.

    MeshWeaver.PluginTester / .Test   -c Release -warnaserror, 0 Warning(s) 0 Error(s)
    MeshWeaver.PluginTester.Test      198/198

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