@agenticprimitives/fabric 0.0.0-alpha.1
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 +67 -0
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/case-machine.d.ts +76 -0
- package/dist/case-machine.d.ts.map +1 -0
- package/dist/case-machine.js +83 -0
- package/dist/case-machine.js.map +1 -0
- package/dist/client/index.d.ts +114 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +76 -0
- package/dist/client/index.js.map +1 -0
- package/dist/cloudflare/authority-verdict-cache.d.ts +27 -0
- package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -0
- package/dist/cloudflare/authority-verdict-cache.js +66 -0
- package/dist/cloudflare/authority-verdict-cache.js.map +1 -0
- package/dist/cloudflare/channel-store.d.ts +61 -0
- package/dist/cloudflare/channel-store.d.ts.map +1 -0
- package/dist/cloudflare/channel-store.js +124 -0
- package/dist/cloudflare/channel-store.js.map +1 -0
- package/dist/cloudflare/exchange-store.d.ts +16 -0
- package/dist/cloudflare/exchange-store.d.ts.map +1 -0
- package/dist/cloudflare/exchange-store.js +45 -0
- package/dist/cloudflare/exchange-store.js.map +1 -0
- package/dist/cloudflare/gateway-tools.d.ts +28 -0
- package/dist/cloudflare/gateway-tools.d.ts.map +1 -0
- package/dist/cloudflare/gateway-tools.js +45 -0
- package/dist/cloudflare/gateway-tools.js.map +1 -0
- package/dist/cloudflare/index.d.ts +13 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +20 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/cloudflare/orchestration-runtime.d.ts +28 -0
- package/dist/cloudflare/orchestration-runtime.d.ts.map +1 -0
- package/dist/cloudflare/orchestration-runtime.js +35 -0
- package/dist/cloudflare/orchestration-runtime.js.map +1 -0
- package/dist/cloudflare/outbox-store.d.ts +24 -0
- package/dist/cloudflare/outbox-store.d.ts.map +1 -0
- package/dist/cloudflare/outbox-store.js +42 -0
- package/dist/cloudflare/outbox-store.js.map +1 -0
- package/dist/cloudflare/principal-gateway-do.d.ts +234 -0
- package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -0
- package/dist/cloudflare/principal-gateway-do.js +369 -0
- package/dist/cloudflare/principal-gateway-do.js.map +1 -0
- package/dist/cloudflare/provenance-store.d.ts +9 -0
- package/dist/cloudflare/provenance-store.d.ts.map +1 -0
- package/dist/cloudflare/provenance-store.js +36 -0
- package/dist/cloudflare/provenance-store.js.map +1 -0
- package/dist/cloudflare/receipt-signer.d.ts +26 -0
- package/dist/cloudflare/receipt-signer.d.ts.map +1 -0
- package/dist/cloudflare/receipt-signer.js +69 -0
- package/dist/cloudflare/receipt-signer.js.map +1 -0
- package/dist/cloudflare/request-id-ledger.d.ts +13 -0
- package/dist/cloudflare/request-id-ledger.d.ts.map +1 -0
- package/dist/cloudflare/request-id-ledger.js +38 -0
- package/dist/cloudflare/request-id-ledger.js.map +1 -0
- package/dist/cloudflare/sql-vault.d.ts +10 -0
- package/dist/cloudflare/sql-vault.d.ts.map +1 -0
- package/dist/cloudflare/sql-vault.js +98 -0
- package/dist/cloudflare/sql-vault.js.map +1 -0
- package/dist/communicative-act.d.ts +47 -0
- package/dist/communicative-act.d.ts.map +1 -0
- package/dist/communicative-act.js +36 -0
- package/dist/communicative-act.js.map +1 -0
- package/dist/delivery-envelope.d.ts +38 -0
- package/dist/delivery-envelope.d.ts.map +1 -0
- package/dist/delivery-envelope.js +43 -0
- package/dist/delivery-envelope.js.map +1 -0
- package/dist/exchange-record.d.ts +131 -0
- package/dist/exchange-record.d.ts.map +1 -0
- package/dist/exchange-record.js +25 -0
- package/dist/exchange-record.js.map +1 -0
- package/dist/exchange-reducer.d.ts +25 -0
- package/dist/exchange-reducer.d.ts.map +1 -0
- package/dist/exchange-reducer.js +108 -0
- package/dist/exchange-reducer.js.map +1 -0
- package/dist/exchange-state.d.ts +56 -0
- package/dist/exchange-state.d.ts.map +1 -0
- package/dist/exchange-state.js +81 -0
- package/dist/exchange-state.js.map +1 -0
- package/dist/gateway-surface.d.ts +24 -0
- package/dist/gateway-surface.d.ts.map +1 -0
- package/dist/gateway-surface.js +33 -0
- package/dist/gateway-surface.js.map +1 -0
- package/dist/inbox-doc.d.ts +32 -0
- package/dist/inbox-doc.d.ts.map +1 -0
- package/dist/inbox-doc.js +57 -0
- package/dist/inbox-doc.js.map +1 -0
- package/dist/inbox-projection.d.ts +15 -0
- package/dist/inbox-projection.d.ts.map +1 -0
- package/dist/inbox-projection.js +28 -0
- package/dist/inbox-projection.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions/audited.d.ts +12 -0
- package/dist/interactions/audited.d.ts.map +1 -0
- package/dist/interactions/audited.js +67 -0
- package/dist/interactions/audited.js.map +1 -0
- package/dist/interactions/builders.d.ts +24 -0
- package/dist/interactions/builders.d.ts.map +1 -0
- package/dist/interactions/builders.js +48 -0
- package/dist/interactions/builders.js.map +1 -0
- package/dist/interactions/cards.d.ts +32 -0
- package/dist/interactions/cards.d.ts.map +1 -0
- package/dist/interactions/cards.js +20 -0
- package/dist/interactions/cards.js.map +1 -0
- package/dist/interactions/index.d.ts +15 -0
- package/dist/interactions/index.d.ts.map +1 -0
- package/dist/interactions/index.js +23 -0
- package/dist/interactions/index.js.map +1 -0
- package/dist/interactions/machine.d.ts +19 -0
- package/dist/interactions/machine.d.ts.map +1 -0
- package/dist/interactions/machine.js +31 -0
- package/dist/interactions/machine.js.map +1 -0
- package/dist/interactions/mandates.d.ts +64 -0
- package/dist/interactions/mandates.d.ts.map +1 -0
- package/dist/interactions/mandates.js +62 -0
- package/dist/interactions/mandates.js.map +1 -0
- package/dist/interactions/relationship.d.ts +29 -0
- package/dist/interactions/relationship.d.ts.map +1 -0
- package/dist/interactions/relationship.js +31 -0
- package/dist/interactions/relationship.js.map +1 -0
- package/dist/interactions/risk.d.ts +39 -0
- package/dist/interactions/risk.d.ts.map +1 -0
- package/dist/interactions/risk.js +49 -0
- package/dist/interactions/risk.js.map +1 -0
- package/dist/interactions/runs.d.ts +26 -0
- package/dist/interactions/runs.d.ts.map +1 -0
- package/dist/interactions/runs.js +80 -0
- package/dist/interactions/runs.js.map +1 -0
- package/dist/interactions/store.d.ts +20 -0
- package/dist/interactions/store.d.ts.map +1 -0
- package/dist/interactions/store.js +68 -0
- package/dist/interactions/store.js.map +1 -0
- package/dist/interactions/tickets.d.ts +68 -0
- package/dist/interactions/tickets.d.ts.map +1 -0
- package/dist/interactions/tickets.js +49 -0
- package/dist/interactions/tickets.js.map +1 -0
- package/dist/interactions/types.d.ts +160 -0
- package/dist/interactions/types.d.ts.map +1 -0
- package/dist/interactions/types.js +7 -0
- package/dist/interactions/types.js.map +1 -0
- package/dist/messaging/board.d.ts +54 -0
- package/dist/messaging/board.d.ts.map +1 -0
- package/dist/messaging/board.js +90 -0
- package/dist/messaging/board.js.map +1 -0
- package/dist/messaging/conversation.d.ts +35 -0
- package/dist/messaging/conversation.d.ts.map +1 -0
- package/dist/messaging/conversation.js +72 -0
- package/dist/messaging/conversation.js.map +1 -0
- package/dist/messaging/delivery.d.ts +19 -0
- package/dist/messaging/delivery.d.ts.map +1 -0
- package/dist/messaging/delivery.js +56 -0
- package/dist/messaging/delivery.js.map +1 -0
- package/dist/messaging/directory.d.ts +32 -0
- package/dist/messaging/directory.d.ts.map +1 -0
- package/dist/messaging/directory.js +35 -0
- package/dist/messaging/directory.js.map +1 -0
- package/dist/messaging/envelope.d.ts +14 -0
- package/dist/messaging/envelope.d.ts.map +1 -0
- package/dist/messaging/envelope.js +71 -0
- package/dist/messaging/envelope.js.map +1 -0
- package/dist/messaging/hash.d.ts +19 -0
- package/dist/messaging/hash.d.ts.map +1 -0
- package/dist/messaging/hash.js +36 -0
- package/dist/messaging/hash.js.map +1 -0
- package/dist/messaging/index.d.ts +16 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/index.js +29 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/messaging/projector.d.ts +58 -0
- package/dist/messaging/projector.d.ts.map +1 -0
- package/dist/messaging/projector.js +103 -0
- package/dist/messaging/projector.js.map +1 -0
- package/dist/messaging/receipts.d.ts +5 -0
- package/dist/messaging/receipts.d.ts.map +1 -0
- package/dist/messaging/receipts.js +19 -0
- package/dist/messaging/receipts.js.map +1 -0
- package/dist/messaging/rules.d.ts +84 -0
- package/dist/messaging/rules.d.ts.map +1 -0
- package/dist/messaging/rules.js +109 -0
- package/dist/messaging/rules.js.map +1 -0
- package/dist/messaging/store.d.ts +24 -0
- package/dist/messaging/store.d.ts.map +1 -0
- package/dist/messaging/store.js +120 -0
- package/dist/messaging/store.js.map +1 -0
- package/dist/messaging/types.d.ts +166 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/messaging/types.js +7 -0
- package/dist/messaging/types.js.map +1 -0
- package/dist/messaging/vault-store.d.ts +37 -0
- package/dist/messaging/vault-store.d.ts.map +1 -0
- package/dist/messaging/vault-store.js +62 -0
- package/dist/messaging/vault-store.js.map +1 -0
- package/dist/record-catalog.d.ts +22 -0
- package/dist/record-catalog.d.ts.map +1 -0
- package/dist/record-catalog.js +35 -0
- package/dist/record-catalog.js.map +1 -0
- package/package.json +82 -0
- package/spec.md +15 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { VaultRef } from '@agenticprimitives/vault';
|
|
3
|
+
import type { ContextRefV1, MessageId, SignatureProof, Hex32 } from '../messaging/index.js';
|
|
4
|
+
import type { CaseState } from '../exchange-state.js';
|
|
5
|
+
import type { CaseTransition } from '../case-machine.js';
|
|
6
|
+
export type InteractionId = `int_${string}`;
|
|
7
|
+
export type InteractionRunId = `run_${string}`;
|
|
8
|
+
export type InteractionInterruptId = `irq_${string}`;
|
|
9
|
+
export type InteractionKind = 'access-request' | 'entitlement-request' | 'approval-request' | 'credential-delivery' | 'revocation-notice' | 'ownership-offer' | 'relationship-proposal' | 'support-thread' | 'agent-task';
|
|
10
|
+
export type InteractionState = CaseState;
|
|
11
|
+
/** By-reference pointer at authority produced by the owning packages —
|
|
12
|
+
* interactions carries these, it never creates the underlying grant. */
|
|
13
|
+
export interface AuthorityRef {
|
|
14
|
+
kind: 'delegation' | 'entitlement' | 'verifiable-credential' | 'verification-receipt';
|
|
15
|
+
/** Hash of the authority artifact (delegation hash, credential hash, …). */
|
|
16
|
+
hash: Hex32;
|
|
17
|
+
ref?: VaultRef;
|
|
18
|
+
}
|
|
19
|
+
export interface InteractionCaseV1 {
|
|
20
|
+
version: 'ap.interaction.v1';
|
|
21
|
+
id: InteractionId;
|
|
22
|
+
kind: InteractionKind;
|
|
23
|
+
subject: string;
|
|
24
|
+
/** Entities this case is ABOUT (spec 312 §4.3) — parallel to evidenceRefs/
|
|
25
|
+
* authorityRefs; an access request about a specific report renders on that
|
|
26
|
+
* report's page alongside its messages. About-ness, never authority. */
|
|
27
|
+
contextRefs?: ContextRefV1[];
|
|
28
|
+
requester: CanonicalAgentId;
|
|
29
|
+
responder: CanonicalAgentId;
|
|
30
|
+
resourceOwner?: CanonicalAgentId;
|
|
31
|
+
state: InteractionState;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
updatedAt: string;
|
|
34
|
+
expiresAt?: string;
|
|
35
|
+
rootMessageId: MessageId;
|
|
36
|
+
latestMessageId: MessageId;
|
|
37
|
+
evidenceRefs: VaultRef[];
|
|
38
|
+
authorityRefs: AuthorityRef[];
|
|
39
|
+
}
|
|
40
|
+
export type InteractionTransitionType = CaseTransition;
|
|
41
|
+
/** A signed lifecycle event. Signature VERIFICATION is the runtime's job; the
|
|
42
|
+
* state machine checks that the ACTOR holds the required role for the move. */
|
|
43
|
+
export interface InteractionTransitionEventV1 {
|
|
44
|
+
version: 'ap.interaction.event.v1';
|
|
45
|
+
interactionId: InteractionId;
|
|
46
|
+
transition: InteractionTransitionType;
|
|
47
|
+
actor: CanonicalAgentId;
|
|
48
|
+
at: string;
|
|
49
|
+
messageId?: MessageId;
|
|
50
|
+
reason?: string;
|
|
51
|
+
/** Replay dedupe (spec 309 §8.10). Same key ⇒ same outcome, applied once. */
|
|
52
|
+
idempotencyKey?: string;
|
|
53
|
+
evidenceRef?: VaultRef;
|
|
54
|
+
authorityRef?: AuthorityRef;
|
|
55
|
+
signature?: SignatureProof;
|
|
56
|
+
}
|
|
57
|
+
export interface AccessRequestV1 {
|
|
58
|
+
type: 'ap.interaction.access-request.v1';
|
|
59
|
+
interactionId: InteractionId;
|
|
60
|
+
resource: string;
|
|
61
|
+
actions: string[];
|
|
62
|
+
fields?: string[];
|
|
63
|
+
purpose?: string;
|
|
64
|
+
expiresAt?: string;
|
|
65
|
+
/** e.g. a mandate/consent receipt backing the ask (W5 wires verification). */
|
|
66
|
+
evidenceRefs?: AuthorityRef[];
|
|
67
|
+
}
|
|
68
|
+
export interface EntitlementRequestV1 {
|
|
69
|
+
type: 'ap.interaction.entitlement-request.v1';
|
|
70
|
+
interactionId: InteractionId;
|
|
71
|
+
audience: string;
|
|
72
|
+
resource: string;
|
|
73
|
+
actions: string[];
|
|
74
|
+
fields?: string[];
|
|
75
|
+
purpose?: string;
|
|
76
|
+
classificationCeiling?: string;
|
|
77
|
+
expiresAt?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface ApprovalDecisionV1 {
|
|
80
|
+
type: 'ap.interaction.approval-decision.v1';
|
|
81
|
+
interactionId: InteractionId;
|
|
82
|
+
decision: 'approved' | 'denied';
|
|
83
|
+
decidedBy: CanonicalAgentId;
|
|
84
|
+
decidedAt: string;
|
|
85
|
+
reason?: string;
|
|
86
|
+
/** What the approval produced — issued by the authority packages, referenced here. */
|
|
87
|
+
resultingAuthority?: AuthorityRef[];
|
|
88
|
+
}
|
|
89
|
+
export interface NeedsInfoV1 {
|
|
90
|
+
type: 'ap.interaction.needs-info.v1';
|
|
91
|
+
interactionId: InteractionId;
|
|
92
|
+
askedBy: CanonicalAgentId;
|
|
93
|
+
askedAt: string;
|
|
94
|
+
questions: string[];
|
|
95
|
+
responseSchemaRef?: string;
|
|
96
|
+
expiresAt?: string;
|
|
97
|
+
}
|
|
98
|
+
export interface CredentialDeliveryV1 {
|
|
99
|
+
type: 'ap.interaction.credential-delivery.v1';
|
|
100
|
+
interactionId: InteractionId;
|
|
101
|
+
issuer: CanonicalAgentId;
|
|
102
|
+
subject: CanonicalAgentId;
|
|
103
|
+
credentialFormat: 'jwt-vc' | 'sd-jwt-vc' | 'w3c-vc';
|
|
104
|
+
/** Credential lives in the recipient vault; the delivery carries hash + ref. */
|
|
105
|
+
credentialHash: Hex32;
|
|
106
|
+
credentialRef?: VaultRef;
|
|
107
|
+
statusEvidenceRef?: VaultRef;
|
|
108
|
+
}
|
|
109
|
+
export interface RevocationNoticeV1 {
|
|
110
|
+
type: 'ap.interaction.revocation-notice.v1';
|
|
111
|
+
interactionId: InteractionId;
|
|
112
|
+
revokedBy: CanonicalAgentId;
|
|
113
|
+
revokedAt: string;
|
|
114
|
+
revokedAuthority: AuthorityRef;
|
|
115
|
+
reason?: string;
|
|
116
|
+
}
|
|
117
|
+
export type InteractionRunState = 'running' | 'paused' | 'completed' | 'failed';
|
|
118
|
+
export type InteractionRunEventType = 'run-started' | 'message-received' | 'state-snapshot' | 'state-delta' | 'tool-call-requested' | 'approval-required' | 'human-interrupt-raised' | 'agent-interrupt-raised' | 'resume-submitted' | 'credential-issued' | 'run-completed' | 'run-failed';
|
|
119
|
+
export interface InteractionRunV1 {
|
|
120
|
+
version: 'ap.interaction.run.v1';
|
|
121
|
+
runId: InteractionRunId;
|
|
122
|
+
interactionId: InteractionId;
|
|
123
|
+
state: InteractionRunState;
|
|
124
|
+
startedAt: string;
|
|
125
|
+
updatedAt: string;
|
|
126
|
+
/** Set while paused — the interrupt a resume must answer. */
|
|
127
|
+
pendingInterruptId?: InteractionInterruptId;
|
|
128
|
+
}
|
|
129
|
+
export interface InteractionRunEventV1 {
|
|
130
|
+
version: 'ap.interaction.run-event.v1';
|
|
131
|
+
runId: InteractionRunId;
|
|
132
|
+
seq: number;
|
|
133
|
+
eventType: InteractionRunEventType;
|
|
134
|
+
at: string;
|
|
135
|
+
payload?: unknown;
|
|
136
|
+
}
|
|
137
|
+
export interface InteractionInterruptV1 {
|
|
138
|
+
version: 'ap.interaction.interrupt.v1';
|
|
139
|
+
interruptId: InteractionInterruptId;
|
|
140
|
+
runId: InteractionRunId;
|
|
141
|
+
raisedBy: 'human' | 'agent';
|
|
142
|
+
reason: string;
|
|
143
|
+
responseSchemaRef?: string;
|
|
144
|
+
expiresAt?: string;
|
|
145
|
+
idempotencyKey: string;
|
|
146
|
+
/** Empty/omitted ⇒ any responder the runtime authenticates may answer. */
|
|
147
|
+
allowedResponders?: CanonicalAgentId[];
|
|
148
|
+
}
|
|
149
|
+
/** A signed answer to an interrupt. It resumes the run — it never itself
|
|
150
|
+
* grants authority (spec 309 §6.2). */
|
|
151
|
+
export interface InteractionResumeV1 {
|
|
152
|
+
version: 'ap.interaction.resume.v1';
|
|
153
|
+
interruptId: InteractionInterruptId;
|
|
154
|
+
responder: CanonicalAgentId;
|
|
155
|
+
at: string;
|
|
156
|
+
response?: unknown;
|
|
157
|
+
idempotencyKey: string;
|
|
158
|
+
signature?: SignatureProof;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/interactions/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// @agenticprimitives/interactions — case, payload, and run types (spec 309 §6).
|
|
2
|
+
//
|
|
3
|
+
// Doctrine: an interaction NEVER mints authority. It references delegation /
|
|
4
|
+
// entitlement / credential artifacts by hash or vault ref (`AuthorityRef`) and
|
|
5
|
+
// tracks the lifecycle around them; verification stays in the owning packages.
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/interactions/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,6EAA6E;AAC7E,+EAA+E;AAC/E,+EAA+E"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { ConversationDescriptorV1, MessageEnvelopeV1 } from './types.js';
|
|
3
|
+
export interface ChannelMessageEntryV1 {
|
|
4
|
+
envelope: MessageEnvelopeV1;
|
|
5
|
+
authorName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ChannelV1 {
|
|
8
|
+
descriptor: ConversationDescriptorV1;
|
|
9
|
+
title: string;
|
|
10
|
+
createdBy: string;
|
|
11
|
+
messages: ChannelMessageEntryV1[];
|
|
12
|
+
visibility?: 'public' | 'private';
|
|
13
|
+
/** For a private topic: the member SAs (lowercased 0x) allowed to see/post. The creator is always included. */
|
|
14
|
+
members?: string[];
|
|
15
|
+
}
|
|
16
|
+
/** Can `viewerSa` (0x) see this topic? Public ⇒ always; private ⇒ only if listed in `members`. `isSteward`
|
|
17
|
+
* overrides (a steward manages every topic). One mechanism — used by the store list + the UI. */
|
|
18
|
+
export declare function canSeeChannel(channel: ChannelV1, viewerSa: string, isSteward?: boolean): boolean;
|
|
19
|
+
/** Bounded per-channel history in the board doc (projection only — bodies live in the vault). */
|
|
20
|
+
export declare const BOARD_HISTORY_LIMIT = 200;
|
|
21
|
+
export type BoardResult<T> = {
|
|
22
|
+
ok: true;
|
|
23
|
+
} & T | {
|
|
24
|
+
ok: false;
|
|
25
|
+
error: string;
|
|
26
|
+
};
|
|
27
|
+
/** Create a channel on the board (mutates `board` on success). Title-unique per context.
|
|
28
|
+
* `contextId` is the org/context SA (substrate vocabulary — spec 322 §5; the wire literal
|
|
29
|
+
* `kind:'community'` is inside signed hashes and renames only at 316's envelope re-cut). */
|
|
30
|
+
export declare function createBoardChannel(board: ChannelV1[], opts: {
|
|
31
|
+
contextId: string;
|
|
32
|
+
owner: CanonicalAgentId;
|
|
33
|
+
title: string;
|
|
34
|
+
createdBy: string;
|
|
35
|
+
now?: string;
|
|
36
|
+
visibility?: 'public' | 'private';
|
|
37
|
+
members?: string[];
|
|
38
|
+
creatorSa?: string;
|
|
39
|
+
}): BoardResult<{
|
|
40
|
+
channel: ChannelV1;
|
|
41
|
+
}>;
|
|
42
|
+
/** Build + append a post to a channel (mutates the channel on success). The envelope's body
|
|
43
|
+
* reference points at the board owner's vault (`message.body:<id>`); the CALLER persists the
|
|
44
|
+
* body there (hash-bound) and the board doc itself — this stays pure over the doc. */
|
|
45
|
+
export declare function appendBoardPost(board: ChannelV1[], opts: {
|
|
46
|
+
channelId: string;
|
|
47
|
+
from: CanonicalAgentId;
|
|
48
|
+
authorName: string;
|
|
49
|
+
bodyText: string;
|
|
50
|
+
now?: string;
|
|
51
|
+
}): Promise<BoardResult<{
|
|
52
|
+
envelope: MessageEnvelopeV1;
|
|
53
|
+
}>>;
|
|
54
|
+
//# sourceMappingURL=board.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/messaging/board.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAKjE,OAAO,KAAK,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,wBAAwB,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAGlC,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAClC,+GAA+G;IAC/G,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;kGACkG;AAClG,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAK9F;AAED,iGAAiG;AACjG,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,CAAC,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E;;6FAE6F;AAC7F,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,EAAE,EAClB,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9K,WAAW,CAAC;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,CAAC,CA+BrC;AAED;;uFAEuF;AACvF,wBAAsB,eAAe,CACnC,KAAK,EAAE,SAAS,EAAE,EAClB,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtG,OAAO,CAAC,WAAW,CAAC;IAAE,QAAQ,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAAC,CA8BvD"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { generateConversationId, generateMessageId, validateMessageEnvelope } from './envelope.js';
|
|
2
|
+
import { sha256Hex32 } from './hash.js';
|
|
3
|
+
import { validateConversationDescriptor } from './conversation.js';
|
|
4
|
+
import { topicBodyResource } from './vault-store.js';
|
|
5
|
+
/** Can `viewerSa` (0x) see this topic? Public ⇒ always; private ⇒ only if listed in `members`. `isSteward`
|
|
6
|
+
* overrides (a steward manages every topic). One mechanism — used by the store list + the UI. */
|
|
7
|
+
export function canSeeChannel(channel, viewerSa, isSteward = false) {
|
|
8
|
+
if (channel.visibility !== 'private')
|
|
9
|
+
return true;
|
|
10
|
+
if (isSteward)
|
|
11
|
+
return true;
|
|
12
|
+
const me = viewerSa.toLowerCase();
|
|
13
|
+
return (channel.members ?? []).some((m) => m.toLowerCase() === me);
|
|
14
|
+
}
|
|
15
|
+
/** Bounded per-channel history in the board doc (projection only — bodies live in the vault). */
|
|
16
|
+
export const BOARD_HISTORY_LIMIT = 200;
|
|
17
|
+
/** Create a channel on the board (mutates `board` on success). Title-unique per context.
|
|
18
|
+
* `contextId` is the org/context SA (substrate vocabulary — spec 322 §5; the wire literal
|
|
19
|
+
* `kind:'community'` is inside signed hashes and renames only at 316's envelope re-cut). */
|
|
20
|
+
export function createBoardChannel(board, opts) {
|
|
21
|
+
const title = opts.title.trim();
|
|
22
|
+
if (!title || title.length > 80)
|
|
23
|
+
return { ok: false, error: 'title required (≤ 80 chars)' };
|
|
24
|
+
if (board.some((c) => c.title.toLowerCase() === title.toLowerCase())) {
|
|
25
|
+
return { ok: false, error: 'a channel with this title already exists' };
|
|
26
|
+
}
|
|
27
|
+
const isPrivate = opts.visibility === 'private';
|
|
28
|
+
const descriptor = {
|
|
29
|
+
version: 'ap.conversation.v1',
|
|
30
|
+
id: generateConversationId(),
|
|
31
|
+
owner: opts.owner,
|
|
32
|
+
title,
|
|
33
|
+
participants: [opts.owner],
|
|
34
|
+
contextRefs: [{ kind: 'community', id: opts.contextId.toLowerCase() }],
|
|
35
|
+
participantPolicy: 'open-to-context',
|
|
36
|
+
createdAt: opts.now ?? new Date().toISOString(),
|
|
37
|
+
// spec 324 §10 — private topics are members-only; public inherit the org's conversation access.
|
|
38
|
+
...(isPrivate ? { confidentialityMode: 'members-only' } : {}),
|
|
39
|
+
};
|
|
40
|
+
const errors = validateConversationDescriptor(descriptor);
|
|
41
|
+
if (errors.length > 0)
|
|
42
|
+
return { ok: false, error: `invalid channel: ${errors.join(', ')}` };
|
|
43
|
+
// The creator is always a member of a private topic; dedupe + lowercase.
|
|
44
|
+
const members = isPrivate
|
|
45
|
+
? [...new Set([opts.creatorSa?.toLowerCase(), ...(opts.members ?? []).map((m) => m.toLowerCase())].filter((m) => !!m))]
|
|
46
|
+
: undefined;
|
|
47
|
+
const channel = {
|
|
48
|
+
descriptor, title, createdBy: opts.createdBy, messages: [],
|
|
49
|
+
...(isPrivate ? { visibility: 'private', members } : {}),
|
|
50
|
+
};
|
|
51
|
+
board.push(channel);
|
|
52
|
+
return { ok: true, channel };
|
|
53
|
+
}
|
|
54
|
+
/** Build + append a post to a channel (mutates the channel on success). The envelope's body
|
|
55
|
+
* reference points at the board owner's vault (`message.body:<id>`); the CALLER persists the
|
|
56
|
+
* body there (hash-bound) and the board doc itself — this stays pure over the doc. */
|
|
57
|
+
export async function appendBoardPost(board, opts) {
|
|
58
|
+
const bodyText = opts.bodyText.trim();
|
|
59
|
+
if (!opts.channelId || !bodyText)
|
|
60
|
+
return { ok: false, error: 'channelId + bodyText required' };
|
|
61
|
+
const channel = board.find((c) => c.descriptor.id === opts.channelId);
|
|
62
|
+
if (!channel)
|
|
63
|
+
return { ok: false, error: 'unknown channel' };
|
|
64
|
+
const now = opts.now ?? new Date().toISOString();
|
|
65
|
+
const messageId = generateMessageId();
|
|
66
|
+
const envelope = {
|
|
67
|
+
version: 'ap.message.v1',
|
|
68
|
+
id: messageId,
|
|
69
|
+
conversationId: channel.descriptor.id,
|
|
70
|
+
kind: 'plain',
|
|
71
|
+
from: opts.from,
|
|
72
|
+
// Shared-board addressing: the descriptor's owner stands for the board (spec 313 §6).
|
|
73
|
+
to: [channel.descriptor.owner],
|
|
74
|
+
createdAt: now,
|
|
75
|
+
classification: 'internal',
|
|
76
|
+
body: { resource: topicBodyResource(channel.descriptor.id, messageId), classification: 'internal', updatedAt: now },
|
|
77
|
+
bodyHash: await sha256Hex32(new TextEncoder().encode(bodyText)),
|
|
78
|
+
bodyContentType: 'text/plain',
|
|
79
|
+
contextRefs: channel.descriptor.contextRefs,
|
|
80
|
+
};
|
|
81
|
+
const errors = validateMessageEnvelope(envelope);
|
|
82
|
+
if (errors.length > 0)
|
|
83
|
+
return { ok: false, error: `invalid post: ${errors.join(', ')}` };
|
|
84
|
+
channel.messages.push({ envelope, authorName: opts.authorName });
|
|
85
|
+
if (channel.messages.length > BOARD_HISTORY_LIMIT) {
|
|
86
|
+
channel.messages.splice(0, channel.messages.length - BOARD_HISTORY_LIMIT);
|
|
87
|
+
}
|
|
88
|
+
return { ok: true, envelope };
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=board.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.js","sourceRoot":"","sources":["../../src/messaging/board.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ConversationDescriptorV1 } from './types.js';
|
|
2
|
+
export type ConversationValidationError = 'bad_version' | 'bad_id' | 'missing_owner' | 'empty_participants' | 'owner_not_participant' | 'bad_participant_policy' | 'bad_created_at' | 'too_many_context_refs' | 'bad_context_ref';
|
|
3
|
+
/** Structural validation, fail-closed. Empty array iff admissible. */
|
|
4
|
+
export declare function validateConversationDescriptor(d: ConversationDescriptorV1): ConversationValidationError[];
|
|
5
|
+
/**
|
|
6
|
+
* Group inbox items into conversation buckets, newest activity first — the
|
|
7
|
+
* conversation-first list the synthesis inbox renders (spec 312 §7.1).
|
|
8
|
+
* Pure over the projection; descriptors (when present) supply titles/anchors.
|
|
9
|
+
*/
|
|
10
|
+
export interface ConversationSummaryV1 {
|
|
11
|
+
conversationId: ConversationDescriptorV1['id'];
|
|
12
|
+
messageCount: number;
|
|
13
|
+
unread: number;
|
|
14
|
+
lastEventAt: string;
|
|
15
|
+
/** Union of context refs across the conversation's messages. */
|
|
16
|
+
contextRefs: {
|
|
17
|
+
kind: string;
|
|
18
|
+
id: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
}[];
|
|
21
|
+
/** True when any message in the conversation awaits review (pending folder). */
|
|
22
|
+
hasPending: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function summarizeConversations(items: readonly {
|
|
25
|
+
conversationId: ConversationDescriptorV1['id'];
|
|
26
|
+
folder: string;
|
|
27
|
+
unread: boolean;
|
|
28
|
+
lastEventAt: string;
|
|
29
|
+
contextRefs: {
|
|
30
|
+
kind: string;
|
|
31
|
+
id: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
}[];
|
|
34
|
+
}[]): ConversationSummaryV1[];
|
|
35
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/messaging/conversation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAK3D,MAAM,MAAM,2BAA2B,GACnC,aAAa,GACb,QAAQ,GACR,eAAe,GACf,oBAAoB,GACpB,uBAAuB,GACvB,wBAAwB,GACxB,gBAAgB,GAChB,uBAAuB,GACvB,iBAAiB,CAAC;AAQtB,sEAAsE;AACtE,wBAAgB,8BAA8B,CAC5C,CAAC,EAAE,wBAAwB,GAC1B,2BAA2B,EAAE,CAsB/B;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5D,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS;IACd,cAAc,EAAE,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7D,EAAE,GACF,qBAAqB,EAAE,CAwBzB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// ConversationDescriptorV1 (spec 312 §4.2) — projection metadata over an
|
|
2
|
+
// opaque ConversationId. A descriptor is a VIEW (title, participants, context
|
|
3
|
+
// anchors, append policy); it never authorizes delivery — admission validates
|
|
4
|
+
// every envelope independently, and each side keeps its own descriptor copy.
|
|
5
|
+
import { MAX_CONTEXT_REFS } from './envelope.js';
|
|
6
|
+
const HEX32_RE = /^0x[0-9a-f]{64}$/;
|
|
7
|
+
const POLICIES = [
|
|
8
|
+
'fixed',
|
|
9
|
+
'owner-managed',
|
|
10
|
+
'open-to-context',
|
|
11
|
+
];
|
|
12
|
+
/** Structural validation, fail-closed. Empty array iff admissible. */
|
|
13
|
+
export function validateConversationDescriptor(d) {
|
|
14
|
+
const errors = [];
|
|
15
|
+
if (d.version !== 'ap.conversation.v1')
|
|
16
|
+
errors.push('bad_version');
|
|
17
|
+
if (!d.id?.startsWith('conv_'))
|
|
18
|
+
errors.push('bad_id');
|
|
19
|
+
if (!d.owner)
|
|
20
|
+
errors.push('missing_owner');
|
|
21
|
+
if (!Array.isArray(d.participants) || d.participants.length === 0) {
|
|
22
|
+
errors.push('empty_participants');
|
|
23
|
+
}
|
|
24
|
+
else if (d.owner && !d.participants.some((p) => p.toLowerCase() === d.owner.toLowerCase())) {
|
|
25
|
+
errors.push('owner_not_participant');
|
|
26
|
+
}
|
|
27
|
+
if (!POLICIES.includes(d.participantPolicy))
|
|
28
|
+
errors.push('bad_participant_policy');
|
|
29
|
+
if (!d.createdAt || Number.isNaN(Date.parse(d.createdAt)))
|
|
30
|
+
errors.push('bad_created_at');
|
|
31
|
+
if (d.contextRefs !== undefined) {
|
|
32
|
+
if (d.contextRefs.length > MAX_CONTEXT_REFS)
|
|
33
|
+
errors.push('too_many_context_refs');
|
|
34
|
+
for (const ref of d.contextRefs) {
|
|
35
|
+
if (!ref.kind?.trim() || !ref.id?.trim() || (ref.hash !== undefined && !HEX32_RE.test(ref.hash))) {
|
|
36
|
+
errors.push('bad_context_ref');
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return errors;
|
|
42
|
+
}
|
|
43
|
+
export function summarizeConversations(items) {
|
|
44
|
+
const byConv = new Map();
|
|
45
|
+
for (const item of items) {
|
|
46
|
+
if (item.folder === 'trash')
|
|
47
|
+
continue;
|
|
48
|
+
const s = byConv.get(item.conversationId) ?? {
|
|
49
|
+
conversationId: item.conversationId,
|
|
50
|
+
messageCount: 0,
|
|
51
|
+
unread: 0,
|
|
52
|
+
lastEventAt: item.lastEventAt,
|
|
53
|
+
contextRefs: [],
|
|
54
|
+
hasPending: false,
|
|
55
|
+
};
|
|
56
|
+
s.messageCount += 1;
|
|
57
|
+
if (item.unread)
|
|
58
|
+
s.unread += 1;
|
|
59
|
+
if (item.lastEventAt > s.lastEventAt)
|
|
60
|
+
s.lastEventAt = item.lastEventAt;
|
|
61
|
+
if (item.folder === 'pending')
|
|
62
|
+
s.hasPending = true;
|
|
63
|
+
for (const ref of item.contextRefs) {
|
|
64
|
+
if (!s.contextRefs.some((r) => r.kind === ref.kind && r.id === ref.id)) {
|
|
65
|
+
s.contextRefs.push({ kind: ref.kind, id: ref.id, label: ref.label });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
byConv.set(item.conversationId, s);
|
|
69
|
+
}
|
|
70
|
+
return [...byConv.values()].sort((a, b) => b.lastEventAt.localeCompare(a.lastEventAt));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/messaging/conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AuditSink } from '@agenticprimitives/audit';
|
|
2
|
+
import type { InboxProjector } from './projector.js';
|
|
3
|
+
import type { MessageEnvelopeV1, MessageEventV1 } from './types.js';
|
|
4
|
+
import type { RuleApplication } from './rules.js';
|
|
5
|
+
export interface AuditedInboxDelivery {
|
|
6
|
+
/**
|
|
7
|
+
* Admit an inbound envelope into the recipient's projection. When
|
|
8
|
+
* `bodyBytes` is provided the body-hash binding is enforced (§8.4); pass the
|
|
9
|
+
* bytes fetched from the vault whenever the body was transported.
|
|
10
|
+
*/
|
|
11
|
+
admit(envelope: MessageEnvelopeV1, event: MessageEventV1, bodyBytes?: Uint8Array): Promise<RuleApplication>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createAuditedInboxDelivery(opts: {
|
|
14
|
+
projector: InboxProjector;
|
|
15
|
+
audit: AuditSink;
|
|
16
|
+
/** The admitting agent (recipient / inbox custodian) — audit actor id. */
|
|
17
|
+
recipient: string;
|
|
18
|
+
}): AuditedInboxDelivery;
|
|
19
|
+
//# sourceMappingURL=delivery.d.ts.map
|
|
@@ -0,0 +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,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAmBlD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,KAAK,CACH,QAAQ,EAAE,iBAAiB,EAC3B,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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Audited recipient-side admission (spec 309 §7 "direct app↔inbox", §8.4, §8.8).
|
|
2
|
+
//
|
|
3
|
+
// Fail-closed ordering: validate → verify body hash → AUDIT (await) → commit.
|
|
4
|
+
// If the audit write fails the message is NOT admitted (spec 291 discipline for
|
|
5
|
+
// privileged outcomes); rejects are audited as `denied` before throwing.
|
|
6
|
+
import { validateMessageEnvelope } from './envelope.js';
|
|
7
|
+
import { verifyBodyHash } from './hash.js';
|
|
8
|
+
function auditEventBase(envelope, recipient) {
|
|
9
|
+
return {
|
|
10
|
+
id: globalThis.crypto.randomUUID(),
|
|
11
|
+
timestamp: new Date().toISOString(),
|
|
12
|
+
actor: { type: 'service', id: recipient },
|
|
13
|
+
subject: { type: 'message', id: envelope.id },
|
|
14
|
+
// Hashes/ids only — never bodies, subjects, or PII (spec 309 §9).
|
|
15
|
+
context: {
|
|
16
|
+
from: envelope.from,
|
|
17
|
+
kind: envelope.kind,
|
|
18
|
+
classification: envelope.classification,
|
|
19
|
+
bodyHash: envelope.bodyHash,
|
|
20
|
+
conversationId: envelope.conversationId,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function createAuditedInboxDelivery(opts) {
|
|
25
|
+
const { projector, audit, recipient } = opts;
|
|
26
|
+
async function reject(envelope, reason) {
|
|
27
|
+
await audit.write({
|
|
28
|
+
...auditEventBase(envelope, recipient),
|
|
29
|
+
action: 'messaging.deliver.reject',
|
|
30
|
+
outcome: 'denied',
|
|
31
|
+
reason,
|
|
32
|
+
});
|
|
33
|
+
throw new Error(`message ${envelope.id} rejected: ${reason}`);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
async admit(envelope, event, bodyBytes) {
|
|
37
|
+
const errors = validateMessageEnvelope(envelope);
|
|
38
|
+
if (errors.length > 0)
|
|
39
|
+
return reject(envelope, `invalid envelope: ${errors.join(', ')}`);
|
|
40
|
+
if (event.messageId !== envelope.id)
|
|
41
|
+
return reject(envelope, 'event/envelope id mismatch');
|
|
42
|
+
if (bodyBytes !== undefined && !(await verifyBodyHash(envelope, bodyBytes))) {
|
|
43
|
+
return reject(envelope, 'bodyHash mismatch');
|
|
44
|
+
}
|
|
45
|
+
// Audit BEFORE commit — if this write throws, nothing was admitted.
|
|
46
|
+
await audit.write({
|
|
47
|
+
...auditEventBase(envelope, recipient),
|
|
48
|
+
action: 'messaging.deliver.accept',
|
|
49
|
+
outcome: 'success',
|
|
50
|
+
});
|
|
51
|
+
projector.putMessage(envelope);
|
|
52
|
+
return projector.appendEvent(event);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=delivery.js.map
|
|
@@ -0,0 +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,QAA2B,EAAE,SAAiB;IACpE,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,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,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,QAA2B,EAAE,MAAc;QAC/D,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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
import type { ContextRefV1, SignatureProof } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A member's self-signed presence listing in a community context (spec 312 §4.4 / 318 / 322).
|
|
5
|
+
* The membership source of truth for channel access: current listing + valid spec-321 delegation
|
|
6
|
+
* ⟹ member. Vault-resident (`directory.data` in the context org's vault at spec-322 W3) — never
|
|
7
|
+
* on-chain, never the public KB (ADR-0040; the opt-in anchor is a separate attestation).
|
|
8
|
+
*/
|
|
9
|
+
export interface DirectoryListingV1 {
|
|
10
|
+
type: 'ap.home.directory-listing.v1';
|
|
11
|
+
/** The person SA publishing themselves (self-published only). */
|
|
12
|
+
subject: CanonicalAgentId;
|
|
13
|
+
/** The community context this listing is scoped to (org SA, community id…). */
|
|
14
|
+
context: ContextRefV1;
|
|
15
|
+
displayName: string;
|
|
16
|
+
/** Display-only; not verified role claims. */
|
|
17
|
+
roles?: string[];
|
|
18
|
+
/** Where signed envelopes can be delivered (the subject's Home inbox). */
|
|
19
|
+
inboxEndpoint?: string;
|
|
20
|
+
visibility: 'community' | 'public';
|
|
21
|
+
publishedAt: string;
|
|
22
|
+
expiresAt?: string;
|
|
23
|
+
proof: SignatureProof;
|
|
24
|
+
}
|
|
25
|
+
export type ListingValidationError = 'bad_type' | 'missing_subject' | 'bad_context' | 'missing_display_name' | 'bad_visibility' | 'bad_published_at' | 'bad_expires_at' | 'missing_proof' | 'proof_not_subject';
|
|
26
|
+
/** Structural validation, fail-closed. The caller MUST additionally verify the
|
|
27
|
+
* proof signature against the subject SA (ERC-1271) before indexing AND at gate time
|
|
28
|
+
* (spec 322 §4) — a listing no one signed is not a listing. */
|
|
29
|
+
export declare function validateDirectoryListing(l: DirectoryListingV1): ListingValidationError[];
|
|
30
|
+
/** True iff the listing is currently in force. Expired ⇒ not discoverable. */
|
|
31
|
+
export declare function isListingCurrent(l: DirectoryListingV1, atIso: string): boolean;
|
|
32
|
+
//# sourceMappingURL=directory.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Structural validation, fail-closed. The caller MUST additionally verify the
|
|
2
|
+
* proof signature against the subject SA (ERC-1271) before indexing AND at gate time
|
|
3
|
+
* (spec 322 §4) — a listing no one signed is not a listing. */
|
|
4
|
+
export function validateDirectoryListing(l) {
|
|
5
|
+
const errors = [];
|
|
6
|
+
if (l.type !== 'ap.home.directory-listing.v1')
|
|
7
|
+
errors.push('bad_type');
|
|
8
|
+
if (!l.subject)
|
|
9
|
+
errors.push('missing_subject');
|
|
10
|
+
if (!l.context?.kind?.trim() || !l.context?.id?.trim())
|
|
11
|
+
errors.push('bad_context');
|
|
12
|
+
if (!l.displayName?.trim())
|
|
13
|
+
errors.push('missing_display_name');
|
|
14
|
+
if (l.visibility !== 'community' && l.visibility !== 'public')
|
|
15
|
+
errors.push('bad_visibility');
|
|
16
|
+
if (!l.publishedAt || Number.isNaN(Date.parse(l.publishedAt)))
|
|
17
|
+
errors.push('bad_published_at');
|
|
18
|
+
if (l.expiresAt !== undefined && Number.isNaN(Date.parse(l.expiresAt)))
|
|
19
|
+
errors.push('bad_expires_at');
|
|
20
|
+
if (!l.proof?.signature)
|
|
21
|
+
errors.push('missing_proof');
|
|
22
|
+
else if (l.subject && l.proof.signer.toLowerCase() !== l.subject.toLowerCase()) {
|
|
23
|
+
// Self-published only: the proof signer IS the subject (ADR-0025).
|
|
24
|
+
errors.push('proof_not_subject');
|
|
25
|
+
}
|
|
26
|
+
return errors;
|
|
27
|
+
}
|
|
28
|
+
/** True iff the listing is currently in force. Expired ⇒ not discoverable. */
|
|
29
|
+
export function isListingCurrent(l, atIso) {
|
|
30
|
+
const at = Date.parse(atIso);
|
|
31
|
+
if (Number.isNaN(at) || at < Date.parse(l.publishedAt))
|
|
32
|
+
return false;
|
|
33
|
+
return l.expiresAt === undefined || at < Date.parse(l.expiresAt);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/messaging/directory.ts"],"names":[],"mappings":"AA8CA;;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"}
|