NEO evidence rail · Platform Mesh marketplace × Cotrugli

One subscription on the Platform Mesh marketplace, end to end — the events each party records, with sample data

An illustrative flow based on the Platform Mesh showroom — a provider publishes an API through kcp, a subscriber binds to it and orders a capability — written down as the business facts each of the three parties records at each step. The 32 synthetic sample events below were replayed into four NEO edge instances in our lab. They were not captured from a SAP installation.

historical replay: 1 October 2026 · kcp APIExport / APIBinding · the showroom's Private LLM and Chat UI providers
Illustrative replay · recorded at four edge instances · not sealed

The existing sample files are preserved. For complete teardown, failed provisioning and metering differences, use the extended lifecycle explorer. Its 30 new fixture events are separate from this 32-event historical run.

Sample objects are illustrative, not deployable manifests. They contain synthetic identifiers, abbreviated hashes and selected status fields. Use the pinned upstream showroom installation for runnable resources.

Technical events and business meaning

kcp holds technical resource facts: an APIExport makes an API available; an APIBinding enables access in a workspace; an instance expresses a request and Ready reports resource readiness. Commercial terms, delivery acceptance and billing are separate business records. Each party records every fact it took part in, in its own book at its own site — and a fact with two parties leaves two records that carry the same digest. In a connected deployment, each nonempty period produces a 32-byte commitment payload. A verifier needs the disclosed record and its independently verified inclusion proof to compare statements without opening the entire book. This historical replay did not include a real rail.

The four laboratory roles

Platform provider

the Platform Mesh operator

root

Proposed collection point: kcp's API-server audit backend (a webhook) → an adapter → the audit SDK.

Service provider A

Private LLM

root:providers:private-llm

Proposed collection point: the provider's operator emits at each reconcile outcome (the audit SDK).

Service provider B

Chat UI

root:providers:chat-ui

Proposed collection point: the provider's operator emits at each reconcile outcome (the audit SDK).

Subscriber

org demo, account tutorial

root:orgs:demo:tutorial

Proposed collection point: a read-only watcher in the subscriber's own workspace (its bindings and instances).

The objects and names are the showroom's (the local Platform Mesh MSP demo): the exports llm.privatellms.msp and ui.privatellms.msp, the org demo with the account tutorial, the bindings llm-binding and chat-ui-binding. Uids, cluster names and identity hashes are sample values.

The flow — eight steps, and who records what

step · what happens in kcpservice provider's bookplatform provider's booksubscriber's book
1 · A service is publishedThe provider's API becomes an offering: its schemas and an APIExport in the provider's workspace; kcp gives the export its identity.APIResourceSchema, APIExport (provider workspace)audit.service.publish (Private LLM)audit.service.publish (Chat UI)audit.catalog.listaudit.catalog.list—
2 · A subscriber joinsAn organisation and an account are created; the account is a workspace of its own.Account ×2 → workspace root:orgs:demo:tutorial—audit.account.createaudit.account.createaudit.account.create
3 · The subscriptionThe subscriber binds to the export and accepts the provider's permission claims; kcp authorises the bind and marks the binding Bound. This is technical API access; commercial terms require a separate agreement.APIBinding llm-binding (subscriber workspace)audit.contract.agreement (Private LLM)audit.door.decisionaudit.contract.agreement
4 · A capability is orderedThe subscriber creates an instance of the bound API; the provider's operator provisions it on the provider's own cluster and reports Ready.LLMInstance demo-llmaudit.workload.start (Private LLM)audit.door.decisionaudit.instance.create
5 · A credential is issuedThe subscriber asks for a token; the provider writes a Secret into the subscriber's workspace under the accepted claim.APITokenRequest → Secret demo-llm-token-tokenaudit.token.issue (Private LLM)audit.claim.useaudit.token.request
6 · A second provider joins the chainThe subscriber binds to the Chat UI export and orders a chat front-end that uses the first provider's credential; the second provider reads that Secret under its own claim.APIBinding chat-ui-binding, ChatUIInstance demo-chataudit.contract.agreement (Chat UI)audit.workload.start (Chat UI)audit.door.decisionaudit.claim.useaudit.contract.agreementaudit.chatui.create
7 · A day of operationThe provider measures what it delivered; the subscriber measures what it received; the subscriber scales the instance.LLMInstance replicas 1 → 2; the day's SLA and usageaudit.workload.scale (Private LLM)audit.contract.sla (Private LLM)—audit.instance.scaleaudit.contract.sla
8 · The endThe instance is deleted, the binding removed, and each side states the week from its own records.delete LLMInstance, delete APIBindingaudit.workload.end (Private LLM)audit.contract.end (Private LLM)audit.contract.week (Private LLM)—audit.instance.deleteaudit.contract.endaudit.contract.week

