@cello-protocol/daemon 0.0.230 → 0.0.232

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 (76) hide show
  1. package/dist/channel-admin-lookup.d.ts +54 -0
  2. package/dist/channel-admin-lookup.d.ts.map +1 -0
  3. package/dist/channel-admin-lookup.js +122 -0
  4. package/dist/channel-admin-lookup.js.map +1 -0
  5. package/dist/channel-collect-tick.d.ts +50 -4
  6. package/dist/channel-collect-tick.d.ts.map +1 -1
  7. package/dist/channel-collect-tick.js +103 -7
  8. package/dist/channel-collect-tick.js.map +1 -1
  9. package/dist/channel-config-store.d.ts +3 -0
  10. package/dist/channel-config-store.d.ts.map +1 -1
  11. package/dist/channel-config-store.js +28 -5
  12. package/dist/channel-config-store.js.map +1 -1
  13. package/dist/channel-join-exchange.d.ts +111 -0
  14. package/dist/channel-join-exchange.d.ts.map +1 -0
  15. package/dist/channel-join-exchange.js +296 -0
  16. package/dist/channel-join-exchange.js.map +1 -0
  17. package/dist/channel-membership-store.d.ts +118 -0
  18. package/dist/channel-membership-store.d.ts.map +1 -0
  19. package/dist/channel-membership-store.js +226 -0
  20. package/dist/channel-membership-store.js.map +1 -0
  21. package/dist/channel-membership-wiring.d.ts +98 -0
  22. package/dist/channel-membership-wiring.d.ts.map +1 -0
  23. package/dist/channel-membership-wiring.js +393 -0
  24. package/dist/channel-membership-wiring.js.map +1 -0
  25. package/dist/channel-publish-handlers.d.ts +8 -0
  26. package/dist/channel-publish-handlers.d.ts.map +1 -1
  27. package/dist/channel-publish-handlers.js +3 -0
  28. package/dist/channel-publish-handlers.js.map +1 -1
  29. package/dist/channel-publish-wiring.d.ts +21 -0
  30. package/dist/channel-publish-wiring.d.ts.map +1 -1
  31. package/dist/channel-publish-wiring.js +39 -3
  32. package/dist/channel-publish-wiring.js.map +1 -1
  33. package/dist/channel-publisher.d.ts +34 -2
  34. package/dist/channel-publisher.d.ts.map +1 -1
  35. package/dist/channel-publisher.js +46 -10
  36. package/dist/channel-publisher.js.map +1 -1
  37. package/dist/channel-subscription-store.d.ts +71 -0
  38. package/dist/channel-subscription-store.d.ts.map +1 -1
  39. package/dist/channel-subscription-store.js +150 -9
  40. package/dist/channel-subscription-store.js.map +1 -1
  41. package/dist/channel-wake-sender.d.ts +35 -0
  42. package/dist/channel-wake-sender.d.ts.map +1 -0
  43. package/dist/channel-wake-sender.js +61 -0
  44. package/dist/channel-wake-sender.js.map +1 -0
  45. package/dist/daemon.d.ts.map +1 -1
  46. package/dist/daemon.js +76 -1
  47. package/dist/daemon.js.map +1 -1
  48. package/dist/inbound-sessions.d.ts +6 -0
  49. package/dist/inbound-sessions.d.ts.map +1 -1
  50. package/dist/inbound-sessions.js +27 -1
  51. package/dist/inbound-sessions.js.map +1 -1
  52. package/dist/refusal-reasons.d.ts +7 -0
  53. package/dist/refusal-reasons.d.ts.map +1 -1
  54. package/dist/refusal-reasons.js +15 -0
  55. package/dist/refusal-reasons.js.map +1 -1
  56. package/dist/register-handler.d.ts.map +1 -1
  57. package/dist/register-handler.js +18 -1
  58. package/dist/register-handler.js.map +1 -1
  59. package/dist/registration-manager.d.ts +6 -0
  60. package/dist/registration-manager.d.ts.map +1 -1
  61. package/dist/registration-manager.js +9 -1
  62. package/dist/registration-manager.js.map +1 -1
  63. package/dist/session-content-context.d.ts +8 -0
  64. package/dist/session-content-context.d.ts.map +1 -1
  65. package/dist/session-content-ingest.d.ts.map +1 -1
  66. package/dist/session-content-ingest.js +28 -0
  67. package/dist/session-content-ingest.js.map +1 -1
  68. package/dist/session-node-manager.d.ts +4 -0
  69. package/dist/session-node-manager.d.ts.map +1 -1
  70. package/dist/session-node-manager.js +11 -0
  71. package/dist/session-node-manager.js.map +1 -1
  72. package/dist/signaling-wiring.d.ts +5 -0
  73. package/dist/signaling-wiring.d.ts.map +1 -1
  74. package/dist/signaling-wiring.js +14 -0
  75. package/dist/signaling-wiring.js.map +1 -1
  76. package/package.json +5 -5
