@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.
Files changed (201) hide show
  1. package/CLAUDE.md +67 -0
  2. package/LICENSE +21 -0
  3. package/README.md +21 -0
  4. package/dist/case-machine.d.ts +76 -0
  5. package/dist/case-machine.d.ts.map +1 -0
  6. package/dist/case-machine.js +83 -0
  7. package/dist/case-machine.js.map +1 -0
  8. package/dist/client/index.d.ts +114 -0
  9. package/dist/client/index.d.ts.map +1 -0
  10. package/dist/client/index.js +76 -0
  11. package/dist/client/index.js.map +1 -0
  12. package/dist/cloudflare/authority-verdict-cache.d.ts +27 -0
  13. package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -0
  14. package/dist/cloudflare/authority-verdict-cache.js +66 -0
  15. package/dist/cloudflare/authority-verdict-cache.js.map +1 -0
  16. package/dist/cloudflare/channel-store.d.ts +61 -0
  17. package/dist/cloudflare/channel-store.d.ts.map +1 -0
  18. package/dist/cloudflare/channel-store.js +124 -0
  19. package/dist/cloudflare/channel-store.js.map +1 -0
  20. package/dist/cloudflare/exchange-store.d.ts +16 -0
  21. package/dist/cloudflare/exchange-store.d.ts.map +1 -0
  22. package/dist/cloudflare/exchange-store.js +45 -0
  23. package/dist/cloudflare/exchange-store.js.map +1 -0
  24. package/dist/cloudflare/gateway-tools.d.ts +28 -0
  25. package/dist/cloudflare/gateway-tools.d.ts.map +1 -0
  26. package/dist/cloudflare/gateway-tools.js +45 -0
  27. package/dist/cloudflare/gateway-tools.js.map +1 -0
  28. package/dist/cloudflare/index.d.ts +13 -0
  29. package/dist/cloudflare/index.d.ts.map +1 -0
  30. package/dist/cloudflare/index.js +20 -0
  31. package/dist/cloudflare/index.js.map +1 -0
  32. package/dist/cloudflare/orchestration-runtime.d.ts +28 -0
  33. package/dist/cloudflare/orchestration-runtime.d.ts.map +1 -0
  34. package/dist/cloudflare/orchestration-runtime.js +35 -0
  35. package/dist/cloudflare/orchestration-runtime.js.map +1 -0
  36. package/dist/cloudflare/outbox-store.d.ts +24 -0
  37. package/dist/cloudflare/outbox-store.d.ts.map +1 -0
  38. package/dist/cloudflare/outbox-store.js +42 -0
  39. package/dist/cloudflare/outbox-store.js.map +1 -0
  40. package/dist/cloudflare/principal-gateway-do.d.ts +234 -0
  41. package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -0
  42. package/dist/cloudflare/principal-gateway-do.js +369 -0
  43. package/dist/cloudflare/principal-gateway-do.js.map +1 -0
  44. package/dist/cloudflare/provenance-store.d.ts +9 -0
  45. package/dist/cloudflare/provenance-store.d.ts.map +1 -0
  46. package/dist/cloudflare/provenance-store.js +36 -0
  47. package/dist/cloudflare/provenance-store.js.map +1 -0
  48. package/dist/cloudflare/receipt-signer.d.ts +26 -0
  49. package/dist/cloudflare/receipt-signer.d.ts.map +1 -0
  50. package/dist/cloudflare/receipt-signer.js +69 -0
  51. package/dist/cloudflare/receipt-signer.js.map +1 -0
  52. package/dist/cloudflare/request-id-ledger.d.ts +13 -0
  53. package/dist/cloudflare/request-id-ledger.d.ts.map +1 -0
  54. package/dist/cloudflare/request-id-ledger.js +38 -0
  55. package/dist/cloudflare/request-id-ledger.js.map +1 -0
  56. package/dist/cloudflare/sql-vault.d.ts +10 -0
  57. package/dist/cloudflare/sql-vault.d.ts.map +1 -0
  58. package/dist/cloudflare/sql-vault.js +98 -0
  59. package/dist/cloudflare/sql-vault.js.map +1 -0
  60. package/dist/communicative-act.d.ts +47 -0
  61. package/dist/communicative-act.d.ts.map +1 -0
  62. package/dist/communicative-act.js +36 -0
  63. package/dist/communicative-act.js.map +1 -0
  64. package/dist/delivery-envelope.d.ts +38 -0
  65. package/dist/delivery-envelope.d.ts.map +1 -0
  66. package/dist/delivery-envelope.js +43 -0
  67. package/dist/delivery-envelope.js.map +1 -0
  68. package/dist/exchange-record.d.ts +131 -0
  69. package/dist/exchange-record.d.ts.map +1 -0
  70. package/dist/exchange-record.js +25 -0
  71. package/dist/exchange-record.js.map +1 -0
  72. package/dist/exchange-reducer.d.ts +25 -0
  73. package/dist/exchange-reducer.d.ts.map +1 -0
  74. package/dist/exchange-reducer.js +108 -0
  75. package/dist/exchange-reducer.js.map +1 -0
  76. package/dist/exchange-state.d.ts +56 -0
  77. package/dist/exchange-state.d.ts.map +1 -0
  78. package/dist/exchange-state.js +81 -0
  79. package/dist/exchange-state.js.map +1 -0
  80. package/dist/gateway-surface.d.ts +24 -0
  81. package/dist/gateway-surface.d.ts.map +1 -0
  82. package/dist/gateway-surface.js +33 -0
  83. package/dist/gateway-surface.js.map +1 -0
  84. package/dist/inbox-doc.d.ts +32 -0
  85. package/dist/inbox-doc.d.ts.map +1 -0
  86. package/dist/inbox-doc.js +57 -0
  87. package/dist/inbox-doc.js.map +1 -0
  88. package/dist/inbox-projection.d.ts +15 -0
  89. package/dist/inbox-projection.d.ts.map +1 -0
  90. package/dist/inbox-projection.js +28 -0
  91. package/dist/inbox-projection.js.map +1 -0
  92. package/dist/index.d.ts +19 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.js +30 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/interactions/audited.d.ts +12 -0
  97. package/dist/interactions/audited.d.ts.map +1 -0
  98. package/dist/interactions/audited.js +67 -0
  99. package/dist/interactions/audited.js.map +1 -0
  100. package/dist/interactions/builders.d.ts +24 -0
  101. package/dist/interactions/builders.d.ts.map +1 -0
  102. package/dist/interactions/builders.js +48 -0
  103. package/dist/interactions/builders.js.map +1 -0
  104. package/dist/interactions/cards.d.ts +32 -0
  105. package/dist/interactions/cards.d.ts.map +1 -0
  106. package/dist/interactions/cards.js +20 -0
  107. package/dist/interactions/cards.js.map +1 -0
  108. package/dist/interactions/index.d.ts +15 -0
  109. package/dist/interactions/index.d.ts.map +1 -0
  110. package/dist/interactions/index.js +23 -0
  111. package/dist/interactions/index.js.map +1 -0
  112. package/dist/interactions/machine.d.ts +19 -0
  113. package/dist/interactions/machine.d.ts.map +1 -0
  114. package/dist/interactions/machine.js +31 -0
  115. package/dist/interactions/machine.js.map +1 -0
  116. package/dist/interactions/mandates.d.ts +64 -0
  117. package/dist/interactions/mandates.d.ts.map +1 -0
  118. package/dist/interactions/mandates.js +62 -0
  119. package/dist/interactions/mandates.js.map +1 -0
  120. package/dist/interactions/relationship.d.ts +29 -0
  121. package/dist/interactions/relationship.d.ts.map +1 -0
  122. package/dist/interactions/relationship.js +31 -0
  123. package/dist/interactions/relationship.js.map +1 -0
  124. package/dist/interactions/risk.d.ts +39 -0
  125. package/dist/interactions/risk.d.ts.map +1 -0
  126. package/dist/interactions/risk.js +49 -0
  127. package/dist/interactions/risk.js.map +1 -0
  128. package/dist/interactions/runs.d.ts +26 -0
  129. package/dist/interactions/runs.d.ts.map +1 -0
  130. package/dist/interactions/runs.js +80 -0
  131. package/dist/interactions/runs.js.map +1 -0
  132. package/dist/interactions/store.d.ts +20 -0
  133. package/dist/interactions/store.d.ts.map +1 -0
  134. package/dist/interactions/store.js +68 -0
  135. package/dist/interactions/store.js.map +1 -0
  136. package/dist/interactions/tickets.d.ts +68 -0
  137. package/dist/interactions/tickets.d.ts.map +1 -0
  138. package/dist/interactions/tickets.js +49 -0
  139. package/dist/interactions/tickets.js.map +1 -0
  140. package/dist/interactions/types.d.ts +160 -0
  141. package/dist/interactions/types.d.ts.map +1 -0
  142. package/dist/interactions/types.js +7 -0
  143. package/dist/interactions/types.js.map +1 -0
  144. package/dist/messaging/board.d.ts +54 -0
  145. package/dist/messaging/board.d.ts.map +1 -0
  146. package/dist/messaging/board.js +90 -0
  147. package/dist/messaging/board.js.map +1 -0
  148. package/dist/messaging/conversation.d.ts +35 -0
  149. package/dist/messaging/conversation.d.ts.map +1 -0
  150. package/dist/messaging/conversation.js +72 -0
  151. package/dist/messaging/conversation.js.map +1 -0
  152. package/dist/messaging/delivery.d.ts +19 -0
  153. package/dist/messaging/delivery.d.ts.map +1 -0
  154. package/dist/messaging/delivery.js +56 -0
  155. package/dist/messaging/delivery.js.map +1 -0
  156. package/dist/messaging/directory.d.ts +32 -0
  157. package/dist/messaging/directory.d.ts.map +1 -0
  158. package/dist/messaging/directory.js +35 -0
  159. package/dist/messaging/directory.js.map +1 -0
  160. package/dist/messaging/envelope.d.ts +14 -0
  161. package/dist/messaging/envelope.d.ts.map +1 -0
  162. package/dist/messaging/envelope.js +71 -0
  163. package/dist/messaging/envelope.js.map +1 -0
  164. package/dist/messaging/hash.d.ts +19 -0
  165. package/dist/messaging/hash.d.ts.map +1 -0
  166. package/dist/messaging/hash.js +36 -0
  167. package/dist/messaging/hash.js.map +1 -0
  168. package/dist/messaging/index.d.ts +16 -0
  169. package/dist/messaging/index.d.ts.map +1 -0
  170. package/dist/messaging/index.js +29 -0
  171. package/dist/messaging/index.js.map +1 -0
  172. package/dist/messaging/projector.d.ts +58 -0
  173. package/dist/messaging/projector.d.ts.map +1 -0
  174. package/dist/messaging/projector.js +103 -0
  175. package/dist/messaging/projector.js.map +1 -0
  176. package/dist/messaging/receipts.d.ts +5 -0
  177. package/dist/messaging/receipts.d.ts.map +1 -0
  178. package/dist/messaging/receipts.js +19 -0
  179. package/dist/messaging/receipts.js.map +1 -0
  180. package/dist/messaging/rules.d.ts +84 -0
  181. package/dist/messaging/rules.d.ts.map +1 -0
  182. package/dist/messaging/rules.js +109 -0
  183. package/dist/messaging/rules.js.map +1 -0
  184. package/dist/messaging/store.d.ts +24 -0
  185. package/dist/messaging/store.d.ts.map +1 -0
  186. package/dist/messaging/store.js +120 -0
  187. package/dist/messaging/store.js.map +1 -0
  188. package/dist/messaging/types.d.ts +166 -0
  189. package/dist/messaging/types.d.ts.map +1 -0
  190. package/dist/messaging/types.js +7 -0
  191. package/dist/messaging/types.js.map +1 -0
  192. package/dist/messaging/vault-store.d.ts +37 -0
  193. package/dist/messaging/vault-store.d.ts.map +1 -0
  194. package/dist/messaging/vault-store.js +62 -0
  195. package/dist/messaging/vault-store.js.map +1 -0
  196. package/dist/record-catalog.d.ts +22 -0
  197. package/dist/record-catalog.d.ts.map +1 -0
  198. package/dist/record-catalog.js +35 -0
  199. package/dist/record-catalog.js.map +1 -0
  200. package/package.json +82 -0
  201. package/spec.md +15 -0