Highlighted: the records that carry the subscription's digest — the same 32 bytes in the three books. The event names follow the audit-logging signal's form (audit.*, with the actor, the action, the outcome and the target as attributes). Six of them have their own code at the edge today (audit.contract.agreement, audit.door.decision, audit.workload.start / .end, audit.contract.sla, audit.contract.week); the others are filed as general audit events — their names are local proposed conventions, not a claim of standardised KCP business events.

One technical subscription snapshot — one digest, three books

When the binding becomes Bound, both sides see the same facts in kcp: the export and its identity, the subscriber's workspace, the claims it accepted, the resources bound. Written in one canonical form, their SHA-256 is the 32 bytes each party's record carries.

{
 "kind": "platform-mesh.subscription.v1",
 "export": {"path": "root:providers:private-llm", "name": "llm.privatellms.msp", "identityHash": "6aedce73259b9202790d4f502a37577673d4e7f830fe22782e1a277e99eb3ea0"},
 "consumer": {"workspace": "root:orgs:demo:tutorial", "cluster": "5t8r3p1y6u2i7o4w"},
 "binding": {"name": "llm-binding", "uid": "36adc41e-a627-5047-9bdd-5ec8ca6f6904"},
 "permissionClaims": [
  {"group": "", "resource": "secrets", "verbs": ["*"], "selector": {"matchAll": true}, "state": "Accepted"},
  {"group": "", "resource": "namespaces", "verbs": ["*"], "selector": {"matchAll": true}, "state": "Accepted"},
  {"group": "", "resource": "events", "verbs": ["*"], "selector": {"matchAll": true}, "state": "Accepted"}
 ],
 "boundResources": [
  {"group": "llm.privatellms.msp", "resource": "llminstances", "schema": "v1a2b3c4d.llminstances.llm.privatellms.msp"},
  {"group": "llm.privatellms.msp", "resource": "apitokenrequests", "schema": "v1a2b3c4d.apitokenrequests.llm.privatellms.msp"}
 ],
 "boundAt": "2026-09-30T09:03:12Z"
}

sha256(canonical form) = 66ba9ca6470b7f3566447b84cf13a3599cd61570f15f0fc0efbf736466c49e41
bookeventactorrecord idbooked asrecord hash
Subscriberaudit.contract.agreementuser:tutorial@example.combinding:36adc41e-a627-5047-9bdd-5ec8ca6f6904record 2, code 2181b9e4627ac35e4e…
Platform provideraudit.door.decisionsystem:kcp:authorizerbinding:36adc41e-a627-5047-9bdd-5ec8ca6f6904:admitrecord 5, code 20709ce5932a7263c3…
Service provider Aaudit.contract.agreementsystem:private-llm:controllerbinding:36adc41e-a627-5047-9bdd-5ec8ca6f6904record 2, code 21a8fb2e69280093f0…

Three generated records carry the same technical subscription digest. This replay checks local recording and digest consistency; it does not demonstrate source authentication or rail finality. In a connected installation, source signatures and verified inclusion proofs support comparison of the disclosed records. Matching digests establish matching content, not truthful metering, commercial acceptance or a dispute ruling. Later events refer to the subscription digest; a separate signed terms document supplies the business agreement.

Proposed collection points for a future installation

  • The platform provider — kcp's own audit. kcp is a Kubernetes API server: its audit backend already sees every create, update and delete with the user, the verb, the resource and the logical cluster. A webhook backend hands the selected ones — apiexports, apibindings, accounts, the providers' resources, the claimed secrets — to a small adapter that emits them through the audit SDK.
  • A service provider — its operator. The operator knows the moments that matter to the business: provisioned, token issued, scaled, failed, deprovisioned. One emit call of the audit SDK at each reconcile outcome; the sync agent and the operator's logic stay as they are.
  • A subscriber — a watcher in its own workspace. A read-only kubeconfig for its workspace is enough to record its bindings and instances as they are created, become Ready and are deleted; later the portal can emit on the subscriber's behalf.
  • Behind every tap, the same two pieces. ApeiroRA's audit collector in strict mode (source-signed records only) and the edge beside it: the book on the party's own disk, 128 bytes a record plus the original, one 32-byte commitment a minute to the rail, the proof of every minute back in the party's kit.

The commitment payload is 32 bytes; the existing light33 message adds one flag byte. Transport, retries and proof traffic are additional. A collection adapter must preserve actor identity and exclude Secret values. These taps were not exercised by this replay.