@@ -0,0 +1,393 @@
1
+ import { channelJoinFrameType, encodeChannelRekey, buildChannelFetchKeyTbs, JOIN_REQUEST_TYPE, } from "@cello-protocol/protocol-types";
2
+ import { generateGroupKey, wrapGroupKeyFor, deriveFetchKey } from "@cello-protocol/crypto";
3
+ import { ChannelMembershipStore } from "./channel-membership-store.js";
4
+ import { ChannelSubscriptionStore } from "./channel-subscription-store.js";
5
+ import { createChannelJoinExchange, } from "./channel-join-exchange.js";
6
+ import { createChannelAdminLookup, } from "./channel-admin-lookup.js";
7
+ import { extractErrorMessage } from "./error-message.js";
8
+ /**
9
+ * M16 020-CHANADMIN — where the subscriber's admin key comes from.
10
+ *
11
+ * The join exchange compares the agent that answered against this. It is deliberately the ONLY
12
+ * source: the session proves who the counterparty is and says nothing about their authority over a
13
+ * channel, so "whoever answered" is exactly the hole the check exists to close.
14
+ *
15
+ * Two sources, in order:
16
+ * 1. **This daemon's own settings**, when we publish the channel. No round trip, and no directory
17
+ * outage in the path of a join to a channel running on this very machine.
18
+ * 2. **The directory**, for everything else. Before 020 there was no step 2 and this returned null
19
+ * for every channel not published here — so nobody could join anybody else's channel, or their
20
+ * own from a second device.
21
+ *
22
+ * ⚠️ **`null` MEANS REFUSE, AND EVERY UNKNOWN STILL ENDS HERE.** A directory that cannot be reached,
23
+ * one that faults, a pubkey that is not a channel, and a lookup that throws all answer `null`, which
24
+ * the exchange refuses as `admin_unresolved`. 020 removes a refusal that was firing on every
25
+ * channel; it must not weaken the one that remains.
26
+ */
27
+ export function createProfileAdminPubkey(deps) {
28
+ return async function profileAdminPubkey(channelHex, agentId) {
29
+ // The ADMIN this daemon recorded, not the channel's own key — the two are different agents, and
30
+ // comparing a key with itself is what the first version of this did.
31
+ const settings = deps.members.settings(channelHex);
32
+ if (settings && settings.admin_pubkey.length > 0) {
33
+ return { ok: true, adminPubkeyHex: settings.admin_pubkey };
34
+ }
35
+ try {
36
+ const outcome = await deps.lookup(agentId, channelHex);
37
+ if (outcome.kind === "admin")
38
+ return { ok: true, adminPubkeyHex: outcome.adminPubkeyHex };
39
+ // M16 021-WAKE item 21: the reason goes BACK, not just into a log. `admin_unresolved` alone
40
+ // cannot tell a dead stream from an unrolled directory from a channel that does not exist.
41
+ const reason = outcome.kind === "not_a_channel" ? "not_a_channel" : outcome.reason;
42
+ deps.logger.info("channel.join.admin_unresolved", { channel_pubkey: channelHex, reason });
43
+ return { ok: false, reason };
44
+ }
45
+ catch (err) {
46
+ // This runs inside the inbound content path. An exception escaping would surface as a broken
47
+ // session rather than a refused join, which is a worse answer to the same question.
48
+ const reason = extractErrorMessage(err);
49
+ deps.logger.warn("channel.join.admin_unresolved", { channel_pubkey: channelHex, reason });
50
+ return { ok: false, reason };
51
+ }
52
+ };
53
+ }
54
+ function needAgent(deps, params, connectionId) {
55
+ const agentName = deps.resolveCurrentAgent(connectionId, params?.["agent"]);
56
+ if (agentName === null) {
57
+ return {
58
+ ok: false,
59
+ answer: { ok: false, reason: "no_current_agent", guidance: "Name the agent, or select one with cello_use_agent." },
60
+ };
61
+ }
62
+ return { ok: true, agentName };
63
+ }
64
+ function needChannel(params) {
65
+ const raw = params?.["channel"];
66
+ if (typeof raw !== "string" || !/^[0-9a-fA-F]{64}$/.test(raw)) {
67
+ return {
68
+ ok: false,
69
+ answer: { ok: false, reason: "bad_channel", guidance: "Pass the channel's 64-character hex public key as `channel`." },
70
+ };
71
+ }
72
+ return { ok: true, channelHex: raw.toLowerCase() };
73
+ }
74
+ export function wireChannelMembership(deps) {
75
+ const { handlers, logger } = deps;
76
+ const members = new ChannelMembershipStore(deps.getDb(), logger);
77
+ const subscriptions = new ChannelSubscriptionStore(deps.getDb(), logger);
78
+ /**
79
+ * ⚠️ A CHANNEL IS AN AGENT THIS DAEMON HOLDS, looked up BY PUBKEY — the same rule the publisher
80
+ * follows, because the pubkey is the identity and the name is a mutable label. In this release the
81
+ * publisher and the admin are the SAME daemon; that is ASSERTED by returning null when the key is
82
+ * not here, rather than assumed anywhere downstream.
83
+ */
84
+ const localChannelAdmin = (channelHex) => {
85
+ const channel = deps.loadedAgents.find((a) => a.pubkey.toLowerCase() === channelHex.toLowerCase());
86
+ if (!channel)
87
+ return null;
88
+ /**
89
+ * ⚠️ **THE ADMIN IS A DIFFERENT AGENT FROM THE CHANNEL, and reading the channel's own key here
90
+ * was a defect.** The channel signs posts and never converses; the ADMIN holds the sessions and
91
+ * answers join requests. A subscriber compares the agent that answered against the admin key, so
92
+ * returning the channel's key made that comparison a key against itself — it could never
93
+ * succeed, in either direction, and the check was safe only by never passing.
94
+ *
95
+ * The admin is whichever agent ran the channel's setup, recorded then. No row, or an agent this
96
+ * daemon no longer holds, means this daemon cannot answer for the channel — which is the truth.
97
+ */
98
+ const settings = members.settings(channelHex);
99
+ if (!settings || settings.admin_pubkey.length === 0)
100
+ return null;
101
+ const adminAgent = deps.loadedAgents.find((a) => a.pubkey.toLowerCase() === settings.admin_pubkey.toLowerCase());
102
+ if (!adminAgent)
103
+ return null;
104
+ const adminKp = deps.keyProviders.get(adminAgent.name);
105
+ if (!adminKp)
106
+ return null;
107
+ return {
108
+ agentId: deps.resolveAgentId(adminAgent.name),
109
+ adminPubkeyHex: adminAgent.pubkey,
110
+ channelKeyProvider: channel.keyProvider,
111
+ adminKeyProvider: adminKp,
112
+ };
113
+ };
114
+ /**
115
+ * The join path carries an agent ID; `signalingFor` is keyed by the daemon's agent NAME. Resolved
116
+ * the same way `keyProviderFor` does it just below — by walking the loaded agents, because the ID
117
+ * is the stable key and the name is a mutable label.
118
+ */
119
+ const signalingForAgentId = (agentId) => {
120
+ const agent = deps.loadedAgents.find((a) => deps.resolveAgentId(a.name) === agentId);
121
+ return agent ? deps.signalingFor(agent.name) : null;
122
+ };
123
+ const profileAdminPubkey = createProfileAdminPubkey({
124
+ members,
125
+ logger,
126
+ lookup: createChannelAdminLookup({ signalingFor: signalingForAgentId, logger }),
127
+ });
128
+ const keyProviderFor = (agentId) => {
129
+ const agent = deps.loadedAgents.find((a) => deps.resolveAgentId(a.name) === agentId);
130
+ return agent ? (deps.keyProviders.get(agent.name) ?? null) : null;
131
+ };
132
+ const openSessionWith = (agentName, memberPubkeyHex) => {
133
+ const open = deps.activeSessionsFor(agentName)
134
+ .find((s) => s.counterpartyPubkeyHex.toLowerCase() === memberPubkeyHex.toLowerCase());
135
+ return open ? open.sessionId : null;
136
+ };
137
+ const raiseNotice = (event, channelHex, subscriberHex) => {
138
+ logger.info(event, { channel_pubkey: channelHex, subscriber_pubkey: subscriberHex });
139
+ };
140
+ /** Which agent a session belongs to, so the hook's answers go back down the right one. */
141
+ const exchangeFor = (agentName) => createChannelJoinExchange({
142
+ logger,
143
+ members,
144
+ subscriptions,
145
+ sendInSession: (sessionId, content) => deps.sendInSession(agentName, sessionId, content),
146
+ localChannelAdmin,
147
+ profileAdminPubkey,
148
+ keyProviderFor,
149
+ raiseNotice,
150
+ });
151
+ /**
152
+ * ⚠️ CLASSIFY SYNCHRONOUSLY, HANDLE ASYNCHRONOUSLY. The ingest path needs an immediate answer to
153
+ * decide whether these bytes are conversation; the admin and subscriber work — key wrapping,
154
+ * a directory lookup — cannot be done in that window.
155
+ */
156
+ deps.setOnChannelJoinFrame((agentName, sessionId, content, senderPubkey, correlationId) => {
157
+ /**
158
+ * ⚠️ **ROUTED BY FRAME TYPE, ONCE — trying the admin half first and falling through was a bug
159
+ * that made joining impossible.** `onAdminFrame` answers `consumed: true` for any join frame it
160
+ * cannot read as a REQUEST, so an acceptance or a re-key arriving at a SUBSCRIBER was absorbed
161
+ * there and the subscriber half was never called. A member sent a request, the admin admitted
162
+ * them and replied with the key, and their daemon appended a leaf and discarded it: no
163
+ * subscription, no key, and not one line saying anything had gone wrong. Every re-key after an
164
+ * ejection went the same way. The unit tests missed it because they call the two halves by hand.
165
+ */
166
+ const kind = channelJoinFrameType(content);
167
+ if (kind === null)
168
+ return { consumed: false };
169
+ const exchange = exchangeFor(agentName);
170
+ const agentId = deps.resolveAgentId(agentName);
171
+ void (async () => {
172
+ if (kind === JOIN_REQUEST_TYPE) {
173
+ await exchange.onAdminFrame(sessionId, senderPubkey, content);
174
+ return;
175
+ }
176
+ // An acceptance, a refusal or a re-key: all answers TO us, all the subscriber's business.
177
+ const asSubscriber = await exchange.onSubscriberFrame(agentId, sessionId, senderPubkey, content);
178
+ if (!asSubscriber.ok) {
179
+ logger.warn("channel.join.refused", {
180
+ ...(correlationId !== undefined ? { correlationId } : {}),
181
+ reason: asSubscriber.reason, sender: senderPubkey, frame_type: kind,
182
+ // ⚠️ THE LINE THE OPERATOR ACTUALLY READS — this is the one carrying correlationId, and
183
+ // the join path is fire-and-forget so there is no response to inspect either. Dropping
184
+ // `detail` here left `admin_unresolved` as bare as it was before item 21 fixed it, with
185
+ // the cause visible only on a second line that shares this event name.
186
+ ...(asSubscriber.detail !== undefined ? { detail: asSubscriber.detail } : {}),
187
+ });
188
+ }
189
+ })().catch((err) => {
190
+ // A rejected promise here must not take down the content path for every other session.
191
+ logger.error("channel.join.handling_failed", {
192
+ ...(correlationId !== undefined ? { correlationId } : {}),
193
+ reason: extractErrorMessage(err),
194
+ });
195
+ });
196
+ return { consumed: true };
197
+ });
198
+ // ─── Operator verbs ───────────────────────────────────────────────────────────────────────────
199
+ handlers.set("cello_channels", async (params, connectionId) => {
200
+ const agent = needAgent(deps, params, connectionId);
201
+ if (!agent.ok)
202
+ return agent.answer;
203
+ const agentId = deps.resolveAgentId(agent.agentName);
204
+ const rows = subscriptions.active().filter((s) => s.agent_id === agentId);
205
+ return Promise.resolve({
206
+ ok: true,
207
+ channels: rows.map((s) => ({
208
+ channel: s.channel_pubkey,
209
+ moniker: s.moniker,
210
+ access: s.access,
211
+ delivered_through: s.delivered_through,
212
+ processed_through: s.processed_through,
213
+ // What the operator actually wants to know: how much is waiting.
214
+ unread: Math.max(0, s.delivered_through - s.processed_through),
215
+ })),
216
+ });
217
+ });
218
+ handlers.set("cello_channel_set_moniker", async (params, connectionId) => {
219
+ const agent = needAgent(deps, params, connectionId);
220
+ if (!agent.ok)
221
+ return agent.answer;
222
+ const channel = needChannel(params);
223
+ if (!channel.ok)
224
+ return channel.answer;
225
+ const moniker = params?.["moniker"];
226
+ if (typeof moniker !== "string" || moniker.length === 0) {
227
+ return { ok: false, reason: "bad_moniker", guidance: "Pass a `moniker`: what you want to call this channel." };
228
+ }
229
+ subscriptions.setMoniker(deps.resolveAgentId(agent.agentName), channel.channelHex, moniker);
230
+ return Promise.resolve({ ok: true, channel: channel.channelHex, moniker });
231
+ });
232
+ handlers.set("cello_channel_leave", async (params, connectionId) => {
233
+ const agent = needAgent(deps, params, connectionId);
234
+ if (!agent.ok)
235
+ return agent.answer;
236
+ const channel = needChannel(params);
237
+ if (!channel.ok)
238
+ return channel.answer;
239
+ try {
240
+ subscriptions.markLeft(deps.resolveAgentId(agent.agentName), channel.channelHex);
241
+ }
242
+ catch (err) {
243
+ return { ok: false, reason: extractErrorMessage(err) };
244
+ }
245
+ return Promise.resolve({
246
+ ok: true,
247
+ channel: channel.channelHex,
248
+ // ⚠️ LEAVING IS LOCAL, and saying so matters: an operator who thinks the publisher was told
249
+ // may expect to be removed from a member list they are still on.
250
+ guidance: "You have stopped collecting this channel. Nothing was sent — the publisher does not know, and your keys are kept so old posts stay readable.",
251
+ });
252
+ });
253
+ /**
254
+ * Eject a member and re-key the channel.
255
+ *
256
+ * ⚠️ **THE GENERATION BUMP AND THE STATUS FLIP ARE ONE TRANSACTION** (in the store). What happens
257
+ * HERE is the delivery, and a delivery that fails does NOT undo the ejection: the member is out at
258
+ * the relay the moment the next deposit carries the new fetch key, whether or not every remaining
259
+ * member has collected their new key yet. A member left behind hits `unknown_generation` and asks.
260
+ */
261
+ handlers.set("cello_channel_eject", async (params, connectionId) => {
262
+ const agent = needAgent(deps, params, connectionId);
263
+ if (!agent.ok)
264
+ return agent.answer;
265
+ const channel = needChannel(params);
266
+ if (!channel.ok)
267
+ return channel.answer;
268
+ const subscriber = params?.["subscriber"];
269
+ if (typeof subscriber !== "string" || !/^[0-9a-fA-F]{64}$/.test(subscriber)) {
270
+ return { ok: false, reason: "bad_subscriber", guidance: "Pass the member's 64-character hex public key as `subscriber`." };
271
+ }
272
+ const admin = localChannelAdmin(channel.channelHex);
273
+ if (!admin) {
274
+ return {
275
+ ok: false, reason: "channel_not_local",
276
+ guidance: "This daemon does not hold that channel's key, and ejecting is the admin's own act. Cross-daemon admin is not in this release.",
277
+ };
278
+ }
279
+ let outcome;
280
+ try {
281
+ outcome = members.eject(channel.channelHex, subscriber.toLowerCase());
282
+ }
283
+ catch (err) {
284
+ return { ok: false, reason: extractErrorMessage(err) };
285
+ }
286
+ /**
287
+ * The new key, wrapped once per REMAINING member — the ejected one is simply not in this list.
288
+ *
289
+ * ⚠️ STORED FIRST, against the admin's own agent id. If the process died between minting and
290
+ * storing, the channel's settings would say generation N while no key for N existed anywhere:
291
+ * every subsequent publish would encrypt under a key no member was ever given, and the channel
292
+ * would go permanently silent for everyone rather than for the one person ejected.
293
+ */
294
+ const gk = generateGroupKey(outcome.generation);
295
+ subscriptions.addKey(admin.agentId, channel.channelHex, gk, Date.now());
296
+ const channelPubkey = await admin.channelKeyProvider.getPublicKey();
297
+ let delivered = 0;
298
+ const unreached = [];
299
+ for (const member of outcome.remaining) {
300
+ const sessionId = openSessionWith(agent.agentName, member);
301
+ if (sessionId === null) {
302
+ // Not a failure of the ejection. Recorded by name so an operator can see who is behind.
303
+ logger.warn("channel.rekey.member_unreached", {
304
+ channel_pubkey: channel.channelHex, member_pubkey: member, generation: outcome.generation,
305
+ });
306
+ unreached.push(member);
307
+ continue;
308
+ }
309
+ const bundle = await wrapGroupKeyFor(gk, channelPubkey, new Uint8Array(Buffer.from(member, "hex")), admin.adminKeyProvider);
310
+ await deps.sendInSession(agent.agentName, sessionId, encodeChannelRekey({
311
+ channel_pubkey: channelPubkey, key_bundle: bundle, generation: outcome.generation,
312
+ }));
313
+ delivered += 1;
314
+ }
315
+ logger.info("channel.rekey.completed", {
316
+ channel_pubkey: channel.channelHex,
317
+ generation: outcome.generation,
318
+ member_count: outcome.remaining.length,
319
+ delivered_count: delivered,
320
+ failed_count: unreached.length,
321
+ });
322
+ return {
323
+ ok: true,
324
+ channel: channel.channelHex,
325
+ generation: outcome.generation,
326
+ delivered,
327
+ unreached,
328
+ guidance: unreached.length > 0
329
+ ? `${String(unreached.length)} member(s) were not reachable and still hold the old key. They will ask for the new one when they next read; the ejection itself is done.`
330
+ : undefined,
331
+ };
332
+ });
333
+ handlers.set("cello_channel_approve", async (params, connectionId) => {
334
+ const agent = needAgent(deps, params, connectionId);
335
+ if (!agent.ok)
336
+ return agent.answer;
337
+ const channel = needChannel(params);
338
+ if (!channel.ok)
339
+ return channel.answer;
340
+ const subscriber = params?.["subscriber"];
341
+ if (typeof subscriber !== "string" || !/^[0-9a-fA-F]{64}$/.test(subscriber)) {
342
+ return { ok: false, reason: "bad_subscriber" };
343
+ }
344
+ const sessionId = openSessionWith(agent.agentName, subscriber.toLowerCase());
345
+ if (sessionId === null) {
346
+ // The approval is recorded either way: the next request from an approved member is accepted
347
+ // immediately, so an admin approving somebody who has gone offline is not wasted work.
348
+ return { ok: false, reason: "no_open_session", guidance: "They are not currently reachable. Approve again when they next ask, or the approval applies to their next request." };
349
+ }
350
+ const result = await exchangeFor(agent.agentName).approve(channel.channelHex, subscriber.toLowerCase(), sessionId);
351
+ return result.ok ? { ok: true, channel: channel.channelHex } : { ok: false, reason: result.reason };
352
+ });
353
+ handlers.set("cello_channel_refuse", async (params, connectionId) => {
354
+ const agent = needAgent(deps, params, connectionId);
355
+ if (!agent.ok)
356
+ return agent.answer;
357
+ const channel = needChannel(params);
358
+ if (!channel.ok)
359
+ return channel.answer;
360
+ const subscriber = params?.["subscriber"];
361
+ if (typeof subscriber !== "string" || !/^[0-9a-fA-F]{64}$/.test(subscriber)) {
362
+ return { ok: false, reason: "bad_subscriber" };
363
+ }
364
+ const sessionId = openSessionWith(agent.agentName, subscriber.toLowerCase());
365
+ if (sessionId === null)
366
+ return { ok: false, reason: "no_open_session" };
367
+ const result = await exchangeFor(agent.agentName).refuse(channel.channelHex, subscriber.toLowerCase(), sessionId);
368
+ return result.ok ? { ok: true, channel: channel.channelHex } : { ok: false, reason: result.reason };
369
+ });
370
+ return {
371
+ activeMembers: (channelHex) => members.activeMembers(channelHex),
372
+ currentFetchKey: async (channelHex) => {
373
+ const admin = localChannelAdmin(channelHex);
374
+ if (!admin)
375
+ return undefined;
376
+ // The NEWEST generation this daemon holds for its own channel. `keysFor` returns them newest
377
+ // first, so a re-key is picked up by the next publish without anything else being told.
378
+ const newest = subscriptions.keysFor(admin.agentId, channelHex)[0];
379
+ if (!newest)
380
+ return undefined;
381
+ const fetchKey = await deriveFetchKey(newest, new Uint8Array(Buffer.from(channelHex, "hex")));
382
+ const timeMs = Date.now();
383
+ /**
384
+ * ⚠️ SIGNED WITH THE CHANNEL KEY, and it must be: the post's signature does not cover the
385
+ * fetch key, so without one of its own anyone who could read a post could replay its bytes
386
+ * inside the clock window, attach their own key and take the channel over.
387
+ */
388
+ const signature = await admin.channelKeyProvider.sign(buildChannelFetchKeyTbs(new Uint8Array(Buffer.from(channelHex, "hex")), fetchKey.publicKey, timeMs));
389
+ return { pubkey: fetchKey.publicKey, time_ms: timeMs, signature };
390
+ },
391
+ };
392
+ }
393
+ //# sourceMappingURL=channel-membership-wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-membership-wiring.js","sourceRoot":"","sources":["../src/channel-membership-wiring.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,14 @@ export interface ChannelPublishDeps {
36
36
  };