@@ -0,0 +1,61 @@
1
+ export interface ChannelV1 {
2
+ channelId: string;
3
+ org: string;
4
+ title: string;
5
+ createdAt: string;
6
+ /** Token-gate (spec 318 C3): an entitlement requirement a joiner's credential must satisfy (opaque to the
7
+ * store — the DO's injected `verifyEntitlement` interprets it). Absent ⇒ open join. */
8
+ joinGate?: string;
9
+ }
10
+ /** The actions a `ConversationRoleProjection` can cache authority for (spec 324 §8). NOT an ordinal hierarchy —
11
+ * an explicit capability bundle: `post` (participate), `moderate` (remove/pin), `manage` (assign roles / set
12
+ * projections). A projection lists exactly the actions its underlying delegation authorizes. */
13
+ export type ConversationRoleAction = 'post' | 'moderate' | 'manage';
14
+ /** spec 324 §8 — a CACHE of an org-issued `RoleAssignment` + the delegation it materializes, scoped to one
15
+ * conversation. Never authority's source: `roleAssignmentRef`/`delegationHash` point AT the real artifacts and
16
+ * `authorizedActions` is the resolved bundle re-derived on refresh. The org changes a member's in-conversation
17
+ * authority by re-issuing / revoking the delegation, then re-projecting — the DO only gates on the cache. */
18
+ export interface ConversationRoleProjection {
19
+ conversationId: string;
20
+ agentId: string;
21
+ roleAssignmentRef: string;
22
+ delegationHash: string;
23
+ authorizedActions: ConversationRoleAction[];
24
+ /** Cache staleness bound (ISO), matching the materializing delegation's validity. Absent ⇒ no cached expiry. */
25
+ expiresAt?: string;
26
+ /** Monotonic revision for staleness / CAS against the projecting writer. */
27
+ projectionRevision: number;
28
+ }
29
+ /** Does the cached projection authorize `action` at instant `at`? Fail-closed: no projection ⇒ false; an
30
+ * expired cache ⇒ false (a refresh from the live delegation is required). The action must be in the bundle —
31
+ * there is NO ordinal fall-through (an `admin` is not implicitly a `moderator`; the bundle lists every action). */
32
+ export declare function projectionAuthorizes(p: ConversationRoleProjection | null, action: ConversationRoleAction, at?: string): boolean;
33
+ export interface ChannelStore {
34
+ createChannel(channel: ChannelV1): Promise<void>;
35
+ getChannel(channelId: string): Promise<ChannelV1 | null>;
36
+ join(channelId: string, member: string): Promise<void>;
37
+ leave(channelId: string, member: string): Promise<void>;
38
+ isMember(channelId: string, member: string): Promise<boolean>;
39
+ members(channelId: string): Promise<string[]>;
40
+ /** Upsert the cached role projection for an agent in a conversation (the org's projecting writer calls this
41
+ * after issuing the RoleAssignment + materializing delegation). */
42
+ putRoleProjection(projection: ConversationRoleProjection): Promise<void>;
43
+ /** The agent's cached projection, or `null` if none is projected. */
44
+ roleProjection(conversationId: string, agentId: string): Promise<ConversationRoleProjection | null>;
45
+ /** Drop the cached projection (the org revoked the underlying delegation / demoted the assignment). */
46
+ clearRoleProjection(conversationId: string, agentId: string): Promise<void>;
47
+ /** All cached projections for a conversation. */
48
+ roleProjections(conversationId: string): Promise<ConversationRoleProjection[]>;
49
+ /** Index a post (the full exchange lives in the exchange store). */
50
+ addPost(channelId: string, exchangeId: string, at: string): Promise<void>;
51
+ /** Un-index a post (moderation remove). */
52
+ removePost(channelId: string, exchangeId: string): Promise<void>;
53
+ /** The channel's post exchange ids, newest first. */
54
+ postIds(channelId: string): Promise<string[]>;
55
+ addBot(channelId: string, botSA: string): Promise<void>;
56
+ removeBot(channelId: string, botSA: string): Promise<void>;
57
+ isBot(channelId: string, botSA: string): Promise<boolean>;
58
+ bots(channelId: string): Promise<string[]>;
59
+ }
60
+ export declare function createDurableObjectChannelStore(sql: SqlStorage): ChannelStore;
61
+ //# sourceMappingURL=channel-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-store.d.ts","sourceRoot":"","sources":["../../src/cloudflare/channel-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ /// <reference types="@cloudflare/workers-types" />
2
+ // Channel store (spec 318 C1 / spec 316 Blocker 6 Defect B — the org SA's gateway DO as a shared board, L2).
3
+ //
4
+ // A channel is a shared CONTEXT resident in the ORG SA's own `PrincipalGatewayDO`: posts are exchanges on the
5
+ // org's single-writer stream (the exchange store holds the full record); this store holds the channel's
6
+ // membership + its post index. Membership is the ORG's policy (projected from the app's directory listing —
7
+ // spec 313); the store tracks the set and gates posting fail-closed. Replaces the ad-hoc per-community KV doc
8
+ // (`channels.ts` `CHANNELS_KEY`). Stored on `state.storage.sql`, co-located with the exchange stream + vault.
9
+ //
10
+ // spec 324 §8 — ROLES ARE NOT AUTHORITY. The old `channel_members.role` ordinal (member/moderator/admin) is
11
+ // GONE: membership is now a plain set, and a member's authority-in-conversation is a
12
+ // `ConversationRoleProjection` — a CACHE of a real org-issued RoleAssignment + its materializing delegation,
13
+ // never authority's source (ADR-0048 #4/#10). The DO gates locally on the cached bundle; the org re-issues /
14
+ // revokes the underlying delegation to change it.
15
+ const CREATE_CHANNELS = `CREATE TABLE IF NOT EXISTS channels (
16
+ channel_id TEXT PRIMARY KEY, org TEXT NOT NULL, title TEXT NOT NULL, created_at TEXT NOT NULL, join_gate TEXT
17
+ )`;
18
+ const CREATE_BOTS = `CREATE TABLE IF NOT EXISTS channel_bots (
19
+ channel_id TEXT NOT NULL, bot_sa TEXT NOT NULL, PRIMARY KEY (channel_id, bot_sa)
20
+ )`;
21
+ const CREATE_MEMBERS = `CREATE TABLE IF NOT EXISTS channel_members (
22
+ channel_id TEXT NOT NULL, member TEXT NOT NULL, PRIMARY KEY (channel_id, member)
23
+ )`;
24
+ const CREATE_ROLE_PROJECTIONS = `CREATE TABLE IF NOT EXISTS conversation_role_projections (
25
+ conversation_id TEXT NOT NULL, agent_id TEXT NOT NULL, role_assignment_ref TEXT NOT NULL,
26
+ delegation_hash TEXT NOT NULL, authorized_actions TEXT NOT NULL, expires_at TEXT, projection_revision INTEGER NOT NULL DEFAULT 0,
27
+ PRIMARY KEY (conversation_id, agent_id)
28
+ )`;
29
+ const CREATE_POSTS = `CREATE TABLE IF NOT EXISTS channel_posts (
30
+ channel_id TEXT NOT NULL, exchange_id TEXT NOT NULL, at TEXT NOT NULL, PRIMARY KEY (channel_id, exchange_id)
31
+ )`;
32
+ /** Does the cached projection authorize `action` at instant `at`? Fail-closed: no projection ⇒ false; an
33
+ * expired cache ⇒ false (a refresh from the live delegation is required). The action must be in the bundle —
34
+ * there is NO ordinal fall-through (an `admin` is not implicitly a `moderator`; the bundle lists every action). */
35
+ export function projectionAuthorizes(p, action, at) {
36
+ if (!p)
37
+ return false;
38
+ if (p.expiresAt && at && p.expiresAt <= at)
39
+ return false;
40
+ return p.authorizedActions.includes(action);
41
+ }
42
+ function rowToProjection(conversationId, r) {
43
+ return {
44
+ conversationId,
45
+ agentId: r.agent_id,
46
+ roleAssignmentRef: r.role_assignment_ref,
47
+ delegationHash: r.delegation_hash,
48
+ authorizedActions: JSON.parse(r.authorized_actions),
49
+ ...(r.expires_at ? { expiresAt: r.expires_at } : {}),
50
+ projectionRevision: r.projection_revision,
51
+ };
52
+ }
53
+ export function createDurableObjectChannelStore(sql) {
54
+ sql.exec(CREATE_CHANNELS);
55
+ sql.exec(CREATE_MEMBERS);
56
+ sql.exec(CREATE_ROLE_PROJECTIONS);
57
+ sql.exec(CREATE_POSTS);
58
+ sql.exec(CREATE_BOTS);
59
+ const lc = (s) => s.toLowerCase();
60
+ return {
61
+ async createChannel(c) {
62
+ sql.exec(`INSERT INTO channels (channel_id, org, title, created_at, join_gate) VALUES (?, ?, ?, ?, ?)
63
+ ON CONFLICT(channel_id) DO UPDATE SET title = excluded.title, join_gate = excluded.join_gate`, c.channelId, lc(c.org), c.title, c.createdAt, c.joinGate ?? null);
64
+ },
65
+ async getChannel(channelId) {
66
+ const r = sql.exec('SELECT * FROM channels WHERE channel_id = ?', channelId).toArray()[0];
67
+ return r ? { channelId: r.channel_id, org: r.org, title: r.title, createdAt: r.created_at, joinGate: r.join_gate ?? undefined } : null;
68
+ },
69
+ async join(channelId, member) {
70
+ sql.exec('INSERT OR IGNORE INTO channel_members (channel_id, member) VALUES (?, ?)', channelId, lc(member));
71
+ },
72
+ async leave(channelId, member) {
73
+ sql.exec('DELETE FROM channel_members WHERE channel_id = ? AND member = ?', channelId, lc(member));
74
+ sql.exec('DELETE FROM conversation_role_projections WHERE conversation_id = ? AND agent_id = ?', channelId, lc(member));
75
+ },
76
+ async isMember(channelId, member) {
77
+ return sql.exec('SELECT 1 FROM channel_members WHERE channel_id = ? AND member = ?', channelId, lc(member)).toArray().length > 0;
78
+ },
79
+ async members(channelId) {
80
+ return sql.exec('SELECT member FROM channel_members WHERE channel_id = ? ORDER BY member', channelId).toArray().map((r) => r.member);
81
+ },
82
+ async putRoleProjection(p) {
83
+ sql.exec(`INSERT INTO conversation_role_projections
84
+ (conversation_id, agent_id, role_assignment_ref, delegation_hash, authorized_actions, expires_at, projection_revision)
85
+ VALUES (?, ?, ?, ?, ?, ?, ?)
86
+ ON CONFLICT(conversation_id, agent_id) DO UPDATE SET
87
+ role_assignment_ref = excluded.role_assignment_ref, delegation_hash = excluded.delegation_hash,
88
+ authorized_actions = excluded.authorized_actions, expires_at = excluded.expires_at,
89
+ projection_revision = excluded.projection_revision`, p.conversationId, lc(p.agentId), p.roleAssignmentRef, p.delegationHash, JSON.stringify(p.authorizedActions), p.expiresAt ?? null, p.projectionRevision);
90
+ },
91
+ async roleProjection(conversationId, agentId) {
92
+ const r = sql.exec('SELECT * FROM conversation_role_projections WHERE conversation_id = ? AND agent_id = ?', conversationId, lc(agentId)).toArray()[0];
93
+ return r ? rowToProjection(conversationId, r) : null;
94
+ },
95
+ async clearRoleProjection(conversationId, agentId) {
96
+ sql.exec('DELETE FROM conversation_role_projections WHERE conversation_id = ? AND agent_id = ?', conversationId, lc(agentId));
97
+ },
98
+ async roleProjections(conversationId) {
99
+ return sql.exec('SELECT * FROM conversation_role_projections WHERE conversation_id = ? ORDER BY agent_id', conversationId).toArray().map((r) => rowToProjection(conversationId, r));
100
+ },
101
+ async addPost(channelId, exchangeId, at) {
102
+ sql.exec('INSERT OR IGNORE INTO channel_posts (channel_id, exchange_id, at) VALUES (?, ?, ?)', channelId, exchangeId, at);
103
+ },
104
+ async removePost(channelId, exchangeId) {
105
+ sql.exec('DELETE FROM channel_posts WHERE channel_id = ? AND exchange_id = ?', channelId, exchangeId);
106
+ },
107
+ async postIds(channelId) {
108
+ return sql.exec('SELECT exchange_id FROM channel_posts WHERE channel_id = ? ORDER BY at DESC', channelId).toArray().map((r) => r.exchange_id);
109
+ },
110
+ async addBot(channelId, botSA) {
111
+ sql.exec('INSERT OR IGNORE INTO channel_bots (channel_id, bot_sa) VALUES (?, ?)', channelId, lc(botSA));
112
+ },
113
+ async removeBot(channelId, botSA) {
114
+ sql.exec('DELETE FROM channel_bots WHERE channel_id = ? AND bot_sa = ?', channelId, lc(botSA));
115
+ },
116
+ async isBot(channelId, botSA) {
117
+ return sql.exec('SELECT 1 FROM channel_bots WHERE channel_id = ? AND bot_sa = ?', channelId, lc(botSA)).toArray().length > 0;
118
+ },
119
+ async bots(channelId) {
120
+ return sql.exec('SELECT bot_sa FROM channel_bots WHERE channel_id = ? ORDER BY bot_sa', channelId).toArray().map((r) => r.bot_sa);
121
+ },
122
+ };
123
+ }
124
+ //# sourceMappingURL=channel-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-store.js","sourceRoot":"","sources":["../../src/cloudflare/channel-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ExchangeRecordV1, ExchangeEventV1, ExchangeId } from '../exchange-record.js';
2
+ import { type ExchangeApplyResult } from '../exchange-reducer.js';
3
+ /** Durable, single-writer store of `ExchangeRecordV1` snapshots for one principal's gateway DO. */
4
+ export interface ExchangeStore {
5
+ /** Seed / overwrite an exchange (e.g. T0 delivery persisting a freshly-built record). Single-writer. */
6
+ put(record: ExchangeRecordV1): Promise<void>;
7
+ /** The current record, or `null`. */
8
+ get(exchangeId: ExchangeId | string): Promise<ExchangeRecordV1 | null>;
9
+ /** Append one event: load → `applyExchangeEvent` → persist on success; the reducer's result is returned
10
+ * (a rejection does NOT mutate the row — fail-closed). `null` if the exchange is unknown. */
11
+ append(exchangeId: ExchangeId | string, event: ExchangeEventV1): Promise<ExchangeApplyResult | null>;
12
+ /** All exchanges, newest activity first (the inbox-projection source). */
13
+ list(): Promise<ExchangeRecordV1[]>;
14
+ }
15
+ export declare function createDurableObjectExchangeStore(sql: SqlStorage): ExchangeStore;
16
+ //# sourceMappingURL=exchange-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchange-store.d.ts","sourceRoot":"","sources":["../../src/cloudflare/exchange-store.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC3F,OAAO,EAAsB,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAiBtF,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAC5B,wGAAwG;IACxG,GAAG,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,qCAAqC;IACrC,GAAG,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACvE;kGAC8F;IAC9F,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACrG,0EAA0E;IAC1E,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CACrC;AAED,wBAAgB,gCAAgC,CAAC,GAAG,EAAE,UAAU,GAAG,aAAa,CAyC/E"}
@@ -0,0 +1,45 @@
1
+ import { applyExchangeEvent } from '../exchange-reducer.js';
2
+ const CREATE_TABLE = `CREATE TABLE IF NOT EXISTS exchange_records (
3
+ exchange_id TEXT PRIMARY KEY,
4
+ record_json TEXT NOT NULL,
5
+ rev INTEGER NOT NULL,
6
+ updated_at TEXT NOT NULL
7
+ )`;
8
+ const CREATE_INDEX = `CREATE INDEX IF NOT EXISTS idx_exchange_records_updated ON exchange_records (updated_at DESC)`;
9
+ export function createDurableObjectExchangeStore(sql) {
10
+ sql.exec(CREATE_TABLE);
11
+ sql.exec(CREATE_INDEX);
12
+ const save = (record) => {
13
+ sql.exec(`INSERT INTO exchange_records (exchange_id, record_json, rev, updated_at)
14
+ VALUES (?, ?, ?, ?)
15
+ ON CONFLICT(exchange_id) DO UPDATE SET
16
+ record_json = excluded.record_json, rev = excluded.rev, updated_at = excluded.updated_at`, record.exchangeId, JSON.stringify(record), record.rev, record.updatedAt);
17
+ };
18
+ return {
19
+ async put(record) {
20
+ save(record);
21
+ },
22
+ async get(exchangeId) {
23
+ const rows = sql
24
+ .exec('SELECT record_json FROM exchange_records WHERE exchange_id = ?', String(exchangeId))
25
+ .toArray();
26
+ return rows[0] ? JSON.parse(rows[0].record_json) : null;
27
+ },
28
+ async append(exchangeId, event) {
29
+ const current = await this.get(exchangeId);
30
+ if (!current)
31
+ return null;
32
+ const result = applyExchangeEvent(current, event);
33
+ if (result.ok)
34
+ save(result.record);
35
+ return result;
36
+ },
37
+ async list() {
38
+ const rows = sql
39
+ .exec('SELECT record_json FROM exchange_records ORDER BY updated_at DESC')
40
+ .toArray();
41
+ return rows.map((r) => JSON.parse(r.record_json));
42
+ },
43
+ };
44
+ }
45
+ //# sourceMappingURL=exchange-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exchange-store.js","sourceRoot":"","sources":["../../src/cloudflare/exchange-store.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAA4B,MAAM,wBAAwB,CAAC;AAEtF,MAAM,YAAY,GAAG;;;;;EAKnB,CAAC;AACH,MAAM,YAAY,GAAG,+FAA+F,CAAC;AAsBrH,MAAM,UAAU,gCAAgC,CAAC,GAAe;IAC9D,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEvB,MAAM,IAAI,GAAG,CAAC,MAAwB,EAAQ,EAAE;QAC9C,GAAG,CAAC,IAAI,CACN;;;kGAG4F,EAC5F,MAAM,CAAC,UAAU,EACjB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EACtB,MAAM,CAAC,GAAG,EACV,MAAM,CAAC,SAAS,CACjB,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,MAAM;YACd,IAAI,CAAC,MAAM,CAAC,CAAC;QACf,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,UAAU;YAClB,MAAM,IAAI,GAAG,GAAG;iBACb,IAAI,CAAc,gEAAgE,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;iBACvG,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;QAChF,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK;YAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC1B,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,EAAE;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACnC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,IAAI;YACR,MAAM,IAAI,GAAG,GAAG;iBACb,IAAI,CAAc,mEAAmE,CAAC;iBACtF,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAqB,CAAC,CAAC;QACxE,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { Vault } from '@agenticprimitives/vault';
2
+ export interface GatewayToolContext {
3
+ /** The verified principal (the delegation's delegator) the op runs as. */
4
+ principal: string;
5
+ /** The co-resident vault, already bound to `principal`'s owner-scope by the DO. */
6
+ vault: Vault;
7
+ args: Record<string, unknown>;
8
+ }
9
+ export interface GatewayTool {
10
+ name: string;
11
+ /** `read` tools are T1-fast-lane eligible (with `sensitivity=public`); `write` forces T2 (§3). */
12
+ effect: 'read' | 'write';
13
+ run(ctx: GatewayToolContext): Promise<unknown>;
14
+ }
15
+ export interface GatewayToolRegistry {
16
+ get(name: string): GatewayTool | undefined;
17
+ list(): GatewayTool[];
18
+ }
19
+ export declare function createToolRegistry(tools: GatewayTool[]): GatewayToolRegistry;
20
+ /**
21
+ * The built-in co-resident vault tools: `get_vault_record` / `set_vault_record` / `list_vault_record`,
22
+ * mirroring demo-mcp's surface but over the DO-local vault. `resource === recordType` directly (the DO vault
23
+ * is generic — no `vault:` prefix; the record-scope caveat that gates WHICH recordType is the DO's per-call
24
+ * caveat pass B, not the tool). `data: null` on set tombstones (fail-closed delete). Delegation authority is
25
+ * re-verified by the DO before any of these run (ADR-0041).
26
+ */
27
+ export declare function buildVaultTools(): GatewayTool[];
28
+ //# sourceMappingURL=gateway-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-tools.d.ts","sourceRoot":"","sources":["../../src/cloudflare/gateway-tools.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,GAAG,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAC3C,IAAI,IAAI,WAAW,EAAE,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAG5E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,WAAW,EAAE,CA8B/C"}
@@ -0,0 +1,45 @@
1
+ export function createToolRegistry(tools) {
2
+ const map = new Map(tools.map((t) => [t.name, t]));
3
+ return { get: (name) => map.get(name), list: () => [...map.values()] };
4
+ }
5
+ /**
6
+ * The built-in co-resident vault tools: `get_vault_record` / `set_vault_record` / `list_vault_record`,
7
+ * mirroring demo-mcp's surface but over the DO-local vault. `resource === recordType` directly (the DO vault
8
+ * is generic — no `vault:` prefix; the record-scope caveat that gates WHICH recordType is the DO's per-call
9
+ * caveat pass B, not the tool). `data: null` on set tombstones (fail-closed delete). Delegation authority is
10
+ * re-verified by the DO before any of these run (ADR-0041).
11
+ */
12
+ export function buildVaultTools() {
13
+ return [
14
+ {
15
+ name: 'get_vault_record',
16
+ effect: 'read',
17
+ async run({ principal, vault, args }) {
18
+ const recordType = String(args.recordType ?? '');
19
+ if (!recordType)
20
+ throw new Error('recordType required');
21
+ const obj = await vault.read({ owner: principal, resource: recordType });
22
+ return { recordType, data: obj?.data ?? null };
23
+ },
24
+ },
25
+ {
26
+ name: 'set_vault_record',
27
+ effect: 'write',
28
+ async run({ principal, vault, args }) {
29
+ const recordType = String(args.recordType ?? '');
30
+ if (!recordType)
31
+ throw new Error('recordType required');
32
+ await vault.write({ owner: principal, resource: recordType, data: args.data ?? null });
33
+ return { recordType, ok: true };
34
+ },
35
+ },
36
+ {
37
+ name: 'list_vault_record',
38
+ effect: 'read',
39
+ async run({ principal, vault }) {
40
+ return { records: await vault.list(principal) };
41
+ },
42
+ },
43
+ ];
44
+ }
45
+ //# sourceMappingURL=gateway-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-tools.js","sourceRoot":"","sources":["../../src/cloudflare/gateway-tools.ts"],"names":[],"mappings":"AA+BA,MAAM,UAAU,kBAAkB,CAAC,KAAoB;IACrD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AACzE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL;YACE,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,MAAM;YACd,KAAK,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;gBAClC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,UAAU;oBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBACxD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;gBACzE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC;YACjD,CAAC;SACF;QACD;YACE,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,OAAO;YACf,KAAK,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;gBAClC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;gBACjD,IAAI,CAAC,UAAU;oBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBACxD,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;gBACvF,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YAClC,CAAC;SACF;QACD;YACE,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE,MAAM;YACd,KAAK,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE;gBAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,CAAC;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ export { createDurableObjectSqlVault } from './sql-vault.js';
2
+ export { createDurableObjectExchangeStore, type ExchangeStore } from './exchange-store.js';
3
+ export { createDurableObjectOutboxStore, type OutboxStore, type OutboxEntry } from './outbox-store.js';
4
+ export { createDurableObjectProvenanceStore, type ProvenanceStore } from './provenance-store.js';
5
+ export { createDurableObjectChannelStore, projectionAuthorizes, type ChannelStore, type ChannelV1, type ConversationRoleProjection, type ConversationRoleAction, } from './channel-store.js';
6
+ export { createDurableObjectAuthorityVerdictCache, type AuthorityVerdictCache, type AuthorityVerdict, type AuthorityVerdictKey, } from './authority-verdict-cache.js';
7
+ export { createDurableObjectRequestIdLedger, type RequestIdLedger, type RequestIdReservation } from './request-id-ledger.js';
8
+ export { createDurableObjectReceiptSigner, verifyDeliveryReceipt, type DeliveryReceiptSigner, type DeliveryReceiptInput, type SignedDeliveryReceiptV1, } from './receipt-signer.js';
9
+ export { PrincipalGatewayDO, type PrincipalGatewayEnv, type GatewayDeps } from './principal-gateway-do.js';
10
+ export { buildVaultTools, createToolRegistry, type GatewayTool, type GatewayToolContext, type GatewayToolRegistry, } from './gateway-tools.js';
11
+ export { runGatewayOrchestration, gatewayToolSpecs, bindGatewayToolInvoker } from './orchestration-runtime.js';
12
+ export declare const FABRIC_CLOUDFLARE_ADAPTER_STATUS: "w2-coresident-mcp";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cloudflare/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,gCAAgC,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,8BAA8B,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvG,OAAO,EAAE,kCAAkC,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACjG,OAAO,EACL,+BAA+B,EAAE,oBAAoB,EACrD,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,0BAA0B,EAAE,KAAK,sBAAsB,GAChG,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,wCAAwC,EACxC,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kCAAkC,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC7H,OAAO,EACL,gCAAgC,EAChC,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC3G,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAE/G,eAAO,MAAM,gCAAgC,EAAG,mBAA4B,CAAC"}
@@ -0,0 +1,20 @@
1
+ // @agenticprimitives/fabric/cloudflare — the Cloudflare adapter for the PrincipalGatewayDO (spec 316 W2).
2
+ //
3
+ // The ONLY fabric subtree that touches `@cloudflare/workers-types`; the transport-agnostic core (`../`)
4
+ // never imports it (spec 316 §8 boundary — `.` = pure types/reducers, `./cloudflare` = the DO adapter).
5
+ // W2 lands incrementally: the DO-local SQLite vault (co-residency keystone, L2/§4.0) is the first piece;
6
+ // the `PrincipalGatewayDO` class + co-resident MCP + inbox/session/AuthorityVerdictCache/RequestIdLedger
7
+ // absorption follow in subsequent W2 steps.
8
+ export { createDurableObjectSqlVault } from './sql-vault.js';
9
+ export { createDurableObjectExchangeStore } from './exchange-store.js';
10
+ export { createDurableObjectOutboxStore } from './outbox-store.js';
11
+ export { createDurableObjectProvenanceStore } from './provenance-store.js';
12
+ export { createDurableObjectChannelStore, projectionAuthorizes, } from './channel-store.js';
13
+ export { createDurableObjectAuthorityVerdictCache, } from './authority-verdict-cache.js';
14
+ export { createDurableObjectRequestIdLedger } from './request-id-ledger.js';
15
+ export { createDurableObjectReceiptSigner, verifyDeliveryReceipt, } from './receipt-signer.js';
16
+ export { PrincipalGatewayDO } from './principal-gateway-do.js';
17
+ export { buildVaultTools, createToolRegistry, } from './gateway-tools.js';
18
+ export { runGatewayOrchestration, gatewayToolSpecs, bindGatewayToolInvoker } from './orchestration-runtime.js';
19
+ export const FABRIC_CLOUDFLARE_ADAPTER_STATUS = 'w2-coresident-mcp';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cloudflare/index.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,EAAE;AACF,wGAAwG;AACxG,wGAAwG;AACxG,yGAAyG;AACzG,yGAAyG;AACzG,4CAA4C;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,gCAAgC,EAAsB,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,8BAA8B,EAAsC,MAAM,mBAAmB,CAAC;AACvG,OAAO,EAAE,kCAAkC,EAAwB,MAAM,uBAAuB,CAAC;AACjG,OAAO,EACL,+BAA+B,EAAE,oBAAoB,GAEtD,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,wCAAwC,GAIzC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kCAAkC,EAAmD,MAAM,wBAAwB,CAAC;AAC7H,OAAO,EACL,gCAAgC,EAChC,qBAAqB,GAItB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAA8C,MAAM,2BAA2B,CAAC;AAC3G,OAAO,EACL,eAAe,EACf,kBAAkB,GAInB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAE/G,MAAM,CAAC,MAAM,gCAAgC,GAAG,mBAA4B,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { Vault } from '@agenticprimitives/vault';
2
+ import { type Intent, type Planner, type RunResult, type ToolInvoker, type ToolSpec } from '@agenticprimitives/orchestration';
3
+ import type { GatewayToolRegistry } from './gateway-tools.js';
4
+ /** The co-resident tools as the planner's tool catalog (id + description; the plan may only reference these). */
5
+ export declare function gatewayToolSpecs(registry: GatewayToolRegistry): ToolSpec[];
6
+ /** Bind the co-resident tool registry as an orchestration `ToolInvoker`: each planned step dispatches to a
7
+ * DO tool, run over `vault` under `principal`. Fail-closed on an unknown tool (the plan is validated against
8
+ * the tool catalog too, but this is the last line). */
9
+ export declare function bindGatewayToolInvoker(opts: {
10
+ registry: GatewayToolRegistry;
11
+ vault: Vault;
12
+ principal: string;
13
+ }): ToolInvoker;
14
+ /**
15
+ * Run a T2 intent to completion over the co-resident tools. `planner` is injected (LLM adapter in prod, the
16
+ * deterministic rule-based planner in tests). The loop is bounded (`maxSteps`); authority is NOT the loop's
17
+ * concern — the tools run under the already-verified `principal` (ADR-0041). Returns the orchestration
18
+ * `RunResult` (outcome + observations + composed result) the DO records onto the exchange stream.
19
+ */
20
+ export declare function runGatewayOrchestration(intent: Intent, opts: {
21
+ planner: Planner;
22
+ registry: GatewayToolRegistry;
23
+ vault: Vault;
24
+ principal: string;
25
+ maxSteps?: number;
26
+ maxReplans?: number;
27
+ }): Promise<RunResult>;
28
+ //# sourceMappingURL=orchestration-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration-runtime.d.ts","sourceRoot":"","sources":["../../src/cloudflare/orchestration-runtime.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAa,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACzI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,iHAAiH;AACjH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,QAAQ,EAAE,CAK1E;AAED;;wDAEwD;AACxD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAM5H;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,mBAAmB,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACjI,OAAO,CAAC,SAAS,CAAC,CAQpB"}
@@ -0,0 +1,35 @@
1
+ import { runIntent } from '@agenticprimitives/orchestration';
2
+ /** The co-resident tools as the planner's tool catalog (id + description; the plan may only reference these). */
3
+ export function gatewayToolSpecs(registry) {
4
+ return registry.list().map((t) => ({
5
+ id: t.name,
6
+ description: `${t.effect === 'read' ? 'Read' : 'Write'} co-resident vault tool ${t.name}.`,
7
+ }));
8
+ }
9
+ /** Bind the co-resident tool registry as an orchestration `ToolInvoker`: each planned step dispatches to a
10
+ * DO tool, run over `vault` under `principal`. Fail-closed on an unknown tool (the plan is validated against
11
+ * the tool catalog too, but this is the last line). */
12
+ export function bindGatewayToolInvoker(opts) {
13
+ return async (toolId, args) => {
14
+ const tool = opts.registry.get(toolId);
15
+ if (!tool)
16
+ throw new Error(`orchestration: unknown tool ${toolId}`);
17
+ return tool.run({ principal: opts.principal, vault: opts.vault, args });
18
+ };
19
+ }
20
+ /**
21
+ * Run a T2 intent to completion over the co-resident tools. `planner` is injected (LLM adapter in prod, the
22
+ * deterministic rule-based planner in tests). The loop is bounded (`maxSteps`); authority is NOT the loop's
23
+ * concern — the tools run under the already-verified `principal` (ADR-0041). Returns the orchestration
24
+ * `RunResult` (outcome + observations + composed result) the DO records onto the exchange stream.
25
+ */
26
+ export function runGatewayOrchestration(intent, opts) {
27
+ return runIntent(intent, {
28
+ planner: opts.planner,
29
+ tools: gatewayToolSpecs(opts.registry),
30
+ invoke: bindGatewayToolInvoker({ registry: opts.registry, vault: opts.vault, principal: opts.principal }),
31
+ maxSteps: opts.maxSteps,
32
+ maxReplans: opts.maxReplans,
33
+ });
34
+ }
35
+ //# sourceMappingURL=orchestration-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration-runtime.js","sourceRoot":"","sources":["../../src/cloudflare/orchestration-runtime.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAA8E,MAAM,kCAAkC,CAAC;AAGzI,iHAAiH;AACjH,MAAM,UAAU,gBAAgB,CAAC,QAA6B;IAC5D,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjC,EAAE,EAAE,CAAC,CAAC,IAAI;QACV,WAAW,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,2BAA2B,CAAC,CAAC,IAAI,GAAG;KAC3F,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;wDAEwD;AACxD,MAAM,UAAU,sBAAsB,CAAC,IAAwE;IAC7G,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAc,EACd,IAAkI;IAElI,OAAO,SAAS,CAAC,MAAM,EAAE;QACvB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACtC,MAAM,EAAE,sBAAsB,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACzG,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { DeliveryEnvelopeV1 } from '../delivery-envelope.js';
2
+ export interface OutboxEntry {
3
+ delivery: DeliveryEnvelopeV1;
4
+ nextAttemptAt: string;
5
+ attempts: number;
6
+ enqueuedAt: string;
7
+ }
8
+ export interface OutboxStore {
9
+ /** Enqueue (or re-enqueue) an undelivered peer delivery, idempotent by `delivery.nonce`. */
10
+ enqueue(delivery: DeliveryEnvelopeV1, opts: {
11
+ nextAttemptAt: string;
12
+ at: string;
13
+ }): Promise<void>;
14
+ /** Entries whose `nextAttemptAt <= now`, oldest-due first (the `alarm()` drain set). */
15
+ due(now: string): Promise<OutboxEntry[]>;
16
+ /** Remove on successful delivery. */
17
+ markDelivered(nonce: string): Promise<void>;
18
+ /** Backoff after a failed attempt: bump `attempts` + set the next attempt time. */
19
+ reschedule(nonce: string, nextAttemptAt: string): Promise<void>;
20
+ /** All queued entries. */
21
+ list(): Promise<OutboxEntry[]>;
22
+ }
23
+ export declare function createDurableObjectOutboxStore(sql: SqlStorage): OutboxStore;
24
+ //# sourceMappingURL=outbox-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-store.d.ts","sourceRoot":"","sources":["../../src/cloudflare/outbox-store.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAmBlE,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,4FAA4F;IAC5F,OAAO,CAAC,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG,wFAAwF;IACxF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACzC,qCAAqC;IACrC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,mFAAmF;IACnF,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,0BAA0B;IAC1B,IAAI,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;CAChC;AASD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,CAiC3E"}
@@ -0,0 +1,42 @@
1
+ const CREATE_TABLE = `CREATE TABLE IF NOT EXISTS outbox (
2
+ nonce TEXT PRIMARY KEY,
3
+ delivery_json TEXT NOT NULL,
4
+ next_attempt_at TEXT NOT NULL,
5
+ attempts INTEGER NOT NULL DEFAULT 0,
6
+ enqueued_at TEXT NOT NULL
7
+ )`;
8
+ const CREATE_IDX = `CREATE INDEX IF NOT EXISTS idx_outbox_due ON outbox (next_attempt_at)`;
9
+ const toEntry = (r) => ({
10
+ delivery: JSON.parse(r.delivery_json),
11
+ nextAttemptAt: r.next_attempt_at,
12
+ attempts: r.attempts,
13
+ enqueuedAt: r.enqueued_at,
14
+ });
15
+ export function createDurableObjectOutboxStore(sql) {
16
+ sql.exec(CREATE_TABLE);
17
+ sql.exec(CREATE_IDX);
18
+ return {
19
+ async enqueue(delivery, opts) {
20
+ sql.exec(`INSERT INTO outbox (nonce, delivery_json, next_attempt_at, attempts, enqueued_at)
21
+ VALUES (?, ?, ?, 0, ?)
22
+ ON CONFLICT(nonce) DO UPDATE SET
23
+ delivery_json = excluded.delivery_json, next_attempt_at = excluded.next_attempt_at`, delivery.nonce, JSON.stringify(delivery), opts.nextAttemptAt, opts.at);
24
+ },
25
+ async due(now) {
26
+ return sql
27
+ .exec('SELECT * FROM outbox WHERE next_attempt_at <= ? ORDER BY next_attempt_at', now)
28
+ .toArray()
29
+ .map(toEntry);
30
+ },
31
+ async markDelivered(nonce) {
32
+ sql.exec('DELETE FROM outbox WHERE nonce = ?', nonce);
33
+ },
34
+ async reschedule(nonce, nextAttemptAt) {
35
+ sql.exec('UPDATE outbox SET next_attempt_at = ?, attempts = attempts + 1 WHERE nonce = ?', nextAttemptAt, nonce);
36
+ },
37
+ async list() {
38
+ return sql.exec('SELECT * FROM outbox ORDER BY enqueued_at').toArray().map(toEntry);
39
+ },
40
+ };
41
+ }
42
+ //# sourceMappingURL=outbox-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-store.js","sourceRoot":"","sources":["../../src/cloudflare/outbox-store.ts"],"names":[],"mappings":"AAUA,MAAM,YAAY,GAAG;;;;;;EAMnB,CAAC;AACH,MAAM,UAAU,GAAG,uEAAuE,CAAC;AA8B3F,MAAM,OAAO,GAAG,CAAC,CAAY,EAAe,EAAE,CAAC,CAAC;IAC9C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAuB;IAC3D,aAAa,EAAE,CAAC,CAAC,eAAe;IAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;IACpB,UAAU,EAAE,CAAC,CAAC,WAAW;CAC1B,CAAC,CAAC;AAEH,MAAM,UAAU,8BAA8B,CAAC,GAAe;IAC5D,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAErB,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI;YAC1B,GAAG,CAAC,IAAI,CACN;;;8FAGsF,EACtF,QAAQ,CAAC,KAAK,EACd,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EACxB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,EAAE,CACR,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAG;YACX,OAAO,GAAG;iBACP,IAAI,CAAY,0EAA0E,EAAE,GAAG,CAAC;iBAChG,OAAO,EAAE;iBACT,GAAG,CAAC,OAAO,CAAC,CAAC;QAClB,CAAC;QACD,KAAK,CAAC,aAAa,CAAC,KAAK;YACvB,GAAG,CAAC,IAAI,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,aAAa;YACnC,GAAG,CAAC,IAAI,CAAC,gFAAgF,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;QACnH,CAAC;QACD,KAAK,CAAC,IAAI;YACR,OAAO,GAAG,CAAC,IAAI,CAAY,2CAA2C,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjG,CAAC;KACF,CAAC;AACJ,CAAC"}