Booked in the lab — what each edge kept, what left

Platform provider · the Platform Mesh operator9 records1,152 bytes of book, 4,382 bytes of originals.
Commitment captured by the lab door double:
37790d2bd518c393de5d53a85138d82a75e02687ddcbbef04134d192d4bd757d
Service provider A · Private LLM9 records1,152 bytes of book, 4,884 bytes of originals.
Commitment captured by the lab door double:
91fe2567ef3657f6d007e70fc374e289c86a299fa0b6eb0b437f45b0a2fc72b5
Service provider B · Chat UI3 records384 bytes of book, 1,643 bytes of originals.
Commitment captured by the lab door double:
745c77fa8b07b201a2376cf2bdc758dfd701feabdfd234cfa6265bf5efee1b0e
Subscriber · org demo, account tutorial11 records1,408 bytes of book, 5,781 bytes of originals.
Commitment captured by the lab door double:
85f54e6d8db4081b500b01a6dcbffe053abcc0d050168d260a4c3d022e7ea54d

The 32 events of this page were sent to four NEO edges in our lab on 2026-10-01 14:13:05 UTC (one edge per party, the edge core of the pilot). Every record's hash at the edge is the one computed from the event beforehand (all 32 as predicted); each edge closed its minute and offered one commitment to a test double; a retry of the first event was answered 200 and made no second record. The lab had no real rail behind it; these commitments are not sealed. Event timestamps span 30 September to 7 October, but all events were replayed on 1 October. This is not a week-long run. No end-to-end finality latency is established by this replay.

Sample data

The kcp objects of the flow

In root:providers:private-llm — Service provider A:

apiVersion: apis.kcp.io/v1alpha2
kind: APIExport
metadata:
  name: llm.privatellms.msp
spec:
  resources:
  - {group: llm.privatellms.msp, name: llminstances,     schema: v1a2b3c4d.llminstances.llm.privatellms.msp,     storage: {crd: {}}}
  - {group: llm.privatellms.msp, name: apitokenrequests, schema: v1a2b3c4d.apitokenrequests.llm.privatellms.msp, storage: {crd: {}}}
  permissionClaims:
  - {group: "", resource: secrets,    verbs: ["*"]}
  - {group: "", resource: namespaces, verbs: ["*"]}
  - {group: "", resource: events,     verbs: ["*"]}
status:
  identityHash: 6aedce73259b9202790d4f502a37577673d4e7f830fe22782e1a277e99eb3ea0

In root:orgs and root:orgs:demo — Platform provider / the subscriber:

apiVersion: core.platform-mesh.io/v1alpha1
kind: Account
metadata:
  name: demo
spec:
  type: org
  displayName: Demo Org
---
apiVersion: core.platform-mesh.io/v1alpha1
kind: Account
metadata:
  name: tutorial
spec:
  type: account
  displayName: Tutorial Account

In root:orgs:demo:tutorial — Subscriber:

apiVersion: apis.kcp.io/v1alpha2
kind: APIBinding
metadata:
  name: llm-binding
  uid: 36adc41e-a627-5047-9bdd-5ec8ca6f6904
spec:
  reference:
    export:
      path: root:providers:private-llm
      name: llm.privatellms.msp
  permissionClaims:
  - {group: "", resource: secrets,    verbs: ["*"], selector: {matchAll: true}, state: Accepted}
  - {group: "", resource: namespaces, verbs: ["*"], selector: {matchAll: true}, state: Accepted}
  - {group: "", resource: events,     verbs: ["*"], selector: {matchAll: true}, state: Accepted}
status:
  phase: Bound
  boundResources:
  - {group: llm.privatellms.msp, resource: llminstances,     schema: {name: v1a2b3c4d.llminstances.llm.privatellms.msp,     identityHash: 6aedce73259b9202…}}
  - {group: llm.privatellms.msp, resource: apitokenrequests, schema: {name: v1a2b3c4d.apitokenrequests.llm.privatellms.msp, identityHash: 6aedce73259b9202…}}

In root:orgs:demo:tutorial — Subscriber:

apiVersion: llm.privatellms.msp/v1alpha1
kind: LLMInstance
metadata:
  name: demo-llm
  namespace: default
  uid: 7e2d83de-e0f5-5874-9510-ce2f1ce6edb0
spec:
  model: gemma-3-1b-it
  replicas: 1
status:
  conditions:
  - {type: Ready, status: "True"}

In root:orgs:demo:tutorial — Subscriber:

