@cello-protocol/daemon 0.0.230 → 0.0.231

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 (53) 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-config-store.d.ts +3 -0
  6. package/dist/channel-config-store.d.ts.map +1 -1
  7. package/dist/channel-config-store.js +28 -5
  8. package/dist/channel-config-store.js.map +1 -1
  9. package/dist/channel-join-exchange.d.ts +87 -0
  10. package/dist/channel-join-exchange.d.ts.map +1 -0
  11. package/dist/channel-join-exchange.js +289 -0
  12. package/dist/channel-join-exchange.js.map +1 -0
  13. package/dist/channel-membership-store.d.ts +118 -0
  14. package/dist/channel-membership-store.d.ts.map +1 -0
  15. package/dist/channel-membership-store.js +226 -0
  16. package/dist/channel-membership-store.js.map +1 -0
  17. package/dist/channel-membership-wiring.d.ts +90 -0
  18. package/dist/channel-membership-wiring.d.ts.map +1 -0
  19. package/dist/channel-membership-wiring.js +387 -0
  20. package/dist/channel-membership-wiring.js.map +1 -0
  21. package/dist/channel-publish-wiring.d.ts +11 -0
  22. package/dist/channel-publish-wiring.d.ts.map +1 -1
  23. package/dist/channel-publish-wiring.js +21 -2
  24. package/dist/channel-publish-wiring.js.map +1 -1
  25. package/dist/channel-publisher.d.ts +34 -2
  26. package/dist/channel-publisher.d.ts.map +1 -1
  27. package/dist/channel-publisher.js +46 -10
  28. package/dist/channel-publisher.js.map +1 -1
  29. package/dist/channel-subscription-store.d.ts +71 -0
  30. package/dist/channel-subscription-store.d.ts.map +1 -1
  31. package/dist/channel-subscription-store.js +150 -9
  32. package/dist/channel-subscription-store.js.map +1 -1
  33. package/dist/daemon.d.ts.map +1 -1
  34. package/dist/daemon.js +40 -0
  35. package/dist/daemon.js.map +1 -1
  36. package/dist/inbound-sessions.d.ts +6 -0
  37. package/dist/inbound-sessions.d.ts.map +1 -1
  38. package/dist/inbound-sessions.js +27 -1
  39. package/dist/inbound-sessions.js.map +1 -1
  40. package/dist/refusal-reasons.d.ts +7 -0
  41. package/dist/refusal-reasons.d.ts.map +1 -1
  42. package/dist/refusal-reasons.js +15 -0
  43. package/dist/refusal-reasons.js.map +1 -1
  44. package/dist/session-content-context.d.ts +8 -0
  45. package/dist/session-content-context.d.ts.map +1 -1
  46. package/dist/session-content-ingest.d.ts.map +1 -1
  47. package/dist/session-content-ingest.js +28 -0
  48. package/dist/session-content-ingest.js.map +1 -1
  49. package/dist/session-node-manager.d.ts +4 -0
  50. package/dist/session-node-manager.d.ts.map +1 -1
  51. package/dist/session-node-manager.js +11 -0
  52. package/dist/session-node-manager.js.map +1 -1
  53. package/package.json +5 -5
