@agenticprimitives/fabric 0.0.0-alpha.1 → 0.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +26 -30
- package/README.md +16 -16
- package/dist/case-emissions.d.ts +95 -0
- package/dist/case-emissions.d.ts.map +1 -0
- package/dist/case-emissions.js +208 -0
- package/dist/case-emissions.js.map +1 -0
- package/dist/case-machine.d.ts +28 -2
- package/dist/case-machine.d.ts.map +1 -1
- package/dist/case-machine.js +34 -7
- package/dist/case-machine.js.map +1 -1
- package/dist/cloudflare/authority-verdict-cache.d.ts +28 -1
- package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -1
- package/dist/cloudflare/authority-verdict-cache.js +32 -1
- package/dist/cloudflare/authority-verdict-cache.js.map +1 -1
- package/dist/cloudflare/index.d.ts +4 -1
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +7 -1
- package/dist/cloudflare/index.js.map +1 -1
- package/dist/cloudflare/interaction-store.d.ts +55 -0
- package/dist/cloudflare/interaction-store.d.ts.map +1 -0
- package/dist/cloudflare/interaction-store.js +230 -0
- package/dist/cloudflare/interaction-store.js.map +1 -0
- package/dist/cloudflare/principal-gateway-do.d.ts +136 -2
- package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -1
- package/dist/cloudflare/principal-gateway-do.js +190 -8
- package/dist/cloudflare/principal-gateway-do.js.map +1 -1
- package/dist/cloudflare/vault-exchange-store.d.ts +47 -0
- package/dist/cloudflare/vault-exchange-store.d.ts.map +1 -0
- package/dist/cloudflare/vault-exchange-store.js +118 -0
- package/dist/cloudflare/vault-exchange-store.js.map +1 -0
- package/dist/cloudflare/vault-interaction-store.d.ts +44 -0
- package/dist/cloudflare/vault-interaction-store.d.ts.map +1 -0
- package/dist/cloudflare/vault-interaction-store.js +245 -0
- package/dist/cloudflare/vault-interaction-store.js.map +1 -0
- package/dist/communicative-act.d.ts +24 -1
- package/dist/communicative-act.d.ts.map +1 -1
- package/dist/communicative-act.js +28 -0
- package/dist/communicative-act.js.map +1 -1
- package/dist/delivery-envelope.d.ts.map +1 -1
- package/dist/delivery-envelope.js +0 -1
- package/dist/delivery-envelope.js.map +1 -1
- package/dist/enum-retirement.d.ts +43 -0
- package/dist/enum-retirement.d.ts.map +1 -0
- package/dist/enum-retirement.js +93 -0
- package/dist/enum-retirement.js.map +1 -0
- package/dist/exchange-record.d.ts +35 -4
- package/dist/exchange-record.d.ts.map +1 -1
- package/dist/exchange-record.js.map +1 -1
- package/dist/exchange-reducer.d.ts +32 -4
- package/dist/exchange-reducer.d.ts.map +1 -1
- package/dist/exchange-reducer.js +75 -1
- package/dist/exchange-reducer.js.map +1 -1
- package/dist/exchange-state.d.ts +30 -8
- package/dist/exchange-state.d.ts.map +1 -1
- package/dist/exchange-state.js +12 -10
- package/dist/exchange-state.js.map +1 -1
- package/dist/inbox-doc.d.ts +2 -2
- package/dist/inbox-doc.d.ts.map +1 -1
- package/dist/inbox-doc.js.map +1 -1
- package/dist/inbox-projection.d.ts +2 -2
- package/dist/inbox-projection.d.ts.map +1 -1
- package/dist/inbox-projection.js.map +1 -1
- package/dist/inbox-revision.d.ts +42 -0
- package/dist/inbox-revision.d.ts.map +1 -0
- package/dist/inbox-revision.js +57 -0
- package/dist/inbox-revision.js.map +1 -0
- package/dist/index.d.ts +24 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -2
- package/dist/index.js.map +1 -1
- package/dist/interaction-machines.d.ts +136 -0
- package/dist/interaction-machines.d.ts.map +1 -0
- package/dist/interaction-machines.js +174 -0
- package/dist/interaction-machines.js.map +1 -0
- package/dist/interaction-profile.d.ts +126 -0
- package/dist/interaction-profile.d.ts.map +1 -0
- package/dist/interaction-profile.js +192 -0
- package/dist/interaction-profile.js.map +1 -0
- package/dist/interaction-record.d.ts +168 -0
- package/dist/interaction-record.d.ts.map +1 -0
- package/dist/interaction-record.js +108 -0
- package/dist/interaction-record.js.map +1 -0
- package/dist/interactions/machine.d.ts +2 -2
- package/dist/interactions/machine.d.ts.map +1 -1
- package/dist/interactions/machine.js +2 -2
- package/dist/interactions/machine.js.map +1 -1
- package/dist/interactions/open-case.d.ts +60 -0
- package/dist/interactions/open-case.d.ts.map +1 -0
- package/dist/interactions/open-case.js +83 -0
- package/dist/interactions/open-case.js.map +1 -0
- package/dist/interactions/store.d.ts +9 -0
- package/dist/interactions/store.d.ts.map +1 -1
- package/dist/interactions/store.js +57 -2
- package/dist/interactions/store.js.map +1 -1
- package/dist/messaging/board.d.ts +86 -6
- package/dist/messaging/board.d.ts.map +1 -1
- package/dist/messaging/board.js +100 -9
- package/dist/messaging/board.js.map +1 -1
- package/dist/messaging/consult-routing.d.ts +289 -0
- package/dist/messaging/consult-routing.d.ts.map +1 -0
- package/dist/messaging/consult-routing.js +455 -0
- package/dist/messaging/consult-routing.js.map +1 -0
- package/dist/messaging/consult.d.ts +158 -0
- package/dist/messaging/consult.d.ts.map +1 -0
- package/dist/messaging/consult.js +141 -0
- package/dist/messaging/consult.js.map +1 -0
- package/dist/messaging/conversation-interaction.d.ts +66 -0
- package/dist/messaging/conversation-interaction.d.ts.map +1 -0
- package/dist/messaging/conversation-interaction.js +139 -0
- package/dist/messaging/conversation-interaction.js.map +1 -0
- package/dist/messaging/delivery.d.ts +2 -2
- package/dist/messaging/delivery.d.ts.map +1 -1
- package/dist/messaging/delivery.js +8 -1
- package/dist/messaging/delivery.js.map +1 -1
- package/dist/messaging/directory.d.ts +16 -0
- package/dist/messaging/directory.d.ts.map +1 -1
- package/dist/messaging/directory.js.map +1 -1
- package/dist/messaging/envelope.d.ts +7 -3
- package/dist/messaging/envelope.d.ts.map +1 -1
- package/dist/messaging/envelope.js +18 -1
- package/dist/messaging/envelope.js.map +1 -1
- package/dist/messaging/hash.d.ts +8 -2
- package/dist/messaging/hash.d.ts.map +1 -1
- package/dist/messaging/hash.js +6 -0
- package/dist/messaging/hash.js.map +1 -1
- package/dist/messaging/inbox-assistant.d.ts +80 -0
- package/dist/messaging/inbox-assistant.d.ts.map +1 -0
- package/dist/messaging/inbox-assistant.js +125 -0
- package/dist/messaging/inbox-assistant.js.map +1 -0
- package/dist/messaging/index.d.ts +10 -3
- package/dist/messaging/index.d.ts.map +1 -1
- package/dist/messaging/index.js +20 -2
- package/dist/messaging/index.js.map +1 -1
- package/dist/messaging/outbound-message.d.ts +42 -0
- package/dist/messaging/outbound-message.d.ts.map +1 -0
- package/dist/messaging/outbound-message.js +64 -0
- package/dist/messaging/outbound-message.js.map +1 -0
- package/dist/messaging/projector.d.ts +3 -3
- package/dist/messaging/projector.d.ts.map +1 -1
- package/dist/messaging/projector.js.map +1 -1
- package/dist/messaging/receipts.d.ts +3 -3
- package/dist/messaging/receipts.d.ts.map +1 -1
- package/dist/messaging/receipts.js.map +1 -1
- package/dist/messaging/rules.d.ts +10 -3
- package/dist/messaging/rules.d.ts.map +1 -1
- package/dist/messaging/rules.js +8 -1
- package/dist/messaging/rules.js.map +1 -1
- package/dist/messaging/store.d.ts +4 -4
- package/dist/messaging/store.d.ts.map +1 -1
- package/dist/messaging/store.js +5 -3
- package/dist/messaging/store.js.map +1 -1
- package/dist/messaging/types.d.ts +52 -0
- package/dist/messaging/types.d.ts.map +1 -1
- package/dist/messaging/types.js +18 -1
- package/dist/messaging/types.js.map +1 -1
- package/dist/messaging/vault-store.d.ts +35 -2
- package/dist/messaging/vault-store.d.ts.map +1 -1
- package/dist/messaging/vault-store.js +53 -5
- package/dist/messaging/vault-store.js.map +1 -1
- package/dist/protocol-binding.d.ts +71 -0
- package/dist/protocol-binding.d.ts.map +1 -0
- package/dist/protocol-binding.js +0 -0
- package/dist/protocol-binding.js.map +1 -0
- package/dist/record-catalog.d.ts.map +1 -1
- package/dist/record-catalog.js +24 -0
- package/dist/record-catalog.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consult.d.ts","sourceRoot":"","sources":["../../src/messaging/consult.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;uFACuF;AACvF,eAAO,MAAM,gBAAgB,EAAG,oBAA6B,CAAC;AAE9D;+FAC+F;AAC/F,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAClD,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,wFAAwF;AACxF,eAAO,MAAM,8BAA8B,QAAqB,CAAC;AAIjE,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,+FAA+F;AAC/F,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAClD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC;0DAC0D;AAC1D,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;0FAE0F;AAC1F,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;mEACmE;AACnE,eAAO,MAAM,gCAAgC,EAAG,qBAA8B,CAAC;AAE/E;gGACgG;AAChG,eAAO,MAAM,qBAAqB,aAAc,MAAM,KAAG,MACV,CAAC;AAEhD,qGAAqG;AACrG,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAE7G;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,iFAAiF;AACjF,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,uDAAuD;QACvD,KAAK,EAAE,MAAM,CAAC;QACd,uCAAuC;QACvC,OAAO,EAAE,MAAM,CAAC;QAChB,0FAA0F;QAC1F,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,2FAA2F;QAC3F,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;KAChC,CAAC;CACH;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;wFACwF;AACxF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CA0BtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,sBAAsB,CAAC;IAChC,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0FAA0F;IAC1F,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,gEAAgE;AAChE,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE;IAAE,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5G,wBAAwB,CAqB1B;AAED,MAAM,MAAM,4BAA4B,GACpC,aAAa,GACb,qBAAqB,GACrB,aAAa,GACb,eAAe,GACf,eAAe,GACf,uBAAuB,GACvB,+BAA+B,CAAC;AAEpC,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,eAAe,GAAG,4BAA4B,EAAE,CAWxF;AAED,8EAA8E;AAC9E,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,2BAA2B,CAAC;IACrC,mEAAmE;IACnE,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,SAAS,EAAE,SAAS,CAAC;IACrB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,WAAW,EAAE,gBAAgB,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAChC,yEAAyE;IACzE,WAAW,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,iCAAiC,GACzC,aAAa,GACb,eAAe,GACf,sBAAsB,GACtB,kBAAkB,GAClB,qBAAqB,GACrB,YAAY,CAAC;AAEjB,kDAAkD;AAClD,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,oBAAoB,GAAG,iCAAiC,EAAE,CASvG"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/** The consult A2A skill id — the delegation's `allowedMethods` selector derives from THIS string
|
|
2
|
+
* (`skillSelector('discussion.consult')`, spec 269 FR-4.2). Never `A2A_ANY_SKILL`. */
|
|
3
|
+
export const CONSULT_SKILL_ID = 'discussion.consult';
|
|
4
|
+
/** Member-side per-org fixed window (spec 329 §3.2): 12 consults / hour / org. Exceeding ⇒ the
|
|
5
|
+
* task fails typed + audited (`a2a.consult.rateLimited`); decided with `fixedWindowAllow`. */
|
|
6
|
+
export const CONSULT_RATE_WINDOW_MS = 60 * 60_000;
|
|
7
|
+
export const CONSULT_RATE_MAX = 12;
|
|
8
|
+
/** Default consultability-delegation lifetime (spec 329 §2.1) — re-opt-in refreshes. */
|
|
9
|
+
export const CONSULT_GRANT_VALIDITY_SECONDS = 180 * 24 * 60 * 60;
|
|
10
|
+
// ── Org-side routing bounds (spec 329 §4 — approved defaults). Kept in THIS leaf (no board
|
|
11
|
+
// import) so board.ts's setTopicRouting and the routing module share one definition. ──
|
|
12
|
+
/** Fan-out per routed question: default 3, steward-tunable 1..5. */
|
|
13
|
+
export const ROUTING_FANOUT_DEFAULT = 3;
|
|
14
|
+
export const ROUTING_FANOUT_MIN = 1;
|
|
15
|
+
export const ROUTING_FANOUT_MAX = 5;
|
|
16
|
+
/** Per-topic routing bucket (on top of 327's dispatch bucket): 3 routed questions / 10 min. */
|
|
17
|
+
export const ROUTING_RATE_WINDOW_MS = 10 * 60_000;
|
|
18
|
+
export const ROUTING_RATE_MAX = 3;
|
|
19
|
+
/** Per-member consult timeout (spec 329 §4): a member agent that hasn't completed by then is
|
|
20
|
+
* reported as timed out in the synthesis attribution. */
|
|
21
|
+
export const CONSULT_MEMBER_TIMEOUT_MS = 60_000;
|
|
22
|
+
/** contextRef kind carried by the turn-1 status post + turn-2 synthesis (spec 329 §6;
|
|
23
|
+
* cbox/interaction-vocabulary.ttl `apmsg:routedConsultation`). */
|
|
24
|
+
export const ROUTED_CONSULTATION_CONTEXT_KIND = 'routed-consultation';
|
|
25
|
+
/** The org-vault record name family holding member consultability grants (spec 329 §2.1) —
|
|
26
|
+
* exported so W2's `find_members` eligibility read and the opt-in ceremony key identically. */
|
|
27
|
+
export const consultGrantRecordKey = (memberSA) => `org.consult-grant:${memberSA.toLowerCase()}`;
|
|
28
|
+
/** Build the routed-consultation contextRef: id = `<orgSA>/<topicId>/<questionId>` (spec 329 §6). */
|
|
29
|
+
export function routedConsultationContextRef(orgSA, topicId, questionId) {
|
|
30
|
+
return { kind: ROUTED_CONSULTATION_CONTEXT_KIND, id: `${orgSA.toLowerCase()}/${topicId}/${questionId}` };
|
|
31
|
+
}
|
|
32
|
+
/** Bounds on the carried context — the consult turn is small by construction. */
|
|
33
|
+
export const CONSULT_QUESTION_MAX_CHARS = 2000;
|
|
34
|
+
export const CONSULT_TAIL_MAX_ROWS = 8;
|
|
35
|
+
export const CONSULT_TAIL_CLIP = 300;
|
|
36
|
+
/** Parse + bound an inbound consult payload, fail-closed. Unknown/oversized context is CLIPPED
|
|
37
|
+
* (data, never authority — ADR-0041); a missing goal/org/topic/question id REJECTS. */
|
|
38
|
+
export function parseConsultRequest(input) {
|
|
39
|
+
if (!input || typeof input !== 'object')
|
|
40
|
+
return { ok: false, error: 'consult requires an object payload { goal, context }' };
|
|
41
|
+
const i = input;
|
|
42
|
+
const goal = typeof i.goal === 'string' ? i.goal.trim().slice(0, CONSULT_QUESTION_MAX_CHARS) : '';
|
|
43
|
+
if (!goal)
|
|
44
|
+
return { ok: false, error: 'consult requires goal (the question text)' };
|
|
45
|
+
const c = (i.context && typeof i.context === 'object' ? i.context : {});
|
|
46
|
+
const orgSA = String(c.orgSA ?? '').toLowerCase();
|
|
47
|
+
if (!/^0x[0-9a-f]{40}$/.test(orgSA))
|
|
48
|
+
return { ok: false, error: 'consult requires context.orgSA (the consulting org SA)' };
|
|
49
|
+
const topicId = String(c.topicId ?? '').trim();
|
|
50
|
+
const questionId = String(c.questionId ?? '').trim();
|
|
51
|
+
if (!topicId || !questionId)
|
|
52
|
+
return { ok: false, error: 'consult requires context.topicId + context.questionId' };
|
|
53
|
+
const tailRaw = Array.isArray(c.topicTail) ? c.topicTail : [];
|
|
54
|
+
const topicTail = tailRaw.slice(-CONSULT_TAIL_MAX_ROWS).flatMap((r) => {
|
|
55
|
+
const row = r;
|
|
56
|
+
const bodyText = typeof row.bodyText === 'string' ? row.bodyText.slice(0, CONSULT_TAIL_CLIP) : '';
|
|
57
|
+
if (!bodyText)
|
|
58
|
+
return [];
|
|
59
|
+
return [{ author: typeof row.author === 'string' ? row.author.slice(0, 120) : 'member', bodyText }];
|
|
60
|
+
});
|
|
61
|
+
const topicTitle = typeof c.topicTitle === 'string' && c.topicTitle.trim() ? c.topicTitle.trim().slice(0, 200) : undefined;
|
|
62
|
+
return {
|
|
63
|
+
ok: true,
|
|
64
|
+
request: {
|
|
65
|
+
goal,
|
|
66
|
+
context: { orgSA, topicId, questionId, ...(topicTitle ? { topicTitle } : {}), ...(topicTail.length ? { topicTail } : {}) },
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Max answer/decline-reason length carried back to the org. */
|
|
71
|
+
export const CONSULT_ANSWER_MAX_CHARS = 4000;
|
|
72
|
+
/**
|
|
73
|
+
* Build the ConsultAnswer artifact body (spec 329 §3.2). IDENTITY-PINNED by construction: the
|
|
74
|
+
* caller supplies only the outcome — `actor` is ALWAYS the member principal, and the request
|
|
75
|
+
* correlation (org/topic/question) comes from the PARSED request, never planner output.
|
|
76
|
+
* Enforces answered XOR declined, fail-closed (ADR-0013): an empty answer without an explicit
|
|
77
|
+
* decline is an error, never a silent empty artifact.
|
|
78
|
+
*/
|
|
79
|
+
export function buildConsultAnswer(request, opts) {
|
|
80
|
+
const answer = (opts.answer ?? '').trim().slice(0, CONSULT_ANSWER_MAX_CHARS);
|
|
81
|
+
const declined = opts.declined === true;
|
|
82
|
+
if (declined && answer)
|
|
83
|
+
return { ok: false, error: 'a consult terminal is answered XOR declined — not both' };
|
|
84
|
+
if (!declined && !answer)
|
|
85
|
+
return { ok: false, error: 'consult answer requires answer text or an explicit decline' };
|
|
86
|
+
const memberAddr = String(opts.member).match(/0x[0-9a-fA-F]{40}$/)?.[0];
|
|
87
|
+
if (!memberAddr)
|
|
88
|
+
return { ok: false, error: 'member must be an EVM agent (CAIP-10)' };
|
|
89
|
+
const declineReason = declined ? (opts.declineReason ?? '').trim().slice(0, CONSULT_ANSWER_MAX_CHARS) : '';
|
|
90
|
+
return {
|
|
91
|
+
ok: true,
|
|
92
|
+
answer: {
|
|
93
|
+
version: 'ap.consult-answer.v1',
|
|
94
|
+
questionId: request.context.questionId,
|
|
95
|
+
orgSA: request.context.orgSA,
|
|
96
|
+
topicId: request.context.topicId,
|
|
97
|
+
question: request.goal,
|
|
98
|
+
...(declined ? { declined: true, ...(declineReason ? { declineReason } : {}) } : { answer }),
|
|
99
|
+
actor: opts.member,
|
|
100
|
+
respondedAt: opts.now ?? new Date().toISOString(),
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** TS mirror of apmsg:ConsultAnswerShape (structural; the bodyHash binding is the task rail's). */
|
|
105
|
+
export function validateConsultAnswer(a) {
|
|
106
|
+
const errors = [];
|
|
107
|
+
if (a.version !== 'ap.consult-answer.v1')
|
|
108
|
+
errors.push('bad_version');
|
|
109
|
+
if (!a.questionId?.trim())
|
|
110
|
+
errors.push('missing_question_id');
|
|
111
|
+
if (!/^0x[0-9a-f]{40}$/.test(a.orgSA ?? ''))
|
|
112
|
+
errors.push('missing_org');
|
|
113
|
+
if (!a.topicId?.trim())
|
|
114
|
+
errors.push('missing_topic');
|
|
115
|
+
if (!a.actor || !String(a.actor).match(/0x[0-9a-fA-F]{40}$/))
|
|
116
|
+
errors.push('missing_actor');
|
|
117
|
+
const answered = typeof a.answer === 'string' && a.answer.trim().length > 0;
|
|
118
|
+
if (answered && a.declined)
|
|
119
|
+
errors.push('answered_and_declined');
|
|
120
|
+
if (!answered && a.declined !== true)
|
|
121
|
+
errors.push('neither_answered_nor_declined');
|
|
122
|
+
return errors;
|
|
123
|
+
}
|
|
124
|
+
/** TS mirror of apint:ConsultationIntentShape. */
|
|
125
|
+
export function validateConsultationIntent(i) {
|
|
126
|
+
const errors = [];
|
|
127
|
+
if (i.version !== 'ap.consultation-intent.v1')
|
|
128
|
+
errors.push('bad_version');
|
|
129
|
+
if (i.direction !== 'receive')
|
|
130
|
+
errors.push('bad_direction');
|
|
131
|
+
if (!i.expressedBy)
|
|
132
|
+
errors.push('missing_expressed_by');
|
|
133
|
+
if (!Array.isArray(i.addressedTo) || i.addressedTo.length !== 1 || !i.addressedTo[0])
|
|
134
|
+
errors.push('bad_addressed_to');
|
|
135
|
+
if (!i.constraints || !(i.constraints.timeoutMs > 0) || !i.constraints.topicId?.trim())
|
|
136
|
+
errors.push('missing_constraints');
|
|
137
|
+
if (!['drafted', 'expressed', 'fulfilled', 'abandoned'].includes(i.status))
|
|
138
|
+
errors.push('bad_status');
|
|
139
|
+
return errors;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=consult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consult.js","sourceRoot":"","sources":["../../src/messaging/consult.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { ConversationDescriptorV1, ConversationId } from './types.js';
|
|
3
|
+
import type { InteractionId, ProfileVersion, ParticipationV1 } from '../interaction-record.js';
|
|
4
|
+
import type { InteractionState } from '../interaction-machines.js';
|
|
5
|
+
import { type ChannelV1 } from './board.js';
|
|
6
|
+
/** Derived from the conversation id, so the two can never disagree and no field needs adding. */
|
|
7
|
+
export declare function conversationInteractionId(conversationId: ConversationId | string): InteractionId;
|
|
8
|
+
/** The inverse, or `null` for an id that is not a conversation interaction. Null rather than a guess —
|
|
9
|
+
* the same rule that keeps derived-participation resolution fail-closed. */
|
|
10
|
+
export declare function conversationIdFromInteraction(interactionId: string): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* `participantPolicy` IS `participationMode`, and noticing that is what made this a projection.
|
|
13
|
+
*
|
|
14
|
+
* `open-to-context` means "anyone in the anchored org" — membership owned elsewhere, resolved at read
|
|
15
|
+
* time, never copied per conversation. That is precisely `derived`. `fixed` and `owner-managed` both
|
|
16
|
+
* mean the participant list on the record is the membership: `asserted`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function participationModeOfConversation(descriptor: Pick<ConversationDescriptorV1, 'participantPolicy'>): 'asserted' | 'derived';
|
|
19
|
+
/**
|
|
20
|
+
* Which profile governs this conversation.
|
|
21
|
+
*
|
|
22
|
+
* `forum`/`discussion` are boards — `topic`. Everything else is conversation — `direct`. Neither can
|
|
23
|
+
* create an obligation, which is true of both today and stated rather than left to inference. A
|
|
24
|
+
* conversation that needs to negotiate is promoted to its own Interaction under the negotiation
|
|
25
|
+
* profile (ADR-0058 §14), not granted extra acts here.
|
|
26
|
+
*/
|
|
27
|
+
export declare function profileVersionOfConversation(descriptor: Pick<ConversationDescriptorV1, 'profile'>): ProfileVersion;
|
|
28
|
+
/**
|
|
29
|
+
* Lifecycle state.
|
|
30
|
+
*
|
|
31
|
+
* `archived` is deliberately NOT read as an ending. Spec 340 §P settled that shelving is a display
|
|
32
|
+
* concern that already lives in `InboxState`; an archived conversation has still either concluded or
|
|
33
|
+
* not, and conflating them would mean unarchiving a board silently reopened a concluded situation.
|
|
34
|
+
* The descriptor carries no concluded flag today, so every live conversation is `active` — stated here
|
|
35
|
+
* rather than invented, because inferring a conclusion from `archived` would be exactly the wrong fix.
|
|
36
|
+
*/
|
|
37
|
+
export declare function lifecycleStateOfConversation(_descriptor: Pick<ConversationDescriptorV1, 'archived'>): InteractionState;
|
|
38
|
+
/** Participations, for an `asserted` conversation. Empty for a `derived` one — the whole point. */
|
|
39
|
+
export declare function participationsOfConversation(descriptor: Pick<ConversationDescriptorV1, 'participantPolicy' | 'participants' | 'createdAt'>): readonly ParticipationV1[];
|
|
40
|
+
/** What an Exchange in this conversation pins — `interactionId` + `profileVersion` in one call, so a
|
|
41
|
+
* caller cannot set one and forget the other. */
|
|
42
|
+
export interface ConversationExchangePins {
|
|
43
|
+
interactionId: InteractionId;
|
|
44
|
+
profileVersion: ProfileVersion;
|
|
45
|
+
}
|
|
46
|
+
export declare function conversationPins(descriptor: Pick<ConversationDescriptorV1, 'id' | 'profile'>): ConversationExchangePins;
|
|
47
|
+
/** The full interaction view of a conversation — the projection, assembled. */
|
|
48
|
+
export interface ConversationInteractionView {
|
|
49
|
+
interactionId: InteractionId;
|
|
50
|
+
profileVersion: ProfileVersion;
|
|
51
|
+
principal: CanonicalAgentId;
|
|
52
|
+
lifecycleState: InteractionState;
|
|
53
|
+
participationMode: 'asserted' | 'derived';
|
|
54
|
+
participations: readonly ParticipationV1[];
|
|
55
|
+
}
|
|
56
|
+
export declare function interactionViewOfConversation(descriptor: ConversationDescriptorV1): ConversationInteractionView;
|
|
57
|
+
/** Participation mode of a board channel — `open` topics derive membership, `restricted` assert it. */
|
|
58
|
+
export declare function participationModeOfChannel(channel: Pick<ChannelV1, 'participationPolicy' | 'visibility'>): 'asserted' | 'derived';
|
|
59
|
+
/**
|
|
60
|
+
* The interaction view of a live board channel — the one `demo-a2a` actually serves.
|
|
61
|
+
*
|
|
62
|
+
* Zero storage change: every field is read from what the board already persists. A topic in the vault
|
|
63
|
+
* IS an Interaction; this is how to read it as one.
|
|
64
|
+
*/
|
|
65
|
+
export declare function interactionViewOfChannel(channel: ChannelV1): ConversationInteractionView;
|
|
66
|
+
//# sourceMappingURL=conversation-interaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-interaction.d.ts","sourceRoot":"","sources":["../../src/messaging/conversation-interaction.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAIxE,iGAAiG;AACjG,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,cAAc,GAAG,MAAM,GAAG,aAAa,CAEhG;AAED;6EAC6E;AAC7E,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAElF;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,GAC9D,UAAU,GAAG,SAAS,CAExB;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAC,GACpD,cAAc,CAIhB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,IAAI,CAAC,wBAAwB,EAAE,UAAU,CAAC,GACtD,gBAAgB,CAElB;AAED,mGAAmG;AACnG,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,mBAAmB,GAAG,cAAc,GAAG,WAAW,CAAC,GAC7F,SAAS,eAAe,EAAE,CAU5B;AAED;kDACkD;AAClD,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,IAAI,GAAG,SAAS,CAAC,GAC3D,wBAAwB,CAK1B;AAED,+EAA+E;AAC/E,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,cAAc,EAAE,gBAAgB,CAAC;IACjC,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAC;IAC1C,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;CAC5C;AAED,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,wBAAwB,GACnC,2BAA2B,CAU7B;AAcD,uGAAuG;AACvG,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,qBAAqB,GAAG,YAAY,CAAC,GAC7D,UAAU,GAAG,SAAS,CAExB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,GAAG,2BAA2B,CAkBxF"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// The vault-backed conversation, viewed as the Interaction it already is (spec 340 W12).
|
|
2
|
+
//
|
|
3
|
+
// WHY THIS FILE EXISTS, stated plainly because it is a correction. W11 made org topics a real
|
|
4
|
+
// Interaction by wiring `PrincipalGatewayDO.createChannel`/`postToChannel` — the DO-SQL channel store.
|
|
5
|
+
// `demo-a2a`, the only app that actually serves topics, does not use that store. It uses the
|
|
6
|
+
// VAULT-backed board (`createBoardChannel` / `appendBoardPost` over `ConversationDescriptorV1`). So
|
|
7
|
+
// W11 landed in a code path no demo runs, which is the same dormancy the whole exercise was meant to
|
|
8
|
+
// end — this time with the added problem that a third model of "a governed conversation" now existed.
|
|
9
|
+
//
|
|
10
|
+
// THE FIX IS A PROJECTION, NOT A MIGRATION. `ConversationDescriptorV1` already carries every field the
|
|
11
|
+
// Interaction needs, under different names:
|
|
12
|
+
//
|
|
13
|
+
// descriptor.id → the interaction identity (derived, see below)
|
|
14
|
+
// descriptor.owner → the custodian (`principal`)
|
|
15
|
+
// descriptor.participantPolicy → `participationMode`, exactly
|
|
16
|
+
// descriptor.participants → the asserted list, when there is one
|
|
17
|
+
// descriptor.profile → which InteractionProfile applies
|
|
18
|
+
// descriptor.archived → shelving, NOT the lifecycle (spec 340 §P)
|
|
19
|
+
//
|
|
20
|
+
// So nothing is stored twice and nothing migrates. A conversation IS an interaction; this says how to
|
|
21
|
+
// read it as one. Deriving rather than storing is deliberate: a stored copy of a value computable from
|
|
22
|
+
// the record is the drift this ontology work exists to remove, and it would need a migration to add.
|
|
23
|
+
import { TOPIC_PROFILE, DIRECT_PROFILE } from '../interaction-profile.js';
|
|
24
|
+
import { channelParticipationPolicy } from './board.js';
|
|
25
|
+
const CONVERSATION_PREFIX = 'ixn_conv_';
|
|
26
|
+
/** Derived from the conversation id, so the two can never disagree and no field needs adding. */
|
|
27
|
+
export function conversationInteractionId(conversationId) {
|
|
28
|
+
return `${CONVERSATION_PREFIX}${conversationId}`;
|
|
29
|
+
}
|
|
30
|
+
/** The inverse, or `null` for an id that is not a conversation interaction. Null rather than a guess —
|
|
31
|
+
* the same rule that keeps derived-participation resolution fail-closed. */
|
|
32
|
+
export function conversationIdFromInteraction(interactionId) {
|
|
33
|
+
return interactionId.startsWith(CONVERSATION_PREFIX) ? interactionId.slice(CONVERSATION_PREFIX.length) : null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* `participantPolicy` IS `participationMode`, and noticing that is what made this a projection.
|
|
37
|
+
*
|
|
38
|
+
* `open-to-context` means "anyone in the anchored org" — membership owned elsewhere, resolved at read
|
|
39
|
+
* time, never copied per conversation. That is precisely `derived`. `fixed` and `owner-managed` both
|
|
40
|
+
* mean the participant list on the record is the membership: `asserted`.
|
|
41
|
+
*/
|
|
42
|
+
export function participationModeOfConversation(descriptor) {
|
|
43
|
+
return descriptor.participantPolicy === 'open-to-context' ? 'derived' : 'asserted';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Which profile governs this conversation.
|
|
47
|
+
*
|
|
48
|
+
* `forum`/`discussion` are boards — `topic`. Everything else is conversation — `direct`. Neither can
|
|
49
|
+
* create an obligation, which is true of both today and stated rather than left to inference. A
|
|
50
|
+
* conversation that needs to negotiate is promoted to its own Interaction under the negotiation
|
|
51
|
+
* profile (ADR-0058 §14), not granted extra acts here.
|
|
52
|
+
*/
|
|
53
|
+
export function profileVersionOfConversation(descriptor) {
|
|
54
|
+
return descriptor.profile === 'forum' || descriptor.profile === 'discussion'
|
|
55
|
+
? TOPIC_PROFILE.profileVersion
|
|
56
|
+
: DIRECT_PROFILE.profileVersion;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Lifecycle state.
|
|
60
|
+
*
|
|
61
|
+
* `archived` is deliberately NOT read as an ending. Spec 340 §P settled that shelving is a display
|
|
62
|
+
* concern that already lives in `InboxState`; an archived conversation has still either concluded or
|
|
63
|
+
* not, and conflating them would mean unarchiving a board silently reopened a concluded situation.
|
|
64
|
+
* The descriptor carries no concluded flag today, so every live conversation is `active` — stated here
|
|
65
|
+
* rather than invented, because inferring a conclusion from `archived` would be exactly the wrong fix.
|
|
66
|
+
*/
|
|
67
|
+
export function lifecycleStateOfConversation(_descriptor) {
|
|
68
|
+
return 'active';
|
|
69
|
+
}
|
|
70
|
+
/** Participations, for an `asserted` conversation. Empty for a `derived` one — the whole point. */
|
|
71
|
+
export function participationsOfConversation(descriptor) {
|
|
72
|
+
if (participationModeOfConversation(descriptor) === 'derived')
|
|
73
|
+
return [];
|
|
74
|
+
return descriptor.participants.map((agent) => ({
|
|
75
|
+
agent,
|
|
76
|
+
role: 'participant',
|
|
77
|
+
// The descriptor records no per-participant join time, so the conversation's own is the honest
|
|
78
|
+
// answer: it is when membership was first observable, and claiming a more precise one would be
|
|
79
|
+
// inventing provenance.
|
|
80
|
+
joinedAt: descriptor.createdAt,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
export function conversationPins(descriptor) {
|
|
84
|
+
return {
|
|
85
|
+
interactionId: conversationInteractionId(descriptor.id),
|
|
86
|
+
profileVersion: profileVersionOfConversation(descriptor),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function interactionViewOfConversation(descriptor) {
|
|
90
|
+
return {
|
|
91
|
+
...conversationPins(descriptor),
|
|
92
|
+
// The descriptor's `owner` is the store that holds this copy, which for an org board is the org —
|
|
93
|
+
// the same custodial rule W3 enforces, arrived at from the other direction.
|
|
94
|
+
principal: descriptor.owner,
|
|
95
|
+
lifecycleState: lifecycleStateOfConversation(descriptor),
|
|
96
|
+
participationMode: participationModeOfConversation(descriptor),
|
|
97
|
+
participations: participationsOfConversation(descriptor),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// ─── Board channels ──────────────────────────────────────────────────────────
|
|
101
|
+
//
|
|
102
|
+
// A board `ChannelV1` (this subpath) is NOT the DO-SQL `ChannelV1` in `../cloudflare/channel-store.ts`.
|
|
103
|
+
// Same name, two different concepts, two subpaths — noted here rather than renamed, because renaming a
|
|
104
|
+
// live wire type is its own change; see spec 340 §C.
|
|
105
|
+
//
|
|
106
|
+
// The board channel is the better projection source than its descriptor: it carries
|
|
107
|
+
// `participationPolicy` DIRECTLY (`open` = derived from org membership and never stored; `restricted` =
|
|
108
|
+
// `members` is the list), with `channelParticipationPolicy` already resolving the legacy `visibility`
|
|
109
|
+
// spelling. Reading that instead of re-deriving from `participantPolicy` means one answer, from the
|
|
110
|
+
// field that actually decides it.
|
|
111
|
+
/** Participation mode of a board channel — `open` topics derive membership, `restricted` assert it. */
|
|
112
|
+
export function participationModeOfChannel(channel) {
|
|
113
|
+
return channelParticipationPolicy(channel) === 'open' ? 'derived' : 'asserted';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The interaction view of a live board channel — the one `demo-a2a` actually serves.
|
|
117
|
+
*
|
|
118
|
+
* Zero storage change: every field is read from what the board already persists. A topic in the vault
|
|
119
|
+
* IS an Interaction; this is how to read it as one.
|
|
120
|
+
*/
|
|
121
|
+
export function interactionViewOfChannel(channel) {
|
|
122
|
+
const mode = participationModeOfChannel(channel);
|
|
123
|
+
return {
|
|
124
|
+
...conversationPins(channel.descriptor),
|
|
125
|
+
principal: channel.descriptor.owner,
|
|
126
|
+
lifecycleState: lifecycleStateOfConversation(channel.descriptor),
|
|
127
|
+
participationMode: mode,
|
|
128
|
+
// A restricted topic's `members` IS the participant list (legacy field name; these are discussion
|
|
129
|
+
// participants, not the org roster). An open topic stores none, by design.
|
|
130
|
+
participations: mode === 'derived'
|
|
131
|
+
? []
|
|
132
|
+
: (channel.members ?? []).map((agent) => ({
|
|
133
|
+
agent: agent,
|
|
134
|
+
role: 'participant',
|
|
135
|
+
joinedAt: channel.descriptor.createdAt,
|
|
136
|
+
})),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=conversation-interaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-interaction.js","sourceRoot":"","sources":["../../src/messaging/conversation-interaction.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,EAAE;AACF,8FAA8F;AAC9F,uGAAuG;AACvG,6FAA6F;AAC7F,oGAAoG;AACpG,qGAAqG;AACrG,sGAAsG;AACtG,EAAE;AACF,uGAAuG;AACvG,4CAA4C;AAC5C,EAAE;AACF,yFAAyF;AACzF,uEAAuE;AACvE,wEAAwE;AACxE,gFAAgF;AAChF,4EAA4E;AAC5E,qFAAqF;AACrF,EAAE;AACF,sGAAsG;AACtG,uGAAuG;AACvG,qGAAqG;AAMrG,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAkB,MAAM,YAAY,CAAC;AAExE,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAExC,iGAAiG;AACjG,MAAM,UAAU,yBAAyB,CAAC,cAAuC;IAC/E,OAAO,GAAG,mBAAmB,GAAG,cAAc,EAAmB,CAAC;AACpE,CAAC;AAED;6EAC6E;AAC7E,MAAM,UAAU,6BAA6B,CAAC,aAAqB;IACjE,OAAO,aAAa,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,+BAA+B,CAC7C,UAA+D;IAE/D,OAAO,UAAU,CAAC,iBAAiB,KAAK,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACrF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,4BAA4B,CAC1C,UAAqD;IAErD,OAAO,UAAU,CAAC,OAAO,KAAK,OAAO,IAAI,UAAU,CAAC,OAAO,KAAK,YAAY;QAC1E,CAAC,CAAC,aAAa,CAAC,cAAc;QAC9B,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,4BAA4B,CAC1C,WAAuD;IAEvD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,4BAA4B,CAC1C,UAA8F;IAE9F,IAAI,+BAA+B,CAAC,UAAU,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACzE,OAAO,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7C,KAAK;QACL,IAAI,EAAE,aAAa;QACnB,+FAA+F;QAC/F,+FAA+F;QAC/F,wBAAwB;QACxB,QAAQ,EAAE,UAAU,CAAC,SAAS;KAC/B,CAAC,CAAC,CAAC;AACN,CAAC;AASD,MAAM,UAAU,gBAAgB,CAC9B,UAA4D;IAE5D,OAAO;QACL,aAAa,EAAE,yBAAyB,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,cAAc,EAAE,4BAA4B,CAAC,UAAU,CAAC;KACzD,CAAC;AACJ,CAAC;AAYD,MAAM,UAAU,6BAA6B,CAC3C,UAAoC;IAEpC,OAAO;QACL,GAAG,gBAAgB,CAAC,UAAU,CAAC;QAC/B,kGAAkG;QAClG,4EAA4E;QAC5E,SAAS,EAAE,UAAU,CAAC,KAAK;QAC3B,cAAc,EAAE,4BAA4B,CAAC,UAAU,CAAC;QACxD,iBAAiB,EAAE,+BAA+B,CAAC,UAAU,CAAC;QAC9D,cAAc,EAAE,4BAA4B,CAAC,UAAU,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,EAAE;AACF,wGAAwG;AACxG,uGAAuG;AACvG,qDAAqD;AACrD,EAAE;AACF,oFAAoF;AACpF,wGAAwG;AACxG,sGAAsG;AACtG,oGAAoG;AACpG,kCAAkC;AAElC,uGAAuG;AACvG,MAAM,UAAU,0BAA0B,CACxC,OAA8D;IAE9D,OAAO,0BAA0B,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAkB;IACzD,MAAM,IAAI,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC;QACvC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK;QACnC,cAAc,EAAE,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC;QAChE,iBAAiB,EAAE,IAAI;QACvB,kGAAkG;QAClG,2EAA2E;QAC3E,cAAc,EACZ,IAAI,KAAK,SAAS;YAChB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACtC,KAAK,EAAE,KAAyB;gBAChC,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,SAAS;aACvC,CAAC,CAAC;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AuditSink } from '@agenticprimitives/audit';
|
|
2
2
|
import type { InboxProjector } from './projector.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AnyMessageEnvelope, MessageEventV1 } from './types.js';
|
|
4
4
|
import type { RuleApplication } from './rules.js';
|
|
5
5
|
export interface AuditedInboxDelivery {
|
|
6
6
|
/**
|
|
@@ -8,7 +8,7 @@ export interface AuditedInboxDelivery {
|
|
|
8
8
|
* `bodyBytes` is provided the body-hash binding is enforced (§8.4); pass the
|
|
9
9
|
* bytes fetched from the vault whenever the body was transported.
|
|
10
10
|
*/
|
|
11
|
-
admit(envelope:
|
|
11
|
+
admit(envelope: AnyMessageEnvelope, event: MessageEventV1, bodyBytes?: Uint8Array): Promise<RuleApplication>;
|
|
12
12
|
}
|
|
13
13
|
export declare function createAuditedInboxDelivery(opts: {
|
|
14
14
|
projector: InboxProjector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/messaging/delivery.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/messaging/delivery.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAwBlD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,KAAK,CACH,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,cAAc,EACrB,SAAS,CAAC,EAAE,UAAU,GACrB,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,oBAAoB,CAiCvB"}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// Fail-closed ordering: validate → verify body hash → AUDIT (await) → commit.
|
|
4
4
|
// If the audit write fails the message is NOT admitted (spec 291 discipline for
|
|
5
5
|
// privileged outcomes); rejects are audited as `denied` before throwing.
|
|
6
|
+
import { isEnvelopeV2 } from './types.js';
|
|
7
|
+
import { performativeOf } from '../communicative-act.js';
|
|
6
8
|
import { validateMessageEnvelope } from './envelope.js';
|
|
7
9
|
import { verifyBodyHash } from './hash.js';
|
|
8
10
|
function auditEventBase(envelope, recipient) {
|
|
@@ -14,7 +16,12 @@ function auditEventBase(envelope, recipient) {
|
|
|
14
16
|
// Hashes/ids only — never bodies, subjects, or PII (spec 309 §9).
|
|
15
17
|
context: {
|
|
16
18
|
from: envelope.from,
|
|
17
|
-
|
|
19
|
+
// spec 340 — the audit records what the message DOES, which spans both wire versions. `kind` is
|
|
20
|
+
// kept when the envelope is V1 so historical rows stay comparable, and is simply absent on V2
|
|
21
|
+
// rather than being back-derived: `performativeForKind` is not injective, so a reconstructed
|
|
22
|
+
// `kind` would be a guess written into an audit trail.
|
|
23
|
+
performative: performativeOf(envelope),
|
|
24
|
+
...(isEnvelopeV2(envelope) ? {} : { kind: envelope.kind }),
|
|
18
25
|
classification: envelope.classification,
|
|
19
26
|
bodyHash: envelope.bodyHash,
|
|
20
27
|
conversationId: envelope.conversationId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/messaging/delivery.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,yEAAyE;AAKzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,SAAS,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/messaging/delivery.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,yEAAyE;AAKzE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,SAAS,cAAc,CAAC,QAA4B,EAAE,SAAiB;IACrE,OAAO;QACL,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE;QAClC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAkB,EAAE,EAAE,EAAE,SAAS,EAAE;QAClD,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;QAC7C,kEAAkE;QAClE,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,gGAAgG;YAChG,8FAA8F;YAC9F,6FAA6F;YAC7F,uDAAuD;YACvD,YAAY,EAAE,cAAc,CAAC,QAAQ,CAAC;YACtC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC1D,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,cAAc,EAAE,QAAQ,CAAC,cAAc;SACxC;KACF,CAAC;AACJ,CAAC;AAeD,MAAM,UAAU,0BAA0B,CAAC,IAK1C;IACC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAE7C,KAAK,UAAU,MAAM,CAAC,QAA4B,EAAE,MAAc;QAChE,MAAM,KAAK,CAAC,KAAK,CAAC;YAChB,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC;YACtC,MAAM,EAAE,0BAA0B;YAClC,OAAO,EAAE,QAAQ;YACjB,MAAM;SACP,CAAC,CAAC;QACH,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,CAAC,EAAE,cAAc,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS;YACpC,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;YACjD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,MAAM,CAAC,QAAQ,EAAE,qBAAqB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzF,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,EAAE;gBAAE,OAAO,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC,CAAC;YAC3F,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;gBAC5E,OAAO,MAAM,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YAC/C,CAAC;YAED,oEAAoE;YACpE,MAAM,KAAK,CAAC,KAAK,CAAC;gBAChB,GAAG,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC;gBACtC,MAAM,EAAE,0BAA0B;gBAClC,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;YAEH,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -17,6 +17,22 @@ export interface DirectoryListingV1 {
|
|
|
17
17
|
roles?: string[];
|
|
18
18
|
/** Where signed envelopes can be delivered (the subject's Home inbox). */
|
|
19
19
|
inboxEndpoint?: string;
|
|
20
|
+
/** spec 329 §2.2 — member-asserted, org-scoped routing HINT (aporg:consultable): "my agent may
|
|
21
|
+
* be consulted for this org's discussions". The AUTHORITY is the consultability delegation —
|
|
22
|
+
* flag without delegation ⇒ not consultable (fail-closed); delegation without flag ⇒ not
|
|
23
|
+
* surfaced to routing. Absent ⇒ false. Inside the signed digest (additive optional field —
|
|
24
|
+
* legacy listings verify unchanged; setting/clearing it is a re-publish, i.e. re-signed). */
|
|
25
|
+
consultable?: boolean;
|
|
26
|
+
/** spec 329 §12 — the member's PRIMARY ROLE **in this organization**, self-asserted ("tax
|
|
27
|
+
* advisor", "financial advisor"). Org-scoped by construction: the listing IS per-org, so the
|
|
28
|
+
* same person holds a different role in each org they list themselves in. MEMBER-AUTHORED —
|
|
29
|
+
* the listing is member-signed, so nobody else can set it (a steward-assigned role is out of
|
|
30
|
+
* scope, §12.2). Free text, display + routing HINT only: it is never an authorization and never
|
|
31
|
+
* a verified credential. Distinct from the display-only {@link DirectoryListingV1.roles} list
|
|
32
|
+
* (unstructured, multi-valued, pre-329) — routing needs ONE primary role per org.
|
|
33
|
+
* Inside the signed digest (additive optional field — legacy listings verify byte-identically;
|
|
34
|
+
* setting/clearing it is a re-publish, i.e. re-signed). Absent ⇒ no role asserted. */
|
|
35
|
+
orgRole?: string;
|
|
20
36
|
visibility: 'community' | 'public';
|
|
21
37
|
publishedAt: string;
|
|
22
38
|
expiresAt?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/messaging/directory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,8BAA8B,CAAC;IACrC,iEAAiE;IACjE,OAAO,EAAE,gBAAgB,CAAC;IAC1B,+EAA+E;IAC/E,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,WAAW,GAAG,QAAQ,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,MAAM,sBAAsB,GAC9B,UAAU,GACV,iBAAiB,GACjB,aAAa,GACb,sBAAsB,GACtB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,mBAAmB,CAAC;AAExB;;gEAEgE;AAChE,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,kBAAkB,GAAG,sBAAsB,EAAE,CAexF;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAI9E"}
|
|
1
|
+
{"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/messaging/directory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,8BAA8B,CAAC;IACrC,iEAAiE;IACjE,OAAO,EAAE,gBAAgB,CAAC;IAC1B,+EAA+E;IAC/E,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;kGAI8F;IAC9F,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;2FAQuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,WAAW,GAAG,QAAQ,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,MAAM,sBAAsB,GAC9B,UAAU,GACV,iBAAiB,GACjB,aAAa,GACb,sBAAsB,GACtB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,mBAAmB,CAAC;AAExB;;gEAEgE;AAChE,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,kBAAkB,GAAG,sBAAsB,EAAE,CAexF;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAI9E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/messaging/directory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/messaging/directory.ts"],"names":[],"mappings":"AA8DA;;gEAEgE;AAChE,MAAM,UAAU,wBAAwB,CAAC,CAAqB;IAC5D,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,IAAI,CAAC,CAAC,IAAI,KAAK,8BAA8B;QAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvE,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC/C,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACnF,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE;QAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAChE,IAAI,CAAC,CAAC,UAAU,KAAK,WAAW,IAAI,CAAC,CAAC,UAAU,KAAK,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7F,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/F,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACtG,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;SACjD,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/E,mEAAmE;QACnE,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,CAAqB,EAAE,KAAa;IACnE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AnyMessageEnvelope, ConversationId, MessageId, ThreadId } from './types.js';
|
|
2
2
|
export declare function generateMessageId(): MessageId;
|
|
3
3
|
export declare function generateConversationId(): ConversationId;
|
|
4
4
|
export declare function generateThreadId(): ThreadId;
|
|
5
|
-
export type EnvelopeValidationError = 'bad_version' | 'bad_id' | 'bad_conversation_id' | 'missing_from' | 'empty_recipients' | 'bad_created_at' | 'bad_expires_at' | 'expired_before_created' | 'bad_body_hash' | 'missing_body_content_type' | 'bad_attachment_hash' | 'too_many_context_refs' | 'bad_context_ref'
|
|
5
|
+
export type EnvelopeValidationError = 'bad_version' | 'bad_id' | 'bad_conversation_id' | 'missing_from' | 'empty_recipients' | 'bad_created_at' | 'bad_expires_at' | 'expired_before_created' | 'bad_body_hash' | 'missing_body_content_type' | 'bad_attachment_hash' | 'too_many_context_refs' | 'bad_context_ref'
|
|
6
|
+
/** V2-only (spec 340 cutover): the version says v2 but the act it performs is absent. */
|
|
7
|
+
| 'missing_performative'
|
|
8
|
+
/** V2-only: a half-migrated sender stamped v2 while still emitting the retired `kind` taxonomy. */
|
|
9
|
+
| 'v2_carries_retired_kind';
|
|
6
10
|
/** Envelope context refs are bounded so refs stay metadata, not payload. */
|
|
7
11
|
export declare const MAX_CONTEXT_REFS = 8;
|
|
8
12
|
/**
|
|
@@ -10,5 +14,5 @@ export declare const MAX_CONTEXT_REFS = 8;
|
|
|
10
14
|
* recipient admission policy are the recipient runtime's job (spec 309 §4.4).
|
|
11
15
|
* Returns an empty array iff the envelope is structurally admissible.
|
|
12
16
|
*/
|
|
13
|
-
export declare function validateMessageEnvelope(env:
|
|
17
|
+
export declare function validateMessageEnvelope(env: AnyMessageEnvelope): EnvelopeValidationError[];
|
|
14
18
|
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/messaging/envelope.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/messaging/envelope.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAqB,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAW7G,wBAAgB,iBAAiB,IAAI,SAAS,CAE7C;AAED,wBAAgB,sBAAsB,IAAI,cAAc,CAEvD;AAED,wBAAgB,gBAAgB,IAAI,QAAQ,CAE3C;AAED,MAAM,MAAM,uBAAuB,GAC/B,aAAa,GACb,QAAQ,GACR,qBAAqB,GACrB,cAAc,GACd,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,wBAAwB,GACxB,eAAe,GACf,2BAA2B,GAC3B,qBAAqB,GACrB,uBAAuB,GACvB,iBAAiB;AACnB,yFAAyF;GACvF,sBAAsB;AACxB,mGAAmG;GACjG,yBAAyB,CAAC;AAE9B,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAQlC;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,kBAAkB,GAAG,uBAAuB,EAAE,CA6C1F"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Envelope construction + structural validation (fail-closed, spec 309 §8).
|
|
2
|
+
import { isEnvelopeV2 } from './types.js';
|
|
2
3
|
function randomSuffix() {
|
|
3
4
|
const bytes = new Uint8Array(16);
|
|
4
5
|
globalThis.crypto.getRandomValues(bytes);
|
|
@@ -28,8 +29,24 @@ function isIsoDate(s) {
|
|
|
28
29
|
*/
|
|
29
30
|
export function validateMessageEnvelope(env) {
|
|
30
31
|
const errors = [];
|
|
31
|
-
|
|
32
|
+
// spec 340 — the ap.message.v2 cutover, reader half. BOTH wire versions are structurally
|
|
33
|
+
// admissible. This must ship and be DEPLOYED EVERYWHERE before any sender emits V2: a V2 envelope
|
|
34
|
+
// reaching a validator that only knows V1 is rejected as `bad_version`, which on a peer hop is a
|
|
35
|
+
// delivery failure, not a degraded read.
|
|
36
|
+
//
|
|
37
|
+
// The two shapes are checked for what each one IS, not merely tolerated: V2 must carry a
|
|
38
|
+
// `performative` and must NOT carry `kind`, so a half-migrated sender that stamps v2 while still
|
|
39
|
+
// emitting the retired taxonomy fails here instead of quietly producing an envelope whose version
|
|
40
|
+
// and content disagree.
|
|
41
|
+
if (isEnvelopeV2(env)) {
|
|
42
|
+
if (!env.performative)
|
|
43
|
+
errors.push('missing_performative');
|
|
44
|
+
if (env.kind !== undefined)
|
|
45
|
+
errors.push('v2_carries_retired_kind');
|
|
46
|
+
}
|
|
47
|
+
else if (env.version !== 'ap.message.v1') {
|
|
32
48
|
errors.push('bad_version');
|
|
49
|
+
}
|
|
33
50
|
if (!env.id?.startsWith('msg_'))
|
|
34
51
|
errors.push('bad_id');
|
|
35
52
|
if (!env.conversationId?.startsWith('conv_'))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/messaging/envelope.ts"],"names":[],"mappings":"AAAA,4EAA4E;
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/messaging/envelope.ts"],"names":[],"mappings":"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"}
|
package/dist/messaging/hash.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Hex32, MessageEnvelopeV1 } from './types.js';
|
|
1
|
+
import type { AnyMessageEnvelope, Hex32, MessageEnvelopeV1 } from './types.js';
|
|
2
2
|
import { canonicalizeJson } from '@agenticprimitives/types';
|
|
3
3
|
/** Deterministic JSON: sorted keys, `undefined` members dropped. Hoisted to `@agenticprimitives/types` as
|
|
4
4
|
* `canonicalizeJson` (spec 316 Open Decision F); kept here as an alias for back-compat. */
|
|
@@ -8,8 +8,14 @@ export declare function sha256Hex32(input: string | Uint8Array): Promise<Hex32>;
|
|
|
8
8
|
* Hash of the canonical envelope EXCLUDING `signature` — this is the payload a
|
|
9
9
|
* sender signs and a recipient verifies (spec 309 §8.1). Deterministic across
|
|
10
10
|
* key order and undefined optional fields.
|
|
11
|
+
*
|
|
12
|
+
* Version-agnostic BY CONSTRUCTION, and that is the property the ap.message.v2 cutover rests on: it
|
|
13
|
+
* canonicalizes whatever fields the envelope has. A V1 envelope hashes today exactly as it hashed
|
|
14
|
+
* before V2 existed, so every historical signature and delivery receipt still verifies. `version` is
|
|
15
|
+
* itself inside the hashed body, so V1 and V2 of otherwise-identical content are domain-separated for
|
|
16
|
+
* free — no envelope can be replayed across versions.
|
|
11
17
|
*/
|
|
12
|
-
export declare function hashMessageEnvelope(envelope:
|
|
18
|
+
export declare function hashMessageEnvelope(envelope: AnyMessageEnvelope): Promise<Hex32>;
|
|
13
19
|
/**
|
|
14
20
|
* Body-hash binding (spec 309 §8.4): the envelope's `bodyHash` MUST equal the
|
|
15
21
|
* digest of the vault-resident body bytes. Recipients enforce this BEFORE
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/messaging/hash.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/messaging/hash.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAI5D;4FAC4F;AAC5F,eAAO,MAAM,mBAAmB,yBAAmB,CAAC;AAEpD,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAO5E;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,KAAK,CAAC,CAGtF;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,EAC7C,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,OAAO,CAAC,CAElB"}
|
package/dist/messaging/hash.js
CHANGED
|
@@ -20,6 +20,12 @@ export async function sha256Hex32(input) {
|
|
|
20
20
|
* Hash of the canonical envelope EXCLUDING `signature` — this is the payload a
|
|
21
21
|
* sender signs and a recipient verifies (spec 309 §8.1). Deterministic across
|
|
22
22
|
* key order and undefined optional fields.
|
|
23
|
+
*
|
|
24
|
+
* Version-agnostic BY CONSTRUCTION, and that is the property the ap.message.v2 cutover rests on: it
|
|
25
|
+
* canonicalizes whatever fields the envelope has. A V1 envelope hashes today exactly as it hashed
|
|
26
|
+
* before V2 existed, so every historical signature and delivery receipt still verifies. `version` is
|
|
27
|
+
* itself inside the hashed body, so V1 and V2 of otherwise-identical content are domain-separated for
|
|
28
|
+
* free — no envelope can be replayed across versions.
|
|
23
29
|
*/
|
|
24
30
|
export async function hashMessageEnvelope(envelope) {
|
|
25
31
|
const { signature: _signature, ...unsigned } = envelope;
|