apiVersion: llm.privatellms.msp/v1alpha1
kind: APITokenRequest
metadata:
  name: demo-llm-token
  namespace: default
  uid: 9bbe05b5-ffc8-5367-9923-f209cff1c2c2
spec:
  instanceName: demo-llm
  description: Chat UI access token

In root:orgs:demo:tutorial — Subscriber:

apiVersion: ui.privatellms.msp/v1alpha1
kind: ChatUIInstance
metadata:
  name: demo-chat
  namespace: default
  uid: eb3cc4a8-cdcc-5a20-96ec-ad64c5461e47
spec:
  credentialsSecretRef:
    name: demo-llm-token-token
One event in full — the subscriber's record of the subscription
{
 "resource": {
  "neo.provider.id": "demo-tutorial"
 },
 "event_name": "audit.contract.agreement",
 "time": "2026-09-30T09:03:12Z",
 "attributes": {
  "audit.record.id": "binding:36adc41e-a627-5047-9bdd-5ec8ca6f6904",
  "audit.actor.id": "user:tutorial@example.com",
  "audit.actor.type": "user",
  "audit.action": "BIND",
  "audit.outcome": "success",
  "audit.target.id": "apis.kcp.io/APIExport:root:providers:private-llm/llm.privatellms.msp",
  "neo.country": "DE",
  "kcp.workspace": "root:orgs:demo:tutorial",
  "kcp.binding": "llm-binding",
  "neo.agreement.digest": "66ba9ca6470b7f3566447b84cf13a3599cd61570f15f0fc0efbf736466c49e41",
  "neo.market.role": "subscriber"
 },
 "body": {
  "sha256_of": "D1",
  "bytes_hex": "66ba9ca6470b7f3566447b84cf13a3599cd61570f15f0fc0efbf736466c49e41"
 }
}

The record's body is the 32-byte digest of the agreement; the attributes are the audit signal's (who, what, on what, with what outcome) plus the kcp coordinates. At the edge it became record 2 of the subscriber's book, event code 21, hash 81b9e4627ac35e4e03b24f53da302d1c5f0e18c76e9441c98ecca04849735972.

