Repository navigation
Module build ledger: content-addressed module builds coordinated through memex (Plugins#889, #931) - #3135
Conversation
… Plugins#889) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj
…lable; lane: select + build-workspace wiring (WIP) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj
…se leg, guard, docs, What's New (Plugins#889, #931) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj
Test Results (shard 3)340 tests 338 ✅ 42s ⏱️ Results for commit aba6447. |
Test Results (shard 0)234 tests 234 ✅ 2m 2s ⏱️ Results for commit aba6447. |
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a new cross-run CI coordination protocol (ledger + artifact reuse) and significant reusable-workflow logic changes that warrant careful human validation despite no single blocking defect found.
Pull request overview
Introduces a content-addressed “module build ledger” to coordinate reusable module builds across runs (and avoid rebuilding identical module bytes), with the ledger persisted as mesh nodes on the registry portal and integrated into the node-repo-module-pack reusable workflow.
Changes:
- Adds
ModuleBuildRecord(plus supporting types) and registers a new built-inModuleBuildNodeType rooted atAdmin/ModuleBuilds. - Extends the reusable module-pack workflow to (optionally) key selections, consult the ledger, reuse prior run artifacts, and record build/test/publish transitions.
- Adds lane-guard tests and documentation/What’s New updates describing the as-built protocol and adoption.
File summaries
| File | Description |
|---|---|
| test/MeshWeaver.Documentation.Test/ModuleBuildLedgerLaneGuard.cs | Guard test ensuring the reusable workflow wiring and transition ordering can’t silently drift. |
| src/MeshWeaver.Graph/Configuration/ModuleBuildNodeType.cs | Adds the built-in ModuleBuild NodeType definition and hub type registrations for ledger payloads. |
| src/MeshWeaver.Graph/Configuration/GraphConfigurationExtensions.cs | Registers the new ModuleBuild NodeType in graph setup. |
| src/MeshWeaver.Graph.Contract/ModuleBuildRecord.cs | Defines the ledger record schema (ModuleBuildRecord, status enum, run/artifact/tests records). |
| src/MeshWeaver.Documentation/Data/WhatsNew/2026-09-02-a-module-built-once-is-not-built-again.md | What’s New entry announcing the user-visible behavior change. |
| src/MeshWeaver.Documentation/Data/Architecture/ModuleVersioning.md | Updates versioning docs to describe ledger-backed reuse on push runs. |
| src/MeshWeaver.Documentation/Data/Architecture/ModuleBuildArchitecture.md | Rewrites the “content-addressed outputs” section into the as-built ledger/key/protocol contract. |
| .github/workflows/node-repo-module-pack.yml | Adds ledger input + secret, consult/reuse/record logic, and feeds build-modules into the workspace build. |
| .github/scripts/node-repo-scope.py | Updates push-scope rationale to reflect ledger-based reuse of already-published keys. |
| .github/scripts/module-build-ledger.py | Implements ledger coordination + MCP read/write protocol and self-tests. |
| .github/scripts/module-build-key.py | Implements deterministic build key computation over the compiled+tested closure + global inputs + platform/tester identity. |
Review details
- Files reviewed: 11/11 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Test Results (shard 5) 4 files 4 suites 1m 32s ⏱️ Results for commit aba6447. |
Test Results (shard 1)437 tests 437 ✅ 1m 2s ⏱️ Results for commit aba6447. |
Test Results (shard 2)576 tests 384 ✅ 2m 36s ⏱️ Results for commit aba6447. |
Test Results (shard 4)2 133 tests 2 133 ✅ 2m 20s ⏱️ Results for commit aba6447. |
Test Results 15 files 15 suites 10m 16s ⏱️ Results for commit aba6447. |
Closes Systemorph/MeshWeaver.Plugins#889. Producer half of Systemorph/MeshWeaver.Plugins#931 (the consumer half — comparing the recorded platform identity in
ModuleUpdateDecision— is a separate PR).Maintainer directive (2026-09-02): "we should not start the same build multiple times ⇒ coordinate which packages are in progress; track progress through memex. Build and test only when we have to: if Plugin X was built against Platform version Y, we don't have to rebuild this."
What lands
A content address per module build —
.github/scripts/module-build-key.py(self-tested, 36 cases: determinism, every input flips the key, noise does not, two refusals).K = sha256(package, manifest.lock moduleVersion, tree hashes of the in-repo compiled+tested closure, reached packages' moduleVersions, repo-level build inputs, tester digest, platform digest, platform-ref, recipe version).A ledger on the registry portal —
.github/scripts/module-build-ledger.py(self-tested against an in-process fake MCP server, 35 cases). One node per key atAdmin/ModuleBuilds/<K>(nodeTypeModuleBuild, contentModuleBuildRecord— shipped in the framework,src/MeshWeaver.Graph.Contract/ModuleBuildRecord.cs+src/MeshWeaver.Graph/Configuration/ModuleBuildNodeType.cs), written over MCP JSON-RPC at/mcpwith amw_ApiToken of a CI user holding a partition-admin grant on that root. Claim = create-if-absent (the mutex; "already exists" is the follower's success), heartbeat staleness = the 45-min job cap, reuse = download the recorded run's bundle artifact (sha256-verified) and run only the missing phases, wait = poll 30 s on a live holder, tolerance = compile failures block, test failures block from the 2nd attempt, nothing else blocks. The registry being unavailable never reds a build: the lane builds without coordination and says so in yellow (core #3119).Lane (
node-repo-module-pack.yml): new inputledger: off|required(defaultoff= today's behaviour, printed every run;requiredasserts theledger-tokensecret RED),selectkeys + consults,build-workspacecompiles the ledger'sbuild-modulessubset and feeds its postcondition the same list,prepareresolves the PORTAL's framework identity (tester'sframework-identity /appunder the platform image's dotnet),packgains a reuse leg and records Built (after the artifact upload) / Tested (after the suite, from the trx) / Published (after the hand-over) / Failed (phase from step outcomes) / released (cancelled) / finished. Bundle artifact retention 3 → 7 days (the reuse window). Every job ≤ 45 min (gate green).Guard:
test/MeshWeaver.Documentation.Test/ModuleBuildLedgerLaneGuard.cspins the flag + token, the self-tests, the single enumerator, the three transitions in order gated on step outcomes, the two verdict steps, the reuse verification.Docs:
ModuleBuildArchitecture.md"Content-addressed outputs" rewritten from roadmap to as-built (key, ledger, protocol, whyAdmin/ModuleBuildsnotAdmin/Build, why run artifacts not the branch-scoped actions cache, what a satellite passes);ModuleVersioning.mdpush row; What's NewCategory: Feature.Deviations from the brief, and why
actions/cachemodule-bundle-<K>: the actions cache is branch-scoped, so a bundle cached by a PR run is invisible to the push-to-main run — the one flow that matters most. Artifacts are repo-wide (7-day retention); the caller needspermissions: actions: readfor reuse, otherwiseselectsees the 403 and builds, loudly.Admin/ModuleBuilds, notBuild/Modules: the bake'sAdmin/Buildroot has an arbiter over its children; the ledger is a different protocol. Admin partition kept so the subject cannot write the decision; the CI user is a partition admin on exactly that root, never a global admin.ledgerdefaults tooff: the token cannot be provisioned from a PR (amw_token must be minted on memex.meshweaver.cloud by an admin), and a required-by-default flag would red every satellite and the platform CD (main-cd.yml plugins-modules) at pin move. The summary says OFF on every run so the state cannot be mistaken for a consulted ledger.platformRefis in the key on purpose (dotnet testbuilds core from source at it). Satellites trackingMW_PLATFORM_REF: mainget a new key per core commit; pinning the ref to the promoted set is the lever, and is theirs.Build, so every registry portal has it with no content package and no cross-repo half.Verification
module-build-key.py --self-test36/36,module-build-ledger.py --self-test35/35,node-repo-scope.py --self-test44/44check-workflow-timeouts.py --root .0 violations;check-workflow-shell.py0 live findingsdotnet build src/MeshWeaver.Graph -c Release -warnaserrorandtest/MeshWeaver.Documentation.Test -c Release -warnaserror: 0 warnings, 0 errorsdotnet test test/MeshWeaver.Documentation.Test(whole project): see the CI runAdoption (per satellite; not in this PR)
Admin/ModuleBuilds, grant the CI user theAdminrole there withMainNode = "Admin/ModuleBuilds", mint that user amw_ApiToken → repo secretREGISTRY_LEDGER_TOKEN.ledger: required,secrets.ledger-token, andpermissions: actions: readon the calling job.🤖 Generated with Claude Code
Claude-Session: https://claude.ai/code/session_01G4xPnGYEbdu8AVvR5jytyj