From 426725da78ccf75acb7ee961465b0ab5ec22cd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20B=C3=BCrgi?= Date: Thu, 27 Aug 2026 00:13:38 +0200 Subject: [PATCH] =?UTF-8?q?Node=20repos=20stop=20baking=20through=20a=20me?= =?UTF-8?q?sh=20=E2=80=94=20compiler=20produces,=20mesh=20consumes=20(#206?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every node repo (Plugins, Education, Reinsurance, SocialMedia) reaches its bake through this reusable lane, and it was the one caller still on the FUSED shape: mw-plugin-test /repo --bake-output /bake # the MESH compiles every NodeType #2064 split the platform's own two lanes — dotnet-test.yml's PR lane and main-cd.yml's publish-bake — into `compile … --output` then `… --seed`, and held the pair in bake-then-gate.sh precisely so the two could not drift. This lane drifted: it was never converted, so the satellite repos kept producing their bundles with a mesh. Producing an assembly is a BUILD step. The fused form activates hubs to manufacture bytes nothing has adopted yet, which is where it crashes — and a crash here is expensive twice over, because this lane runs in four repos that share one 60-job concurrency pool with the platform. The split is also strictly stronger AS A GATE, for the reason bake-then-gate.sh already records: fused, the mesh rendered and ran `Tests` against a PRIVATE recompile — bytes nothing ever ships. Seeded, it exercises the very assemblies this lane then publishes, which are the ones a portal adopts. Behaviour otherwise unchanged: same image, same /repo mount (the synced git), same module narrowing, same `--allow`, same `--init` (a crash must exit 134 rather than spin at 100% CPU as an unkillable PID 1, #1741), and the same framework-mvid.txt postcondition after. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/node-repo-publish-bake.yml | 26 +++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/node-repo-publish-bake.yml b/.github/workflows/node-repo-publish-bake.yml index 80f1c02ca8..8f1181aa18 100644 --- a/.github/workflows/node-repo-publish-bake.yml +++ b/.github/workflows/node-repo-publish-bake.yml @@ -7,7 +7,9 @@ name: Node repo publish-bake (reusable) # chances for silent drift. This workflow runs the canonical script from THIS repo (checked out # by ref), so the sentinel contract has exactly one home next to the C# constant it mirrors. # -# What it does: run the caller repo's full content through mw-plugin-test with `--bake-output` +# What it does: run the caller repo's full content through mw-plugin-test as the #2064 SPLIT — +# `compile … --output` (the compiler produces the bake; no mesh) then `… --seed` (a mesh consumes +# and gates the produced bytes). Never the fused `--bake-output`, which makes the MESH the producer # (the run IS a full gate — import + compile + render + Tests areas), then publish the resulting # bundles to every portal storage target under # `/prebuilt-bundles///`. A portal whose own framework @@ -533,7 +535,7 @@ jobs: - name: Pre-bake hook if: inputs.pre-bake-script != '' run: ${{ inputs.pre-bake-script }} - - name: Bake (import + compile + render + tests, --bake-output) + - name: Bake (compiler --output), then gate a mesh against it (--seed) # scope=none means the decision above VERIFIED that this exact content is already sealed # for this framework identity at every target — a positive finding, logged with both # shas, not an input-shaped skip. Everything downstream is skipped with it. @@ -594,10 +596,28 @@ jobs: # tester cannot be killed by the SIGABRT its own runtime raises on a crash — the kernel # discards the signal (SIGNAL_UNKILLABLE) and the process spins at 100% CPU instead of # exiting. Under tini it is PID 2 and a crash exits 134 at once. + # ══ 1. THE BAKE — compiler-driven, NO MESH ANYWHERE IN IT (#2064) ══════════════════ + # 🚨 This used to be ONE fused run: `… /repo --bake-output /bake`, which stood up an + # in-process mesh and let the MESH compile every NodeType. Producing an assembly is a + # BUILD step; the mesh's job is to CONSUME a bake, not to be the thing that makes one. + # The fused shape also activates hubs to produce bytes nothing has adopted yet, which is + # where it crashes. #2064 split the platform's own two lanes (dotnet-test.yml's PR lane + # and main-cd.yml's publish-bake) and held the pair in bake-then-gate.sh so they could + # not drift — this reusable lane was the one caller left on the old shape, so every node + # repo (Plugins, Education, Reinsurance, SocialMedia) still baked through a mesh. + docker run --rm --init -v "$REPO_MOUNT:/repo" -v "$BAKE:/bake" \ + --entrypoint /app/mw-plugin-test "${{ steps.image.outputs.ref }}" compile /repo \ + "${ALLOW_ARGS[@]}" \ + --output /bake --source-sha "$GITHUB_SHA" + + # ══ 2. THE GATE — a mesh, CONSUMING the bake above ═════════════════════════════════ + # Strictly stronger than the fused form as a gate: fused, the mesh rendered and ran + # `Tests` against a PRIVATE recompile — bytes nothing ever ships. Seeded, it exercises + # the very assemblies this lane is about to publish, which are the ones a portal adopts. docker run --rm --init -v "$REPO_MOUNT:/repo" -v "$BAKE:/bake" \ --entrypoint /app/mw-plugin-test "${{ steps.image.outputs.ref }}" /repo \ "${ALLOW_ARGS[@]}" \ - --bake-output /bake --source-sha "$GITHUB_SHA" + --seed /bake # Postcondition, not a hope: a green tester that wrote no identity is a bake-stage # regression (or an image predating --bake-output support). if [ ! -s "$BAKE/framework-mvid.txt" ]; then