Plugin publication provenance
A successful plugin publication calls the existing signed Memex inbox at
/api/hooks/Hosting/PlatformBuilds. The record must identify the content that was built.
Core CD can invoke the same publisher for Systemorph/MeshWeaver.Plugins, so the calling
workflow's commit is not necessarily a commit in the repository named by the record.
node-repo-publish-bake.yml now passes the resolved content checkout SHA from its existing
content step through the job output into the notification. This is the same SHA passed to
the bake and publication scripts. It does not substitute github.sha, a branch name, or the
workflow's own checkout when the output is absent.
The record's version describes the build platform, not a package's SemVer. It is read
from MESHWEAVER_PLATFORM_VERSION in the selected, already-pulled portal image configuration,
the same source a running portal uses. Pushes and core CD calls have this fact even when
github.event.client_payload.version is absent. A package's own version and moduleVersion
remain its manifest.lock fields at the announced content commit.
| Record field | Source |
|---|---|
repo |
Explicit content-repository, otherwise the caller's repository |
sha |
git rev-parse HEAD after the content checkout, also supplied to the bake |
version |
The selected portal image's own MESHWEAVER_PLATFORM_VERSION |
identity |
Existing portal/tester framework identity agreement |
image, digest, platformImage |
Existing resolved tester and portal references; digest is the tester image digest, not a plugin content digest |
run |
The workflow repository and run URL, retained separately from content provenance |
upstreams |
The caller's existing normalized dependency declaration |
The version read refuses a missing, duplicated or malformed image configuration value.
"Malformed" means any shape the pipeline does not mint: accepted are exactly clean X.Y.Z,
X.Y.Z-ci.N, X.Y.Z-edge.N and the retired rc line's X.Y.Z-<label>.ci.N / .edge.N — the
set PlatformReleaseOrder.BuildOrdinal reads. A label no build mints (3.0.0-alpha,
3.0.0-preview.1, a bare 3.0.0-rc9) carries no build ordinal, so a receiver would order it as
a promotion; both the producer step and the POST refuse it with the same pattern. The
final POST independently refuses an absent/malformed 40-digit hexadecimal content SHA or
platform version. It retains the existing URL, HMAC secret, signed payload, HTTP failure
handling and signature-verdict check. It introduces no credential, alternate callback, direct
repository dispatch or new update permission.
Fleet audit, 11 September 2026
The organization's repository inventory, six current ci.yml callers and GitHub code search
(org:Systemorph node-repo-publish-bake filename:ci.yml, six results, not incomplete) identify
these active plugin publishers. All six already supply PLATFORM_WEBHOOK_URL and
PLATFORM_WEBHOOK_SECRET to the shared lane; all six repository variables point at
https://memex.meshweaver.cloud/api/hooks/Hosting/PlatformBuilds, and all six expose the secret's
metadata. The secret values were not read.
| Repository | Audited main | Source / upstream sources | Shared lane ref |
|---|---|---|---|
| MeshWeaver.Plugins | 05fde51007d97e5859682551b94027d190d3491b |
plugins / none |
main |
| MeshWeaver.Education | 67274a2f650f9dcad25a57fa8ad50fceda8634c0 |
education / plugins |
67cbbe0ee4467ac30f086587c97f62c7b0d13689 |
| MeshWeaver.Reinsurance | 17b161a9c2fe6ec50a9764c66bd2b332d7f27621 |
reinsurance / plugins crm |
main |
| MeshWeaver.SocialMedia | 3fa2cab318bf7442a17b83060e80031e09f2f961 |
socialmedia / plugins |
main |
| MeshWeaver.Manufacturing | 73e3da77131a1401af20a3545c2acf16ec0b9add |
manufacturing / plugins |
main |
| MeshWeaver.Crm | a55fec3abce3bc448afb45d48d83d856a334f749 |
crm / plugins |
main |
The publication jobs depend on each caller's validation set and run for default-branch pushes,
scheduled runs and repository dispatches. The shared notification remains downstream of a
successful bake publication with published=true; this change does not redefine a skipped or
already-sealed bake as a new publication. Education's pinned caller must adopt a revision
containing this correction through its normal reviewed workflow update.
The three readable Hosting/Deployment registrations are a separate inventory. The registry's
four GitHub source declarations name Plugins, Education (through the old education alias),
Reinsurance and Crm. SocialMedia and Manufacturing still belong in the publisher fleet despite
not appearing in those declarations. Memex is the deployment repository; agentic-pensions
has a Space root rather than a plugin catalog; MeshWeaver.Feedback is an empty triage
repository. They are not additional callers of this publication lane.
This audit establishes sender wiring, not successful delivery or adoption on every instance. Plugin Update on Green Build describes the receiver/update path. In particular, a tester digest alone cannot identify changed plugin content, and a registry's update policy is distinct from the existence of its callback.
Executed regression
At core baseline ac7617466088b3e43a2a90b893218e0cf21de481, the actual extracted POST step
sent a synthetic workflow SHA 111… when the content checkout was 222…. Both controls failed
at that payload assertion: core building Plugins, and a caller using a different explicit
content ref in its own repository. No network request was made: the fixture captures the
actual curl arguments and executes the real JSON construction and HMAC signing.
PluginPublicationProvenanceTest also executes the actual image-version step against supplied
Docker inspection results. The 20 cases cover both corrected payloads, missing/malformed
producer outputs before any POST, valid/missing/duplicate/malformed or unreadable image
configuration, and the exact job-output wiring. They passed with 52 related publication,
signature and embedded-document checks: 72 passed, zero failed or skipped. The strict
Documentation.Test build reported zero warnings/errors. Workflow shell checks and their
self-test, actionlint, YAML key checks (34 workflows), permission pairing (two callers) and
timeout checks (84 jobs) also passed.
The local before/after receipts are under
/private/tmp/plugin-publication-sender-receipt; they are supplementary. Reproduce the
committed assertions from a fresh build:
dotnet build test/MeshWeaver.Documentation.Test/MeshWeaver.Documentation.Test.csproj -c Release -warnaserror
dotnet test test/MeshWeaver.Documentation.Test/MeshWeaver.Documentation.Test.csproj -c Release --no-build --filter 'FullyQualifiedName~PluginPublicationProvenanceTest|FullyQualifiedName~UpstreamBuildGateGuard|FullyQualifiedName~InboxSignatureVerdictGuard|FullyQualifiedName~PlatformReleaseNotifyGuard|FullyQualifiedName~PlatformBakeLaneGuard|FullyQualifiedName~WhatsNewEntryIntegrityTest|FullyQualifiedName~DocumentationEmbedIntegrityTest'
No live notifier, release workflow, registry registration or adoption was changed to execute these tests. Production delivery requires the normal reviewed shared-lane release and a subsequent successful publication using it.