@@ -0,0 +1,387 @@
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 settings.admin_pubkey;
34
+ try {
35
+ const outcome = await deps.lookup(agentId, channelHex);
36
+ if (outcome.kind === "admin")
37
+ return outcome.adminPubkeyHex;
38
+ deps.logger.info("channel.join.admin_unresolved", {
39
+ channel_pubkey: channelHex,
40
+ reason: outcome.kind === "not_a_channel" ? "not_a_channel" : outcome.reason,
41
+ });
42
+ return null;
43
+ }
44
+ catch (err) {
45
+ // This runs inside the inbound content path. An exception escaping would surface as a broken
46
+ // session rather than a refused join, which is a worse answer to the same question.
47
+ deps.logger.warn("channel.join.admin_unresolved", {
48
+ channel_pubkey: channelHex, reason: extractErrorMessage(err),
49
+ });
50
+ return null;
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
+ });
183
+ }
184
+ })().catch((err) => {
185
+ // A rejected promise here must not take down the content path for every other session.
186
+ logger.error("channel.join.handling_failed", {
187
+ ...(correlationId !== undefined ? { correlationId } : {}),
188
+ reason: extractErrorMessage(err),
189
+ });
190
+ });
191
+ return { consumed: true };
192
+ });
193
+ // ─── Operator verbs ───────────────────────────────────────────────────────────────────────────
194
+ handlers.set("cello_channels", async (params, connectionId) => {
195
+ const agent = needAgent(deps, params, connectionId);
196
+ if (!agent.ok)
197
+ return agent.answer;
198
+ const agentId = deps.resolveAgentId(agent.agentName);
199
+ const rows = subscriptions.active().filter((s) => s.agent_id === agentId);
200
+ return Promise.resolve({
201
+ ok: true,
202
+ channels: rows.map((s) => ({
203
+ channel: s.channel_pubkey,
204
+ moniker: s.moniker,
205
+ access: s.access,
206
+ delivered_through: s.delivered_through,
207
+ processed_through: s.processed_through,
208
+ // What the operator actually wants to know: how much is waiting.
209
+ unread: Math.max(0, s.delivered_through - s.processed_through),
210
+ })),
211
+ });
212
+ });
213
+ handlers.set("cello_channel_set_moniker", async (params, connectionId) => {
214
+ const agent = needAgent(deps, params, connectionId);
215
+ if (!agent.ok)
216
+ return agent.answer;
217
+ const channel = needChannel(params);
218
+ if (!channel.ok)
219
+ return channel.answer;
220
+ const moniker = params?.["moniker"];
221
+ if (typeof moniker !== "string" || moniker.length === 0) {
222
+ return { ok: false, reason: "bad_moniker", guidance: "Pass a `moniker`: what you want to call this channel." };
223
+ }
224
+ subscriptions.setMoniker(deps.resolveAgentId(agent.agentName), channel.channelHex, moniker);
225
+ return Promise.resolve({ ok: true, channel: channel.channelHex, moniker });
226
+ });
227
+ handlers.set("cello_channel_leave", async (params, connectionId) => {
228
+ const agent = needAgent(deps, params, connectionId);
229
+ if (!agent.ok)
230
+ return agent.answer;
231
+ const channel = needChannel(params);
232
+ if (!channel.ok)
233
+ return channel.answer;
234
+ try {
235
+ subscriptions.markLeft(deps.resolveAgentId(agent.agentName), channel.channelHex);
236
+ }
237
+ catch (err) {
238
+ return { ok: false, reason: extractErrorMessage(err) };
239
+ }
240
+ return Promise.resolve({
241
+ ok: true,
242
+ channel: channel.channelHex,
243
+ // ⚠️ LEAVING IS LOCAL, and saying so matters: an operator who thinks the publisher was told
244
+ // may expect to be removed from a member list they are still on.
245
+ 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.",
246
+ });
247
+ });
248
+ /**
249
+ * Eject a member and re-key the channel.
250
+ *
251
+ * ⚠️ **THE GENERATION BUMP AND THE STATUS FLIP ARE ONE TRANSACTION** (in the store). What happens
252
+ * HERE is the delivery, and a delivery that fails does NOT undo the ejection: the member is out at
253
+ * the relay the moment the next deposit carries the new fetch key, whether or not every remaining
254
+ * member has collected their new key yet. A member left behind hits `unknown_generation` and asks.
255
+ */
256
+ handlers.set("cello_channel_eject", async (params, connectionId) => {
257
+ const agent = needAgent(deps, params, connectionId);
258
+ if (!agent.ok)
259
+ return agent.answer;
260
+ const channel = needChannel(params);
261
+ if (!channel.ok)
262
+ return channel.answer;
263
+ const subscriber = params?.["subscriber"];
264
+ if (typeof subscriber !== "string" || !/^[0-9a-fA-F]{64}$/.test(subscriber)) {
265
+ return { ok: false, reason: "bad_subscriber", guidance: "Pass the member's 64-character hex public key as `subscriber`." };
266
+ }
267
+ const admin = localChannelAdmin(channel.channelHex);
268
+ if (!admin) {
269
+ return {
270
+ ok: false, reason: "channel_not_local",
271
+ 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.",
272
+ };
273
+ }
274
+ let outcome;
275
+ try {
276
+ outcome = members.eject(channel.channelHex, subscriber.toLowerCase());
277
+ }
278
+ catch (err) {
279
+ return { ok: false, reason: extractErrorMessage(err) };
280
+ }
281
+ /**
282
+ * The new key, wrapped once per REMAINING member — the ejected one is simply not in this list.
283
+ *
284
+ * ⚠️ STORED FIRST, against the admin's own agent id. If the process died between minting and
285
+ * storing, the channel's settings would say generation N while no key for N existed anywhere:
286
+ * every subsequent publish would encrypt under a key no member was ever given, and the channel
287
+ * would go permanently silent for everyone rather than for the one person ejected.
288
+ */
289
+ const gk = generateGroupKey(outcome.generation);
290
+ subscriptions.addKey(admin.agentId, channel.channelHex, gk, Date.now());
291
+ const channelPubkey = await admin.channelKeyProvider.getPublicKey();
292
+ let delivered = 0;
293
+ const unreached = [];
294
+ for (const member of outcome.remaining) {
295
+ const sessionId = openSessionWith(agent.agentName, member);
296
+ if (sessionId === null) {
297
+ // Not a failure of the ejection. Recorded by name so an operator can see who is behind.
298
+ logger.warn("channel.rekey.member_unreached", {
299
+ channel_pubkey: channel.channelHex, member_pubkey: member, generation: outcome.generation,
300
+ });
301
+ unreached.push(member);
302
+ continue;
303
+ }
304
+ const bundle = await wrapGroupKeyFor(gk, channelPubkey, new Uint8Array(Buffer.from(member, "hex")), admin.adminKeyProvider);
305
+ await deps.sendInSession(agent.agentName, sessionId, encodeChannelRekey({
306
+ channel_pubkey: channelPubkey, key_bundle: bundle, generation: outcome.generation,
307
+ }));
308
+ delivered += 1;
309
+ }
310
+ logger.info("channel.rekey.completed", {
311
+ channel_pubkey: channel.channelHex,
312
+ generation: outcome.generation,
313
+ member_count: outcome.remaining.length,
314
+ delivered_count: delivered,
315
+ failed_count: unreached.length,
316
+ });
317
+ return {
318
+ ok: true,
319
+ channel: channel.channelHex,
320
+ generation: outcome.generation,
321
+ delivered,
322
+ unreached,
323
+ guidance: unreached.length > 0
324
+ ? `${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.`
325
+ : undefined,
326
+ };
327
+ });
328
+ handlers.set("cello_channel_approve", async (params, connectionId) => {
329
+ const agent = needAgent(deps, params, connectionId);
330
+ if (!agent.ok)
331
+ return agent.answer;
332
+ const channel = needChannel(params);
333
+ if (!channel.ok)
334
+ return channel.answer;
335
+ const subscriber = params?.["subscriber"];
336
+ if (typeof subscriber !== "string" || !/^[0-9a-fA-F]{64}$/.test(subscriber)) {
337
+ return { ok: false, reason: "bad_subscriber" };
338
+ }
339
+ const sessionId = openSessionWith(agent.agentName, subscriber.toLowerCase());
340
+ if (sessionId === null) {
341
+ // The approval is recorded either way: the next request from an approved member is accepted
342
+ // immediately, so an admin approving somebody who has gone offline is not wasted work.
343
+ 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." };
344
+ }
345
+ const result = await exchangeFor(agent.agentName).approve(channel.channelHex, subscriber.toLowerCase(), sessionId);
346
+ return result.ok ? { ok: true, channel: channel.channelHex } : { ok: false, reason: result.reason };
347
+ });
348
+ handlers.set("cello_channel_refuse", async (params, connectionId) => {
349
+ const agent = needAgent(deps, params, connectionId);
350
+ if (!agent.ok)
351
+ return agent.answer;
352
+ const channel = needChannel(params);
353
+ if (!channel.ok)
354
+ return channel.answer;
355
+ const subscriber = params?.["subscriber"];
356
+ if (typeof subscriber !== "string" || !/^[0-9a-fA-F]{64}$/.test(subscriber)) {
357
+ return { ok: false, reason: "bad_subscriber" };
358
+ }
359
+ const sessionId = openSessionWith(agent.agentName, subscriber.toLowerCase());
360
+ if (sessionId === null)
361
+ return { ok: false, reason: "no_open_session" };
362
+ const result = await exchangeFor(agent.agentName).refuse(channel.channelHex, subscriber.toLowerCase(), sessionId);
363
+ return result.ok ? { ok: true, channel: channel.channelHex } : { ok: false, reason: result.reason };
364
+ });
365
+ return {
366
+ currentFetchKey: async (channelHex) => {
367
+ const admin = localChannelAdmin(channelHex);
368
+ if (!admin)
369
+ return undefined;
370
+ // The NEWEST generation this daemon holds for its own channel. `keysFor` returns them newest
371
+ // first, so a re-key is picked up by the next publish without anything else being told.
372
+ const newest = subscriptions.keysFor(admin.agentId, channelHex)[0];
373
+ if (!newest)
374
+ return undefined;
375
+ const fetchKey = await deriveFetchKey(newest, new Uint8Array(Buffer.from(channelHex, "hex")));
376
+ const timeMs = Date.now();
377
+ /**
378
+ * ⚠️ SIGNED WITH THE CHANNEL KEY, and it must be: the post's signature does not cover the
379
+ * fetch key, so without one of its own anyone who could read a post could replay its bytes
380
+ * inside the clock window, attach their own key and take the channel over.
381
+ */
382
+ const signature = await admin.channelKeyProvider.sign(buildChannelFetchKeyTbs(new Uint8Array(Buffer.from(channelHex, "hex")), fetchKey.publicKey, timeMs));
383
+ return { pubkey: fetchKey.publicKey, time_ms: timeMs, signature };
384
+ },
385
+ };
386
+ }
387
+ //# 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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"}
@@ -23,11 +23,22 @@ export interface ChannelPublishWiringDeps {
23
23
  screenOutbound: (content: Uint8Array, ctx: ScreenContext) => Promise<ScreenVerdict>;
24
24
  /** Every agent this daemon loaded, read per lookup so one added after boot is publishable. */
25
25
  loadedAgents: ReadonlyArray<{
26
+ name: string;
26
27
  pubkey: string;
27
28
  keyProvider: KeyProvider;
28
29
  }>;
29
30
  keyProviders: Map<string, KeyProvider>;
30
31
  resolveCurrentAgent: (connectionId: string, explicitAgent?: string) => string | null;
32
+ /**
33
+ * M16 019: the channel's current fetch key, signed, or undefined when this daemon holds no group
34
+ * key for it. Injected rather than derived here so the membership half owns the group key and
35
+ * this half never has to hold one.
36
+ */
37
+ currentFetchKey?: (channelHex: string) => Promise<{
38
+ pubkey: Uint8Array;
39
+ time_ms: number;
40
+ signature: Uint8Array;
41
+ } | undefined>;
31
42
  /**
32
43
  * Online AND not explicitly switched off — the same pair every other background loop here reads.
33
44
  * Collecting for an agent the operator switched off is the kill switch failing to switch off.
@@ -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;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,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,CAAC,IAAI,EAAE,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CA2I1F"}
@@ -27,7 +27,18 @@ export function wireChannelPublishing(deps) {
27
27
  return new ChannelPublisher({
28
28
  logger,
29
29
  log,
30
- deposit: (addr, req) => relay.deposit(addr, { post_cbor: req.post_cbor }),
30
+ deposit: (addr, req) => relay.deposit(addr, {
31
+ post_cbor: req.post_cbor,
32
+ ...(req.fetch_key ? { fetch_key: req.fetch_key } : {}),
33
+ }),
34
+ /**
35
+ * ⚠️ **THE KEY THAT MAKES AN EJECTION BITE AT THE RELAY.** Derived from the channel's current
36
+ * group key, signed with the CHANNEL key because the post's signature does not cover it, and
37
+ * sent with each deposit so a re-key reaches the relays on the very next post. `undefined`
38
+ * means this daemon holds no group key for that channel — a public one, or one it does not
39
+ * administer — and the relay then serves it to anyone, which for a public channel is correct.
40
+ */
41
+ currentFetchKey: deps.currentFetchKey,
31
42
  depositInfo: (addr, req) => relay.depositInfo(addr, { info_cbor: req.info_cbor }),
32
43
  prune: (addr, req) => relay.prune(addr, {
33
44
  channel_pubkey: Buffer.from(req.channelHex, "hex"),
@@ -74,7 +85,15 @@ export function wireChannelPublishing(deps) {
74
85
  if (!keyProviders.has(agentName)) {
75
86
  return { ok: false, reason: "no_such_agent", guidance: `${agentName} is not an agent this daemon holds.` };
76
87
  }
77
- config.set(channelHex, cfg, Date.now());
88
+ /**
89
+ * ⚠️ **THE ADMIN AGENT IS RECORDED HERE, and it is what makes the channel joinable at all.**
90
+ * `agentName` is the agent running the setup, and in this release the publisher and the admin
91
+ * are the same operator — so that agent's key is the one a subscriber will check the answering
92
+ * party against. Leaving it empty was how 019's first cut produced a channel that refused
93
+ * every join with `not_admin_of_channel` on a channel it demonstrably administered.
94
+ */
95
+ const adminAgent = deps.loadedAgents.find((a) => a.name === agentName);
96
+ config.set(channelHex, { ...cfg, admin_pubkey: adminAgent?.pubkey ?? "" }, Date.now());
78
97
  return { ok: true };
79
98
  },
80
99
  });
@@ -1 +1 @@
1
- {"version":3,"file":"channel-publish-wiring.js","sourceRoot":"","sources":["../src/channel-publish-wiring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-publish-wiring.js","sourceRoot":"","sources":["../src/channel-publish-wiring.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,22 @@ import { ChannelLogStore } from "./channel-log-store.js";
29
29
  /** How the publisher reaches a relay. The transport is the caller's; this owns the decisions. */
30
30
  export type RelayDepositSeam = (relay: string, req: {
31
31
  post_cbor: Uint8Array;
32
+ /**
33
+ * ⚠️ **THIS IS WHAT MAKES AN EJECTION BITE AT THE RELAY.** The relay serves a non-public
34
+ * channel's queue only to a caller who can sign with the channel's current fetch key, and that
35
+ * key is DERIVED from the group key — so rotating the group key on an ejection rotates this
36
+ * too. Sent with the first deposit of each generation: until the relay has it, the ejected
37
+ * member can still FETCH (they just cannot decrypt), and "cannot read" is a weaker property
38
+ * than the one the order asks for.
39
+ *
40
+ * It carries its own channel signature because the post's does not cover it — see 017's note
41
+ * on the takeover this closes.
42
+ */
43
+ fetch_key?: {
44
+ pubkey: Uint8Array;
45
+ time_ms: number;
46
+ signature: Uint8Array;
47
+ };
32
48
  }) => Promise<{
33
49
  ok: true;
34
50
  receipt_cbor: Uint8Array;
@@ -94,10 +110,26 @@ export interface ChannelPublisherOptions {
94
110
  }) => Promise<ScreenVerdict>;
95
111
  getChannelKey: (channelHex: string) => KeyProvider | null;
96
112
  getAgentKey: (agentName: string) => KeyProvider | null;
97
- /** 019 owns the group key; the publisher must not be able to tell what this does. */
98
- encryptBody: (plaintext: Uint8Array, channelHex: string) => Promise<Uint8Array>;
113
+ /**
114
+ * 019 owns the group key; the publisher must not be able to tell what this does.
115
+ *
116
+ * ⚠️ TAKES THE POST NUMBER, because the body's associated data binds it. Without seq here the
117
+ * encryption cannot bind the position, and a hostile relay can serve one post's body at another's
118
+ * number with every signature still verifying.
119
+ */
120
+ encryptBody: (plaintext: Uint8Array, channelHex: string, seq: number) => Promise<Uint8Array>;
99
121
  /** Overridable so a test can refill without waiting; production takes the default. */
100
122
  resendPaceMs?: number;
123
+ /**
124
+ * The channel's CURRENT fetch key, or undefined for a public channel (which has none — anyone may
125
+ * read it). Asked per publish so a re-key reaches the relays on the very next post rather than
126
+ * waiting for a restart.
127
+ */
128
+ currentFetchKey?: (channelHex: string) => Promise<{
129
+ pubkey: Uint8Array;
130
+ time_ms: number;
131
+ signature: Uint8Array;
132
+ } | undefined>;
101
133
  channelInfo: (channelHex: string) => {
102
134
  access: ChannelAccess;
103
135
  relays: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"channel-publisher.d.ts","sourceRoot":"","sources":["../src/channel-publisher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-publisher.d.ts","sourceRoot":"","sources":["../src/channel-publisher.ts"],"names":[],"mappings":"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"}