@volter/teams 0.1.87 → 0.1.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/teams",
3
- "version": "0.1.87",
3
+ "version": "0.1.88",
4
4
  "type": "module",
5
5
  "description": "Volter Teams, the neutral team plane: machine identity and daemon core, the local door and server link, admission from machine grants, product doors, and the Teams server's neutral routes (company RFC 0008).",
6
6
  "license": "MIT",
@@ -264,21 +264,49 @@ async function delegatedSessionChannel(api, teamId, sessionRef, token) {
264
264
  * the harness session the token names. Null unless the session's owner bound it to the token's Room and Conversation.
265
265
  */
266
266
  async function boundSessionTarget(api, teamId, access) {
267
+ return (await sessionDeliveryResolution(api, teamId, access)).target;
268
+ }
269
+
270
+ /** The same delivery checks, explainable only through a session custodian's authenticated door.
271
+ * No token is accepted and no grant, binding or native message is created by this read.
272
+ */
273
+ export async function sessionDeliveryResolution(api, teamId, access, diagnostics = false) {
267
274
  const named = await api.store.query('SELECT id, canonical_id FROM sessions WHERE team_id=? AND deleted_at IS NULL AND (id=? OR id IN (SELECT session_id FROM origins WHERE team_id=? AND native_id=? AND deleted_at IS NULL))', [teamId, access.sessionRef, teamId, access.sessionRef]);
275
+ let reason = 'session_not_found', origins = null;
268
276
  for (const found of named) {
269
277
  let root = found;
270
278
  for (let hops = 0; root?.canonical_id && hops < 16; hops += 1) root = await api.store.one('SELECT id, canonical_id FROM sessions WHERE team_id=? AND id=? AND deleted_at IS NULL', [teamId, root.canonical_id]);
271
- if (!root || root.canonical_id) continue;
279
+ if (!root || root.canonical_id) { reason = 'session_family_unresolved'; continue; }
272
280
  const bound = await api.store.one('SELECT 1 ok FROM session_view_bindings WHERE team_id=? AND session_id=? AND issuer=? AND room=? AND conversation=?', [teamId, root.id, access.issuer, access.room, access.conversation]);
273
- if (!bound) continue;
281
+ if (!bound) { reason = 'binding_not_found'; continue; }
274
282
  const origin = await api.store.one(`SELECT o.harness, o.native_id, o.session_id, src.machine_id FROM origins o
275
283
  JOIN sources src ON src.team_id=o.team_id AND src.id=o.source_id AND src.state='active' AND src.machine_id IS NOT NULL
276
284
  JOIN machines m ON m.team_id=src.team_id AND m.id=src.machine_id AND m.revoked_at IS NULL
277
285
  WHERE o.team_id=? AND o.deleted_at IS NULL AND o.session_id IN (SELECT id FROM sessions WHERE team_id=? AND deleted_at IS NULL AND (id=? OR canonical_id=?))
278
286
  ORDER BY (o.native_id=?) DESC, o.sequence DESC LIMIT 1`, [teamId, teamId, root.id, root.id, access.sessionRef]);
279
- if (origin) return { sessionId: root.id, harness: origin.harness, nativeId: origin.native_id, machineId: origin.machine_id };
287
+ if (origin) {
288
+ const target = { sessionId: root.id, harness: origin.harness, nativeId: origin.native_id, machineId: origin.machine_id };
289
+ return { state: 'ready', reason: null, target };
290
+ }
291
+ reason = 'no_live_origin';
292
+ if (diagnostics) {
293
+ // LEFT joins retain the row that the delivery's inner joins discarded.
294
+ const rows = await api.store.query(`SELECT o.harness, o.source_id, o.deleted_at, src.state source_state, src.machine_id,
295
+ m.id enrolled_machine, m.revoked_at machine_revoked_at FROM origins o
296
+ LEFT JOIN sources src ON src.team_id=o.team_id AND src.id=o.source_id
297
+ LEFT JOIN machines m ON m.team_id=src.team_id AND m.id=src.machine_id
298
+ WHERE o.team_id=? AND o.session_id IN (SELECT id FROM sessions WHERE team_id=? AND deleted_at IS NULL AND (id=? OR canonical_id=?))
299
+ ORDER BY o.sequence DESC LIMIT 51`, [teamId, teamId, root.id, root.id]);
300
+ const live = rows.filter(row => row.deleted_at == null), active = live.filter(row => row.source_state === 'active');
301
+ const attached = active.filter(row => row.machine_id != null), enrolled = attached.filter(row => row.enrolled_machine != null);
302
+ reason = !rows.length ? 'origin_not_found' : !live.length ? 'origin_deleted' : !active.length ? 'source_not_active'
303
+ : !attached.length ? 'source_without_machine' : !enrolled.length ? 'machine_not_found' : 'machine_revoked';
304
+ origins = { truncated: rows.length > 50, items: rows.slice(0,50).map(row => ({ harness: row.harness,
305
+ source_id: row.source_id, source_state: row.source_state, origin_deleted: row.deleted_at != null,
306
+ machine_id: row.machine_id, machine_present: row.enrolled_machine != null, machine_revoked: row.machine_revoked_at != null })) };
307
+ }
280
308
  }
281
- return null;
309
+ return { state: 'unavailable', reason, target: null, ...(origins ? { origins } : {}) };
282
310
  }
283
311
 
284
312
  /** Close every delegated channel whose grant came from one publication (issuer from delegatedGrantIssuer): it was unpublished. */