Repository navigation
Conversation
… 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
There was a problem hiding this comment.
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 projectandmw-plugin-test build-projectto compile a.csprojagainst an image’s/appreference 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."); |
Test Results (shard 4)1 145 tests +60 1 144 ✅ +59 5m 7s ⏱️ -14s 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. |
Test Results 44 files ± 0 44 suites ±0 31m 50s ⏱️ - 3m 7s 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. |
…' into integration/core-batch
…tegration/core-batch
…into integration/core-batch
…egration/core-batch # Conflicts: # src/MeshWeaver.Cli/BuildPluginCommand.cs
ba8f06a to
40e832e
Compare
Superseded — three of the four members landed individually, so the batch no longer saves a cycleThis existed to spend one queue cycle instead of four. That rationale is gone:
Only #2850 remains, so there is nothing left to batch — and keeping this open is actively risky rather than merely redundant. It is #2850 should land on its own. It is Closing rather than deleting the analysis: the RCA in the body — why #2842 was removed from this batch, and the four-part interlock behind |
Pull request was closed
…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>
…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>
Batches four individually-green PRs into a single merge so they cost one queue cycle instead of four.
memex build project— compile a csproj against the container, no SDK, no NuGet🚨 #2842 was REMOVED from this batch — it is the cause, not a passenger
The first cut of this batch included #2842 and failed
CompileFinishAndDisposeTeston 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:DocumentationMode.Diagnosewas always on), so an undocumentedpublic recordyields CS1591s.FinishisMAX(floor, fold).Succeededwhileresult.Logcarries the foldedWarning.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'sComposeModulesFromSeed(now trunk content) and drops thePullImagethat #2850 moved into the newImageRunner.cs— verified the move had actually landed (ImageRunner.PullImageexists;BuildPluginCommandcalls_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 aCapturecall needing qualification toImageRunner.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