37
37
  /** The daemon's single agent-selection rule, injected rather than re-implemented here. */
38
38
  resolveCurrentAgent: (connectionId: string, explicitAgent?: string) => string | null;
39
+ /**
40
+ * M16 021-WAKE: ring the doorbell for this channel's members after a post lands.
41
+ *
42
+ * ⚠️ **IT CANNOT FAIL A PUBLISH.** The post is deposited and durable before this is called, and
43
+ * every failure inside it is logged and dropped — an unreachable directory means subscribers
44
+ * collect on their backstop poll, which is what the poll is for.
45
+ */
46
+ wakeMembers?: (agentName: string, channelHex: string) => Promise<void>;
39
47
  }
40
48
  export declare function registerChannelPublishHandlers(deps: ChannelPublishDeps): void;
41
49
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"channel-publish-handlers.d.ts","sourceRoot":"","sources":["../src/channel-publish-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1F,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,gBAAgB,GAAG,IAAI,CAAC;IAC7D;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAC7E;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,0FAA0F;IAC1F,mBAAmB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACtF;AAkCD,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAuL7E"}
1
+ {"version":3,"file":"channel-publish-handlers.d.ts","sourceRoot":"","sources":["../src/channel-publish-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1F,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,gBAAgB,GAAG,IAAI,CAAC;IAC7D;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAC7E;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,0FAA0F;IAC1F,mBAAmB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACrF;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAkCD,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CA0L7E"}
@@ -47,6 +47,9 @@ export function registerChannelPublishHandlers(deps) {
47
47
  }
48
48
  const result = await publisher.publish(agent.agentName, channel.channelHex, title, body);
49
49
  if (result.ok) {
50
+ // The doorbell, after the post is durable and never before: a wake for a post that failed to
51
+ // deposit would send every member to fetch something that is not there.
52
+ await deps.wakeMembers?.(agent.agentName, channel.channelHex);
50
53
  return {
51
54
  ok: true, seq: result.seq,
52
55
  relays_ok: result.deposited.filter((d) => d.ok).map((d) => d.relay),
@@ -1 +1 @@
1
- {"version":3,"file":"channel-publish-handlers.js","sourceRoot":"","sources":["../src/channel-publish-handlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-publish-handlers.js","sourceRoot":"","sources":["../src/channel-publish-handlers.ts"],"names":[],"mappings":"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"}
@@ -19,15 +19,35 @@ export interface ChannelPublishWiringDeps {
19
19
  handlers: Map<string, Handler>;
20
20
  logger: Logger;
21
21
  getDb: () => DaemonDatabase;
22
+ /** M16 021-WAKE: who a post's doorbell is rung for. From the membership half, which owns the list. */
23
+ activeMembers: (channelHex: string) => string[];
24
+ /** M16 021-WAKE: the publishing agent's own directory connection, by agent NAME. */
25
+ signalingFor: (agentName: string) => {
26
+ sendRaw(frame: unknown): Promise<{
27
+ ok: boolean;
28
+ reason?: string;
29
+ }>;
30
+ } | null;
22
31
  getNode: () => CelloNode | null;
23
32
  screenOutbound: (content: Uint8Array, ctx: ScreenContext) => Promise<ScreenVerdict>;
24
33
  /** Every agent this daemon loaded, read per lookup so one added after boot is publishable. */
25
34
  loadedAgents: ReadonlyArray<{
35
+ name: string;
26
36
  pubkey: string;
27
37
  keyProvider: KeyProvider;
28
38
  }>;
29
39
  keyProviders: Map<string, KeyProvider>;
30
40
  resolveCurrentAgent: (connectionId: string, explicitAgent?: string) => string | null;
41
+ /**
42
+ * M16 019: the channel's current fetch key, signed, or undefined when this daemon holds no group
43
+ * key for it. Injected rather than derived here so the membership half owns the group key and
44
+ * this half never has to hold one.
45
+ */
46
+ currentFetchKey?: (channelHex: string) => Promise<{
47
+ pubkey: Uint8Array;
48
+ time_ms: number;
49
+ signature: Uint8Array;
50
+ } | undefined>;
31
51
  /**
32
52
  * Online AND not explicitly switched off — the same pair every other background loop here reads.
33
53
  * Collecting for an agent the operator switched off is the kill switch failing to switch off.
@@ -36,6 +56,7 @@ export interface ChannelPublishWiringDeps {
36
56
  }
37
57
  export declare function wireChannelPublishing(deps: ChannelPublishWiringDeps): {
38
58
  stop: () => void;
59
+ collectNow: (agentId: string) => Promise<void>;
39
60
  };
40
61
  export {};
41
62
  //# sourceMappingURL=channel-publish-wiring.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel-publish-wiring.d.ts","sourceRoot":"","sources":["../src/channel-publish-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAW5E,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvG,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACpF,8FAA8F;IAC9F,YAAY,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IAC1E,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACrF;;;OAGG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CAwH1F"}
1
+ {"version":3,"file":"channel-publish-wiring.d.ts","sourceRoot":"","sources":["../src/channel-publish-wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAY5E,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvG,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,sGAAsG;IACtG,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IAChD,oFAAoF;IACpF,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK;QAAE,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACnH,OAAO,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACpF,8FAA8F;IAC9F,YAAY,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC,CAAC;IACxF,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACrF;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IAC9H;;;OAGG;IACH,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,wBAAwB,GAC7B;IAAE,IAAI,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA4JtE"}
@@ -7,6 +7,7 @@ import { ChannelCollector } from "./channel-collector.js";
7
7
  import { ChannelSubscriptionStore } from "./channel-subscription-store.js";
8
8
  import { ChannelInboxStore } from "./channel-inbox-store.js";
9
9
  import { createChannelCollectTicker } from "./channel-collect-tick.js";
10
+ import { createChannelWakeSender } from "./channel-wake-sender.js";
10
11
  export function wireChannelPublishing(deps) {
11
12
  const { logger, keyProviders } = deps;
12
13
  const log = new ChannelLogStore(deps.getDb(), logger);
@@ -27,7 +28,18 @@ export function wireChannelPublishing(deps) {
27
28
  return new ChannelPublisher({
28
29
  logger,
29
30
  log,
30
- deposit: (addr, req) => relay.deposit(addr, { post_cbor: req.post_cbor }),
31
+ deposit: (addr, req) => relay.deposit(addr, {
32
+ post_cbor: req.post_cbor,
33
+ ...(req.fetch_key ? { fetch_key: req.fetch_key } : {}),
34
+ }),
35
+ /**
36
+ * ⚠️ **THE KEY THAT MAKES AN EJECTION BITE AT THE RELAY.** Derived from the channel's current
37
+ * group key, signed with the CHANNEL key because the post's signature does not cover it, and
38
+ * sent with each deposit so a re-key reaches the relays on the very next post. `undefined`
39
+ * means this daemon holds no group key for that channel — a public one, or one it does not
40
+ * administer — and the relay then serves it to anyone, which for a public channel is correct.
41
+ */
42
+ currentFetchKey: deps.currentFetchKey,
31
43
  depositInfo: (addr, req) => relay.depositInfo(addr, { info_cbor: req.info_cbor }),
32
44
  prune: (addr, req) => relay.prune(addr, {
33
45
  channel_pubkey: Buffer.from(req.channelHex, "hex"),
@@ -56,11 +68,22 @@ export function wireChannelPublishing(deps) {
56
68
  channelInfo: (channelHex) => config.get(channelHex),
57
69
  });
58
70
  };
71
+ /**
72
+ * M16 021-WAKE. The publishing agent asks on ITS OWN directory stream — the directory checks the
73
+ * caller is the channel's admin, so it has to be that agent's connection and not any that happens
74
+ * to be open.
75
+ */
76
+ const sendWake = createChannelWakeSender({
77
+ logger,
78
+ activeMembers: (channelHex) => deps.activeMembers(channelHex),
79
+ signalingFor: (agentId) => deps.signalingFor(agentId),
80
+ });
59
81
  registerChannelPublishHandlers({
60
82
  handlers: deps.handlers,
61
83
  logger,
62
84
  resolveCurrentAgent: deps.resolveCurrentAgent,
63
85
  getPublisher: buildPublisher,
86
+ wakeMembers: (agentName, channelHex) => sendWake(agentName, channelHex),
64
87
  setChannelConfig: (agentName, channelHex, cfg) => {
65
88
  // The channel key must be one this daemon HOLDS. Recording relays for a channel we cannot
66
89
  // sign for would leave every later verb failing on a key lookup, which describes neither the
@@ -74,7 +97,15 @@ export function wireChannelPublishing(deps) {
74
97
  if (!keyProviders.has(agentName)) {
75
98
  return { ok: false, reason: "no_such_agent", guidance: `${agentName} is not an agent this daemon holds.` };
76
99
  }
77
- config.set(channelHex, cfg, Date.now());
100
+ /**
101
+ * ⚠️ **THE ADMIN AGENT IS RECORDED HERE, and it is what makes the channel joinable at all.**
102
+ * `agentName` is the agent running the setup, and in this release the publisher and the admin
103
+ * are the same operator — so that agent's key is the one a subscriber will check the answering
104
+ * party against. Leaving it empty was how 019's first cut produced a channel that refused
105
+ * every join with `not_admin_of_channel` on a channel it demonstrably administered.
106
+ */
107
+ const adminAgent = deps.loadedAgents.find((a) => a.name === agentName);
108
+ config.set(channelHex, { ...cfg, admin_pubkey: adminAgent?.pubkey ?? "" }, Date.now());
78
109
  return { ok: true };
79
110
  },
80
111
  });
@@ -119,6 +150,11 @@ export function wireChannelPublishing(deps) {
119
150
  isAgentOnline: deps.isAgentOnline,
120
151
  });
121
152
  ticker.start();
122
- return { stop: () => { ticker.stop(); } };
153
+ return {
154
+ stop: () => { ticker.stop(); },
155
+ // M16 021-WAKE: what the doorbell calls. Exposed rather than wired here because the frame
156
+ // arrives on the agent's signaling stream, which this module does not own.
157
+ collectNow: (agentId) => ticker.collectNow(agentId),
158
+ };
123
159
  }
124
160
  //# sourceMappingURL=channel-publish-wiring.js.map