events: metadata rides as headers, not in the body (ADR 0047)
emit stamps the ADR 0047 headers — x-event-id, x-source, x-node, x-time, content-type, and optional x-causation-id / x-schema — and publishes the body as only the domain payload. on() reconstructs the Event from those headers. Event gains id (the x-event-id a consumer dedups on) plus the optional causation/schema. EventHeaders joins the contracts spine. Supersedes the first cut that carried source/node/time in the body. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
+6
-1
@@ -195,12 +195,17 @@ test("events: a module emits, a listener and the audit sink (#) both receive it,
|
||||
assert.deepEqual(heard.map((e) => e.type), ["module.umami.site.created"]);
|
||||
assert.deepEqual(audited.map((e) => e.type), ["module.umami.site.created", "module.plex.play.started"]);
|
||||
|
||||
// The metadata an audit trail needs is present.
|
||||
// The metadata an audit trail needs is present — read back from the ADR 0047 headers, not the body.
|
||||
const e = heard[0];
|
||||
assert.equal(e.source, "umami");
|
||||
assert.equal(e.node, "anchor");
|
||||
assert.equal((e.body as { domain: string }).domain, "my-app");
|
||||
assert.match(e.at, /^\d{4}-\d{2}-\d{2}T/);
|
||||
// Every event carries a unique id (x-event-id) — the handle a consumer dedups on.
|
||||
assert.ok(e.id, "event has an x-event-id");
|
||||
assert.notEqual(audited[0].id, audited[1].id);
|
||||
// The body is exactly the domain payload — provenance never leaks into it.
|
||||
assert.deepEqual(Object.keys(e.body as object), ["domain"]);
|
||||
|
||||
delete process.env.MESH_MODULE;
|
||||
delete process.env.MESH_NODE;
|
||||
|
||||
Reference in New Issue
Block a user