All 32 events
steptime (UTC)bookeventactoractiontargetrecord at the edge
109-30 08:40Private LLMaudit.service.publishserviceaccount:private-llm-pmPUBLISHprivate-llm/llm.privatellms.msp#1 · 6e5d4201f588…
109-30 08:40the Platform Mesh operatoraudit.catalog.listsystem:platform-mesh:marketplaceCREATEprivate-llm/llm.privatellms.msp#1 · eeee6f55985d…
109-30 08:44Chat UIaudit.service.publishserviceaccount:chat-ui-pmPUBLISHchat-ui/ui.privatellms.msp#1 · b849214efe3e…
109-30 08:44the Platform Mesh operatoraudit.catalog.listsystem:platform-mesh:marketplaceCREATEchat-ui/ui.privatellms.msp#2 · b0126e45c90c…
209-30 08:58the Platform Mesh operatoraudit.account.createuser:platform-admin@example.comCREATEorgs/demo#3 · b9b4636716ee…
209-30 09:00the Platform Mesh operatoraudit.account.createuser:tutorial@example.comCREATEdemo/tutorial#4 · 0f776f15292f…
209-30 09:00org demo, account tutorialaudit.account.createuser:tutorial@example.comCREATEdemo/tutorial#1 · 6977d0799b18…
309-30 09:03org demo, account tutorialaudit.contract.agreementuser:tutorial@example.comBINDprivate-llm/llm.privatellms.msp#2 · 81b9e4627ac3…
309-30 09:03the Platform Mesh operatoraudit.door.decisionsystem:kcp:authorizerAUTHORIZEtutorial/llm-binding#5 · 709ce5932a72…
309-30 09:03Private LLMaudit.contract.agreementsystem:private-llm:controllerACCEPTkcp:cluster:5t8r3p1y6u2i7o4w#2 · a8fb2e692800…
409-30 09:05org demo, account tutorialaudit.instance.createuser:tutorial@example.comCREATEtutorial/default/demo-llm#3 · 0bba02b8c84c…
409-30 09:05the Platform Mesh operatoraudit.door.decisionsystem:kcp:authorizerAUTHORIZEtutorial/default/demo-llm#6 · 2ac5c7b47e76…
409-30 09:08Private LLMaudit.workload.startsystem:private-llm:operatorPROVISIONtutorial/default/demo-llm#3 · 4646c6fc135d…
509-30 09:09org demo, account tutorialaudit.token.requestuser:tutorial@example.comCREATEtutorial/default/demo-llm-token#4 · c4ef602390f5…
509-30 09:09Private LLMaudit.token.issuesystem:private-llm:operatorISSUEtutorial/default/demo-llm-token-token#4 · d8e8fd41bc99…
509-30 09:09the Platform Mesh operatoraudit.claim.usesystem:private-llm:controllerCREATEtutorial/default/demo-llm-token-token#7 · 4d62051a3d30…
609-30 09:11org demo, account tutorialaudit.contract.agreementuser:tutorial@example.comBINDchat-ui/ui.privatellms.msp#5 · 23d44b987dd3…
609-30 09:11the Platform Mesh operatoraudit.door.decisionsystem:kcp:authorizerAUTHORIZEtutorial/chat-ui-binding#8 · 40a7998c66db…
609-30 09:11Chat UIaudit.contract.agreementsystem:chat-ui:controllerACCEPTkcp:cluster:5t8r3p1y6u2i7o4w#2 · 238aa5b2a31d…
609-30 09:12org demo, account tutorialaudit.chatui.createuser:tutorial@example.comCREATEtutorial/default/demo-chat#6 · db29ee67e6e2…
609-30 09:12the Platform Mesh operatoraudit.claim.usesystem:chat-ui:controllerREADtutorial/default/demo-llm-token-token#9 · 08ad06d82d08…
609-30 09:14Chat UIaudit.workload.startsystem:chat-ui:operatorPROVISIONtutorial/default/demo-chat#3 · 50a38ceb816c…
709-30 15:30org demo, account tutorialaudit.instance.scaleuser:tutorial@example.comUPDATEtutorial/default/demo-llm#7 · 65143b265ef9…
709-30 15:31Private LLMaudit.workload.scalesystem:private-llm:operatorUPDATEtutorial/default/demo-llm#5 · ee840dd08bb8…
709-30 23:59Private LLMaudit.contract.slasystem:private-llm:operatorMEASUREtutorial/default/demo-llm#6 · 427c67890ff0…
709-30 23:59org demo, account tutorialaudit.contract.slaserviceaccount:demo-probeMEASUREtutorial/default/demo-llm#8 · 8a84ae6f0b10…
810-07 10:00org demo, account tutorialaudit.instance.deleteuser:tutorial@example.comDELETEtutorial/default/demo-llm#9 · 1ae8bef34906…
810-07 10:00Private LLMaudit.workload.endsystem:private-llm:operatorDEPROVISIONtutorial/default/demo-llm#7 · 09e4ec6afb37…
810-07 10:02org demo, account tutorialaudit.contract.enduser:tutorial@example.comUNBINDprivate-llm/llm.privatellms.msp#10 · 7e8a2b03cf80…
810-07 10:02Private LLMaudit.contract.endsystem:private-llm:controllerRELEASEkcp:cluster:5t8r3p1y6u2i7o4w#8 · b8d6b9ebf7b0…
810-07 10:05Private LLMaudit.contract.weeksystem:private-llm:operatorSTATEkcp:cluster:5t8r3p1y6u2i7o4w#9 · 73a13c610972…
810-07 10:05org demo, account tutorialaudit.contract.weekserviceaccount:demo-probeSTATEprivate-llm/llm.privatellms.msp#11 · 01c9ea4038bb…

events.jsonl objects.yaml agreements.json booked.json

events.jsonl: one readable projection per generated event and its recorded edge hash. The actual client sends OTLP protobuf; this JSONL is not the wire request. agreements.json: the two subscriptions in canonical form with their digests. booked.json: the lab's output, per edge and per event.

Integration questions for a target lab

Proposed validation sequence

  • First, on the local MSP demo: the same eight steps with four edges beside them — every step recorded by the parties that took part in it, every minute sealed, the proofs checked offline by you. Scope and effort depend on the target installation.
  • Then the three taps in your lab environment: the audit webhook of the lab's kcp to the adapter; the emit calls in the Private LLM operator; the watcher in one subscriber workspace.
  • Then the marketplace view: for a subscription, an order or a month, "show the proof" — the two parties' records, their sealed minutes, the digest they share.

Confirm before connecting

  • Can the lab's kcp send its audit events to a webhook, and which policy would you allow for the resources above?
  • Does "enable a service" in the marketplace create exactly the APIBinding shown here, and does the provider's controller see its consumers' bindings through the export's virtual workspace in your version?
  • Which provider operator may carry the first emit calls — the Private LLM operator of the showroom?
  • Which events matter most to you commercially: the subscription, the delivery, the daily measurement, or the claim use on secrets?

Back to the Evidence Explorer Verify a public example