instar 1.3.732 → 1.3.734
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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +127 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/core/ConversationRegistry.d.ts +95 -0
- package/dist/core/ConversationRegistry.d.ts.map +1 -1
- package/dist/core/ConversationRegistry.js +292 -5
- package/dist/core/ConversationRegistry.js.map +1 -1
- package/dist/core/SessionManager.d.ts +15 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +28 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/conversationBindToken.d.ts +36 -0
- package/dist/core/conversationBindToken.d.ts.map +1 -0
- package/dist/core/conversationBindToken.js +144 -0
- package/dist/core/conversationBindToken.js.map +1 -0
- package/dist/core/conversationIdentity.d.ts +14 -0
- package/dist/core/conversationIdentity.d.ts.map +1 -1
- package/dist/core/conversationIdentity.js +19 -0
- package/dist/core/conversationIdentity.js.map +1 -1
- package/dist/core/deliverToConversation.d.ts +68 -25
- package/dist/core/deliverToConversation.d.ts.map +1 -1
- package/dist/core/deliverToConversation.js +300 -11
- package/dist/core/deliverToConversation.js.map +1 -1
- package/dist/core/slackRefreshBinding.d.ts +8 -10
- package/dist/core/slackRefreshBinding.d.ts.map +1 -1
- package/dist/core/slackRefreshBinding.js +8 -16
- package/dist/core/slackRefreshBinding.js.map +1 -1
- package/dist/core/types.d.ts +9 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/CommitmentTracker.d.ts +64 -0
- package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
- package/dist/monitoring/CommitmentTracker.js +58 -0
- package/dist/monitoring/CommitmentTracker.js.map +1 -1
- package/dist/monitoring/PromiseBeacon.d.ts +70 -0
- package/dist/monitoring/PromiseBeacon.d.ts.map +1 -1
- package/dist/monitoring/PromiseBeacon.js +221 -24
- package/dist/monitoring/PromiseBeacon.js.map +1 -1
- package/dist/server/AgentServer.d.ts +9 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +8 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +12 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +128 -10
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +48 -48
- package/upgrades/1.3.733.md +108 -0
- package/upgrades/1.3.734.md +30 -0
- package/upgrades/side-effects/durable-conversation-identity-increment2.md +88 -0
- package/upgrades/side-effects/three-constitutional-standards.md +129 -0
|
@@ -1,4 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deliverToConversation — the outbound funnel
|
|
3
|
+
* (docs/specs/durable-conversation-identity.md §5; §6.1 increments 1–2).
|
|
4
|
+
*
|
|
5
|
+
* A single delivery helper every follow-through consumer migrates onto. The
|
|
6
|
+
* `id<0` arm is dark-gated behind `conversationIdentity.followThrough` (§9:
|
|
7
|
+
* `enabled` OMITTED → the developmentAgent gate resolves it — live-on-dev,
|
|
8
|
+
* dark-fleet; `dryRun: true` FIRST because delivery is externally visible).
|
|
9
|
+
*
|
|
10
|
+
* §5.1 failure/dryRun contract: a funnel non-delivery is a TYPED,
|
|
11
|
+
* NON-EXCEPTIONAL return the caller inspects — never a thrown exception, and
|
|
12
|
+
* NEVER success-shaped. dryRun (and fleet-dark) return the SAME
|
|
13
|
+
* `not-delivered` typed result the unresolvable path uses, plus a
|
|
14
|
+
* `would-deliver` audit line — caller-visible as a non-delivery so beacon
|
|
15
|
+
* retry / attention escalation keep engaging (A Refusal Stays a Refusal / P18).
|
|
16
|
+
*
|
|
17
|
+
* Increment 2 (the proof consumer) adds:
|
|
18
|
+
* - the §5.0(a) E1 ambiguous-outcome idempotency guard (durable send-intent /
|
|
19
|
+
* ambiguous-send / send-retire journal ops; retirement-based LOGICAL lane
|
|
20
|
+
* for callers with a logical send identity, WINDOW-based CONTENT-HASH lane
|
|
21
|
+
* for callers without one — R3-M1/R7-M2/R8-M1);
|
|
22
|
+
* - the §3.5.2 bind-pin overlay + record-carried `boundTuple` delivery rule
|
|
23
|
+
* with the SHARED id↔tuple coherence check (R4-M1/R5-M2/R6-M4);
|
|
24
|
+
* - the §5.1 permanent-vs-transient classification over
|
|
25
|
+
* `SlackApiError.slackError` (+ the L5 drift canary), the reachability
|
|
26
|
+
* flip/auto-clear, flap dampening, and mass-unreachable aggregation.
|
|
27
|
+
*
|
|
28
|
+
* Still NOT here (their §6.1 increments): the `deterministicKind` gate-exempt
|
|
29
|
+
* arm (increment 3), the §5.2 P17 budgets (increment 5).
|
|
30
|
+
*/
|
|
31
|
+
import { createHash } from 'node:crypto';
|
|
32
|
+
import { idWithinCoherenceBound, routingKeyForTuple, SLACK_CHANNEL_ID_RE, SLACK_THREAD_TS_RE, } from './conversationIdentity.js';
|
|
33
|
+
/** §5.1 pinned PERMANENT `chat.postMessage` error codes — the code is
|
|
34
|
+
* `is_archived`, NOT `channel_archived` (adversarial-A2/codex-X4). DISTINCT
|
|
35
|
+
* from the adapter's token-scoped `SlackApiError.permanent` set. */
|
|
36
|
+
export const CONVERSATION_UNREACHABLE_ERRORS = new Set(['is_archived', 'channel_not_found', 'not_in_channel']);
|
|
37
|
+
/** L5 drift canary: an unrecognized permanent-SHAPED channel-state code is
|
|
38
|
+
* treated TRANSIENT (safe default — the beacon retries) + ONE deduped
|
|
39
|
+
* attention item so the pinned set can be updated. */
|
|
40
|
+
const PERMANENT_SHAPED_RE = /archiv|not_found|not_in_|restricted|access_denied/;
|
|
41
|
+
/** Network failures that are positive PRE-ACCEPT evidence (never posted). */
|
|
42
|
+
const CLEAN_NETWORK_RE = /\b(ECONNREFUSED|ENOTFOUND|EAI_AGAIN)\b/;
|
|
43
|
+
/** Content-hash lane length gate — mirrors the Telegram exact-duplicate
|
|
44
|
+
* dedup's `minLength` (brief acks are never suppressed). */
|
|
45
|
+
export const CONTENT_HASH_MIN_LENGTH = 40;
|
|
46
|
+
/** §5.1 R2-lessons-2/P17 pinned emitter coalescing window (mass-unreachable). */
|
|
47
|
+
export const UNREACHABLE_COALESCING_WINDOW_MS = 60000;
|
|
48
|
+
/**
|
|
49
|
+
* Classify a Slack-arm send failure (§5.1 + §5.0(a) R2-security-NEW-3).
|
|
50
|
+
* A `SlackApiError` means Slack ANSWERED `ok:false` — positive evidence the
|
|
51
|
+
* message did NOT post (clean), further split permanent/canary/transient.
|
|
52
|
+
* A pre-accept network refusal is clean. Everything else (timeout, reset,
|
|
53
|
+
* unknown) is AMBIGUOUS — the message may actually have posted, so the E1
|
|
54
|
+
* suppressor IS recorded (only a CLEAN failure forbids recording).
|
|
55
|
+
*/
|
|
56
|
+
export function classifySlackSendError(err) {
|
|
57
|
+
const anyErr = err;
|
|
58
|
+
const slackError = anyErr && typeof anyErr.slackError === 'string' ? anyErr.slackError : null;
|
|
59
|
+
if (slackError) {
|
|
60
|
+
if (CONVERSATION_UNREACHABLE_ERRORS.has(slackError))
|
|
61
|
+
return { kind: 'permanent', code: slackError };
|
|
62
|
+
if (PERMANENT_SHAPED_RE.test(slackError))
|
|
63
|
+
return { kind: 'permanent-shaped-unknown', code: slackError };
|
|
64
|
+
return { kind: 'clean-transient', detail: slackError };
|
|
65
|
+
}
|
|
66
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
67
|
+
if (CLEAN_NETWORK_RE.test(msg))
|
|
68
|
+
return { kind: 'clean-transient', detail: msg };
|
|
69
|
+
return { kind: 'ambiguous', detail: msg };
|
|
70
|
+
}
|
|
71
|
+
/** Shape-clamp a caller-supplied boundTuple (§3.5.2: a malformed/forged tuple
|
|
72
|
+
* falls back to `resolve(id)` — never a crash, never an unclamped tuple applied). */
|
|
73
|
+
function clampBoundTuple(raw) {
|
|
74
|
+
if (!raw || raw.platform !== 'slack' || typeof raw.channelId !== 'string')
|
|
75
|
+
return null;
|
|
76
|
+
if (!SLACK_CHANNEL_ID_RE.test(raw.channelId))
|
|
77
|
+
return null;
|
|
78
|
+
const threadTs = raw.threadTs ?? null;
|
|
79
|
+
if (threadTs !== null && (typeof threadTs !== 'string' || !SLACK_THREAD_TS_RE.test(threadTs)))
|
|
80
|
+
return null;
|
|
81
|
+
return { platform: 'slack', channelId: raw.channelId, threadTs };
|
|
82
|
+
}
|
|
1
83
|
export function createConversationDelivery(deps) {
|
|
84
|
+
const attention = (dedupeKey, title, body) => {
|
|
85
|
+
try {
|
|
86
|
+
deps.onAttention?.(dedupeKey, title, body);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
/* @silent-fallback-ok — attention is observability; a failed raise never gates delivery */
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
// ── §5.1 mass-unreachable aggregation (R2-lessons-2/P17): terminal
|
|
93
|
+
// dead-letters within one coalescing window collapse into ONE summary item —
|
|
94
|
+
// a bot-removed-from-workspace event yields ONE item, not N. ──
|
|
95
|
+
const windowMs = deps.coalescingWindowMs ?? UNREACHABLE_COALESCING_WINDOW_MS;
|
|
96
|
+
let unreachableBatch = [];
|
|
97
|
+
let unreachableTimer = null;
|
|
98
|
+
const flushUnreachable = () => {
|
|
99
|
+
const batch = unreachableBatch;
|
|
100
|
+
unreachableBatch = [];
|
|
101
|
+
unreachableTimer = null;
|
|
102
|
+
if (batch.length === 0)
|
|
103
|
+
return;
|
|
104
|
+
const list = batch.map((b) => `${b.id} (${b.channelId})`).join(', ');
|
|
105
|
+
attention(batch.length === 1 ? `conversation-unreachable:${batch[0].id}` : 'conversation-unreachable:mass', `${batch.length} conversation(s) became unreachable`, `Permanent Slack delivery errors flipped reachability to 'unreachable' for: ${list}. Bot removed from the workspace/channel, or the channel was archived? Reachability auto-clears on the next successful delivery or authenticated inbound (§5.1).`);
|
|
106
|
+
};
|
|
107
|
+
const reportUnreachable = (entryId, channelId, dampened) => {
|
|
108
|
+
if (dampened) {
|
|
109
|
+
// R3-minor flap dampening: ONE per-window flap item instead of a fresh
|
|
110
|
+
// cross-window dead-letter per archived↔unarchived bounce episode.
|
|
111
|
+
attention(`conversation-reachability-flap:${entryId}`, 'Conversation reachability is flapping', `Conversation ${entryId} (${channelId}) flipped between reachable/unreachable more than the flap threshold within 24h. Further flips this window update state silently.`);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
unreachableBatch.push({ id: entryId, channelId });
|
|
115
|
+
if (!unreachableTimer) {
|
|
116
|
+
unreachableTimer = setTimeout(flushUnreachable, windowMs);
|
|
117
|
+
unreachableTimer.unref?.();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
2
120
|
return async (id, text, opts) => {
|
|
3
121
|
// id > 0 → today's Telegram path, all existing layers unchanged.
|
|
4
122
|
if (id > 0) {
|
|
@@ -17,25 +135,75 @@ export function createConversationDelivery(deps) {
|
|
|
17
135
|
};
|
|
18
136
|
}
|
|
19
137
|
}
|
|
20
|
-
// id < 0 → minted conversation. Resolve
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
138
|
+
// ── id < 0 → minted conversation. Resolve the delivery TARGET through the
|
|
139
|
+
// §3.5.2 overlay FIRST (record-carried boundTuple, then the local
|
|
140
|
+
// journaled pin), so the dark/dry audit line names the real target. ──
|
|
141
|
+
const boundTuple = clampBoundTuple(opts?.boundTuple);
|
|
142
|
+
let overlayTuple = null;
|
|
143
|
+
if (boundTuple) {
|
|
144
|
+
// Delivery-time id↔tuple coherence (R5-M2, SHARED predicate — the same
|
|
145
|
+
// implementation the §3.5 ingest check uses). Coherence-STABILITY holds
|
|
146
|
+
// for every legitimate flow, so an incoherent pair affirmatively proves
|
|
147
|
+
// corruption: typed refusal, NEVER a delivery on either field (R6-M4).
|
|
148
|
+
if (!idWithinCoherenceBound(id, boundTuple)) {
|
|
149
|
+
attention(`conversation-binding-incoherent:${id}`, 'Durable binding failed the id↔tuple coherence check', `A binding stored topicId ${id} beside boundTuple ${routingKeyForTuple(boundTuple)}, but the id is not within MAX_PROBE_DISTANCE of the tuple's candidate (§3.5.2 R5-M2). This proves corruption of one field; delivery is refused on BOTH (typed conversation-binding-incoherent — the beacon re-arms, the N-fail dead-letter escalates).`);
|
|
150
|
+
return {
|
|
151
|
+
delivered: false,
|
|
152
|
+
outcome: 'not-delivered',
|
|
153
|
+
reason: 'conversation-binding-incoherent',
|
|
154
|
+
detail: `stored id ${id} incoherent with boundTuple ${routingKeyForTuple(boundTuple)}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
overlayTuple = boundTuple;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
overlayTuple = deps.registry.getBindPinTuple(id);
|
|
161
|
+
}
|
|
162
|
+
let resolved;
|
|
163
|
+
if (overlayTuple) {
|
|
164
|
+
// §3.5.2 property 3/5: the target is the pin's tuple at its CURRENT
|
|
165
|
+
// assignment — resolve(tuple), not resolve(id).
|
|
166
|
+
resolved = deps.registry.resolveByKey(routingKeyForTuple(overlayTuple));
|
|
167
|
+
if (!resolved || resolved.platform !== 'slack') {
|
|
168
|
+
// Pin-tuple pending-mint degradation (§3.5.2): typed non-delivery +
|
|
169
|
+
// one deduped attention — the beacon retries; never a misdeliver.
|
|
170
|
+
attention(`conversation-binding-pending:${id}`, 'Durable binding target has no current assignment', `The bind-time tuple ${routingKeyForTuple(overlayTuple)} for binding id ${id} is in the pending-mint state (no current registry assignment). Delivery returns a typed non-delivery; the beacon retries.`);
|
|
171
|
+
return {
|
|
172
|
+
delivered: false,
|
|
173
|
+
outcome: 'not-delivered',
|
|
174
|
+
reason: 'binding-target-unresolved',
|
|
175
|
+
detail: `bound tuple ${routingKeyForTuple(overlayTuple)} has no current assignment`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
if (resolved.id !== id) {
|
|
179
|
+
// The first time a pin actually REDIRECTS: ONE deduped attention item
|
|
180
|
+
// per pin episode (per pin, not per message) — visible, never silent.
|
|
181
|
+
attention(`conversation-bind-redirect:${id}`, 'A durable binding redirected through its bind-time tuple', `Binding id ${id} now delivers into ${routingKeyForTuple(overlayTuple)} (current assignment ${resolved.id}) — a later merge/re-mint moved the id, and the bound consumer's messages still land in the conversation the promise was made in (§3.5.2 property 3).`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
resolved = deps.registry.resolve(id);
|
|
186
|
+
if (!resolved || resolved.platform !== 'slack') {
|
|
187
|
+
attention(`conversation-non-owning:${id}`, 'A minted-conversation delivery was requested on a machine that cannot resolve it', `No local registry entry resolves ${id} (never minted on this machine, or id is 0). Heal paths: deliver from the owning machine (§5.0), or enable multiMachine.stateSync.conversations (§6.1 step 9) for multi-machine Slack follow-through.`);
|
|
188
|
+
return {
|
|
189
|
+
delivered: false,
|
|
190
|
+
outcome: 'not-delivered',
|
|
191
|
+
reason: 'unresolvable',
|
|
192
|
+
detail: `no local registry entry resolves ${id} (never minted on this machine, or id is 0)`,
|
|
193
|
+
standDown: true,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
30
196
|
}
|
|
31
197
|
// KYP (§3.5/§7): delivery resolves ONLY local-origin entries. A pure
|
|
32
198
|
// `replicated` entry is read-context until locally corroborated.
|
|
33
199
|
if (resolved.origin === 'replicated') {
|
|
200
|
+
attention(`conversation-non-owning:${id}`, 'A minted-conversation delivery was requested on a non-owning machine', `The entry for ${id} is replicated-only (advisory) — the owning machine delivers (§5.0). Heal paths: ownership adoption on first authenticated inbound, or the §11.2 owner/lease reconciliation.`);
|
|
34
201
|
return {
|
|
35
202
|
delivered: false,
|
|
36
203
|
outcome: 'not-delivered',
|
|
37
204
|
reason: 'replicated-only-origin',
|
|
38
205
|
detail: `entry for ${id} is replicated-only (advisory) — the owning machine delivers (§5.0)`,
|
|
206
|
+
standDown: true,
|
|
39
207
|
};
|
|
40
208
|
}
|
|
41
209
|
if (deps.isSystemChannel?.(resolved.channelId)) {
|
|
@@ -60,24 +228,145 @@ export function createConversationDelivery(deps) {
|
|
|
60
228
|
return { delivered: false, outcome: 'not-delivered', reason: 'follow-through-dry-run' };
|
|
61
229
|
}
|
|
62
230
|
if (!deps.sendSlack) {
|
|
231
|
+
attention(`conversation-non-owning:${id}`, 'A minted-conversation delivery was requested with no local Slack adapter', `No local Slack adapter — the owning machine delivers (§5.0). Heal paths: deliver from the machine holding the Slack socket.`);
|
|
63
232
|
return {
|
|
64
233
|
delivered: false,
|
|
65
234
|
outcome: 'not-delivered',
|
|
66
235
|
reason: 'no-slack-adapter',
|
|
67
236
|
detail: 'no local Slack adapter — the owning machine delivers (§5.0)',
|
|
237
|
+
standDown: true,
|
|
68
238
|
};
|
|
69
239
|
}
|
|
240
|
+
// ── §5.0(a) E1 ambiguous-outcome idempotency guard (LIVE sends only) ──
|
|
241
|
+
// Lane selection (R7-M2): a caller-supplied logical send identity rides the
|
|
242
|
+
// retirement-based lane; everyone else rides the WINDOW-based content-hash
|
|
243
|
+
// lane, length-gated exactly like the Telegram dedup (brief acks never
|
|
244
|
+
// suppressed). `allowDuplicate` bypasses for a deliberate operator resend.
|
|
245
|
+
const normalized = text.replace(/\s+/g, ' ').trim();
|
|
246
|
+
let lane = null;
|
|
247
|
+
let sendId = null;
|
|
248
|
+
if (opts?.logicalSendId) {
|
|
249
|
+
lane = 'logical';
|
|
250
|
+
sendId = opts.logicalSendId;
|
|
251
|
+
}
|
|
252
|
+
else if (normalized.length >= CONTENT_HASH_MIN_LENGTH) {
|
|
253
|
+
lane = 'content-hash';
|
|
254
|
+
sendId = `sha256:${createHash('sha256').update(normalized).digest('hex').slice(0, 32)}`;
|
|
255
|
+
}
|
|
256
|
+
if (lane && sendId && !opts?.allowDuplicate && deps.registry.isSendSuppressed(id, sendId, lane)) {
|
|
257
|
+
return { delivered: false, outcome: 'already-delivered-recently' };
|
|
258
|
+
}
|
|
259
|
+
// Durable SEND-INTENT (R6-M1): fsynced BEFORE the transport send — beacon
|
|
260
|
+
// sends are minutes apart, so the extra fsync is off any hot path.
|
|
261
|
+
if (lane && sendId) {
|
|
262
|
+
try {
|
|
263
|
+
deps.registry.recordSendIntent(id, sendId, lane);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
/* @silent-fallback-ok — a failed intent write degrades toward the
|
|
267
|
+
pre-E1 posture for THIS send (delivery still proceeds; identity/
|
|
268
|
+
bookkeeping never costs a message, §3.6). */
|
|
269
|
+
}
|
|
270
|
+
}
|
|
70
271
|
try {
|
|
71
272
|
// Thread-level conversations deliver IN-THREAD (§5).
|
|
72
273
|
await deps.sendSlack(resolved.channelId, text, resolved.threadTs ?? undefined, opts);
|
|
274
|
+
// Suppressor recorded ONLY after positive likely-posted evidence — the
|
|
275
|
+
// deployed Telegram precedent (R2-security-NEW-3). Retirement (seq
|
|
276
|
+
// advance + send-retire) is the CALLER's under the R5-M3 pinned order.
|
|
277
|
+
if (lane && sendId) {
|
|
278
|
+
try {
|
|
279
|
+
deps.registry.recordLikelyPosted(id, sendId, lane);
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
/* @silent-fallback-ok — guard bookkeeping never turns a delivered
|
|
283
|
+
message into a failure (§3.6 fail-toward-delivery). */
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// §5.1 reachability auto-clear on the next successful delivery.
|
|
287
|
+
if (resolved.reachability === 'unreachable') {
|
|
288
|
+
try {
|
|
289
|
+
deps.registry.setReachability(resolved.id, 'ok');
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
/* @silent-fallback-ok — advisory metadata */
|
|
293
|
+
}
|
|
294
|
+
}
|
|
73
295
|
return { delivered: true, outcome: 'delivered' };
|
|
74
296
|
}
|
|
75
297
|
catch (err) {
|
|
298
|
+
const cls = classifySlackSendError(err);
|
|
299
|
+
if (cls.kind === 'permanent') {
|
|
300
|
+
// §5.1: positive not-posted evidence — resolve the intent (no
|
|
301
|
+
// suppressor), flip reachability idempotently, aggregate the
|
|
302
|
+
// dead-letter at the emitter.
|
|
303
|
+
if (lane && sendId) {
|
|
304
|
+
try {
|
|
305
|
+
deps.registry.resolveSendIntent(id, sendId);
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
/* @silent-fallback-ok — see above */
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
const flip = deps.registry.setReachability(resolved.id, 'unreachable');
|
|
313
|
+
if (flip.changed)
|
|
314
|
+
reportUnreachable(resolved.id, resolved.channelId, flip.dampened);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
/* @silent-fallback-ok — advisory metadata */
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
delivered: false,
|
|
321
|
+
outcome: 'not-delivered',
|
|
322
|
+
reason: 'conversation-unreachable',
|
|
323
|
+
permanent: true,
|
|
324
|
+
detail: cls.code,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
if (cls.kind === 'permanent-shaped-unknown') {
|
|
328
|
+
// L5 drift canary: NOT silently mis-bucketed — transient (safe
|
|
329
|
+
// default, the beacon retries) + ONE deduped attention item.
|
|
330
|
+
if (lane && sendId) {
|
|
331
|
+
try {
|
|
332
|
+
deps.registry.resolveSendIntent(id, sendId);
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
/* @silent-fallback-ok */
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
attention(`slack-permanent-drift:${cls.code}`, 'Unrecognized permanent-shaped Slack error (drift canary)', `chat.postMessage returned "${cls.code}" — permanent-SHAPED but not in the pinned set {is_archived, channel_not_found, not_in_channel}. Treated TRANSIENT (safe default — the beacon retries). If Slack added a channel-state code, update the pinned set (§5.1 L5).`);
|
|
339
|
+
return { delivered: false, outcome: 'not-delivered', reason: 'send-failed', detail: cls.code };
|
|
340
|
+
}
|
|
341
|
+
if (cls.kind === 'clean-transient') {
|
|
342
|
+
// Positive evidence the message never posted — the retry must NOT be
|
|
343
|
+
// suppressed (R2-security-NEW-3): resolve the intent, record nothing.
|
|
344
|
+
if (lane && sendId) {
|
|
345
|
+
try {
|
|
346
|
+
deps.registry.resolveSendIntent(id, sendId);
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
/* @silent-fallback-ok */
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return { delivered: false, outcome: 'not-delivered', reason: 'send-failed', detail: cls.detail };
|
|
353
|
+
}
|
|
354
|
+
// AMBIGUOUS (timeout/reset/unknown — the message may have posted):
|
|
355
|
+
// record the suppressor so the re-fire of the SAME logical send is
|
|
356
|
+
// suppressed whenever it arrives (§5.0(a)).
|
|
357
|
+
if (lane && sendId) {
|
|
358
|
+
try {
|
|
359
|
+
deps.registry.recordLikelyPosted(id, sendId, lane);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
/* @silent-fallback-ok */
|
|
363
|
+
}
|
|
364
|
+
}
|
|
76
365
|
return {
|
|
77
366
|
delivered: false,
|
|
78
367
|
outcome: 'not-delivered',
|
|
79
368
|
reason: 'send-failed',
|
|
80
|
-
detail:
|
|
369
|
+
detail: `ambiguous: ${cls.detail}`,
|
|
81
370
|
};
|
|
82
371
|
}
|
|
83
372
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliverToConversation.js","sourceRoot":"","sources":["../../src/core/deliverToConversation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deliverToConversation.js","sourceRoot":"","sources":["../../src/core/deliverToConversation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAEL,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAsDnC;;qEAEqE;AACrE,MAAM,CAAC,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE/G;;uDAEuD;AACvD,MAAM,mBAAmB,GAAG,mDAAmD,CAAC;AAEhF,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG,wCAAwC,CAAC;AAElE;6DAC6D;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAE1C,iFAAiF;AACjF,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,CAAC;AAQtD;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,MAAM,MAAM,GAAG,GAAsC,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9F,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,+BAA+B,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACpG,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACxG,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACzD,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAChF,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC5C,CAAC;AAyBD;sFACsF;AACtF,SAAS,eAAe,CAAC,GAA8B;IACrD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC;IACtC,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3G,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,IAA8B;IACvE,MAAM,SAAS,GAAG,CAAC,SAAiB,EAAE,KAAa,EAAE,IAAY,EAAQ,EAAE;QACzE,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,2FAA2F;QAC7F,CAAC;IACH,CAAC,CAAC;IAEF,oEAAoE;IACpE,6EAA6E;IAC7E,gEAAgE;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,IAAI,gCAAgC,CAAC;IAC7E,IAAI,gBAAgB,GAA6C,EAAE,CAAC;IACpE,IAAI,gBAAgB,GAA0B,IAAI,CAAC;IACnD,MAAM,gBAAgB,GAAG,GAAS,EAAE;QAClC,MAAM,KAAK,GAAG,gBAAgB,CAAC;QAC/B,gBAAgB,GAAG,EAAE,CAAC;QACtB,gBAAgB,GAAG,IAAI,CAAC;QACxB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,SAAS,CACP,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,4BAA4B,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,+BAA+B,EAChG,GAAG,KAAK,CAAC,MAAM,qCAAqC,EACpD,8EAA8E,IAAI,kKAAkK,CACrP,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAE,SAAiB,EAAE,QAAiB,EAAQ,EAAE;QACxF,IAAI,QAAQ,EAAE,CAAC;YACb,uEAAuE;YACvE,mEAAmE;YACnE,SAAS,CACP,kCAAkC,OAAO,EAAE,EAC3C,uCAAuC,EACvC,gBAAgB,OAAO,KAAK,SAAS,mIAAmI,CACzK,CAAC;YACF,OAAO;QACT,CAAC;QACD,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,gBAAgB,GAAG,UAAU,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;YAC1D,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,KAAK,EAAE,EAAU,EAAE,IAAY,EAAE,IAAkB,EAA4B,EAAE;QACtF,iEAAiE;QACjE,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBACnD,OAAO,EAAE;oBACP,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE;oBAC3C,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;YACrF,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO;oBACL,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,eAAe;oBACxB,MAAM,EAAE,sBAAsB;oBAC9B,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACzD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,kEAAkE;QAClE,uEAAuE;QACvE,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,YAAY,GAA6B,IAAI,CAAC;QAClD,IAAI,UAAU,EAAE,CAAC;YACf,uEAAuE;YACvE,wEAAwE;YACxE,wEAAwE;YACxE,uEAAuE;YACvE,IAAI,CAAC,sBAAsB,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC5C,SAAS,CACP,mCAAmC,EAAE,EAAE,EACvC,qDAAqD,EACrD,4BAA4B,EAAE,sBAAsB,kBAAkB,CAAC,UAAU,CAAC,yPAAyP,CAC5U,CAAC;gBACF,OAAO;oBACL,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,eAAe;oBACxB,MAAM,EAAE,iCAAiC;oBACzC,MAAM,EAAE,aAAa,EAAE,+BAA+B,kBAAkB,CAAC,UAAU,CAAC,EAAE;iBACvF,CAAC;YACJ,CAAC;YACD,YAAY,GAAG,UAAU,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,QAAqD,CAAC;QAC1D,IAAI,YAAY,EAAE,CAAC;YACjB,oEAAoE;YACpE,gDAAgD;YAChD,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;YACxE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC/C,oEAAoE;gBACpE,kEAAkE;gBAClE,SAAS,CACP,gCAAgC,EAAE,EAAE,EACpC,kDAAkD,EAClD,uBAAuB,kBAAkB,CAAC,YAAY,CAAC,mBAAmB,EAAE,4HAA4H,CACzM,CAAC;gBACF,OAAO;oBACL,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,eAAe;oBACxB,MAAM,EAAE,2BAA2B;oBACnC,MAAM,EAAE,eAAe,kBAAkB,CAAC,YAAY,CAAC,4BAA4B;iBACpF,CAAC;YACJ,CAAC;YACD,IAAI,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvB,sEAAsE;gBACtE,sEAAsE;gBACtE,SAAS,CACP,8BAA8B,EAAE,EAAE,EAClC,0DAA0D,EAC1D,cAAc,EAAE,sBAAsB,kBAAkB,CAAC,YAAY,CAAC,wBAAwB,QAAQ,CAAC,EAAE,uJAAuJ,CACjQ,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACrC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAC/C,SAAS,CACP,2BAA2B,EAAE,EAAE,EAC/B,kFAAkF,EAClF,oCAAoC,EAAE,uMAAuM,CAC9O,CAAC;gBACF,OAAO;oBACL,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,eAAe;oBACxB,MAAM,EAAE,cAAc;oBACtB,MAAM,EAAE,oCAAoC,EAAE,6CAA6C;oBAC3F,SAAS,EAAE,IAAI;iBAChB,CAAC;YACJ,CAAC;QACH,CAAC;QAED,qEAAqE;QACrE,iEAAiE;QACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YACrC,SAAS,CACP,2BAA2B,EAAE,EAAE,EAC/B,sEAAsE,EACtE,iBAAiB,EAAE,8KAA8K,CAClM,CAAC;YACF,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,eAAe;gBACxB,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE,aAAa,EAAE,qEAAqE;gBAC5F,SAAS,EAAE,IAAI;aAChB,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;QAC7F,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,eAAe;gBACxB,MAAM,EAAE,qBAAqB;gBAC7B,MAAM,EAAE,0DAA0D;aACnE,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,IAAI,CAAC,iBAAiB,EAAE,CACtB,kDAAkD,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC,MAAM,SAAS,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAC3M,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;YACD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,SAAS,CACP,2BAA2B,EAAE,EAAE,EAC/B,0EAA0E,EAC1E,6HAA6H,CAC9H,CAAC;YACF,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,eAAe;gBACxB,MAAM,EAAE,kBAAkB;gBAC1B,MAAM,EAAE,6DAA6D;gBACrE,SAAS,EAAE,IAAI;aAChB,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,4EAA4E;QAC5E,2EAA2E;QAC3E,uEAAuE;QACvE,2EAA2E;QAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,IAAI,GAAsC,IAAI,CAAC;QACnD,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;YACxB,IAAI,GAAG,SAAS,CAAC;YACjB,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;QAC9B,CAAC;aAAM,IAAI,UAAU,CAAC,MAAM,IAAI,uBAAuB,EAAE,CAAC;YACxD,IAAI,GAAG,cAAc,CAAC;YACtB,MAAM,GAAG,UAAU,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC1F,CAAC;QAED,IAAI,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,EAAE,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YAChG,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC;QACrE,CAAC;QAED,0EAA0E;QAC1E,mEAAmE;QACnE,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YACnD,CAAC;YAAC,MAAM,CAAC;gBACP;;+DAE+C;YACjD,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,qDAAqD;YACrD,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,IAAI,SAAS,EAAE,IAAI,CAAC,CAAC;YACrF,uEAAuE;YACvE,mEAAmE;YACnE,uEAAuE;YACvE,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACP;6EACyD;gBAC3D,CAAC;YACH,CAAC;YACD,gEAAgE;YAChE,IAAI,QAAQ,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBAC5C,IAAI,CAAC;oBACH,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBACnD,CAAC;gBAAC,MAAM,CAAC;oBACP,6CAA6C;gBAC/C,CAAC;YACH,CAAC;YACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC7B,8DAA8D;gBAC9D,6DAA6D;gBAC7D,8BAA8B;gBAC9B,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBACnB,IAAI,CAAC;wBACH,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;oBAC9C,CAAC;oBAAC,MAAM,CAAC;wBACP,qCAAqC;oBACvC,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;oBACvE,IAAI,IAAI,CAAC,OAAO;wBAAE,iBAAiB,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACtF,CAAC;gBAAC,MAAM,CAAC;oBACP,6CAA6C;gBAC/C,CAAC;gBACD,OAAO;oBACL,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,eAAe;oBACxB,MAAM,EAAE,0BAA0B;oBAClC,SAAS,EAAE,IAAI;oBACf,MAAM,EAAE,GAAG,CAAC,IAAI;iBACjB,CAAC;YACJ,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,0BAA0B,EAAE,CAAC;gBAC5C,+DAA+D;gBAC/D,6DAA6D;gBAC7D,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBACnB,IAAI,CAAC;wBACH,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;oBAC9C,CAAC;oBAAC,MAAM,CAAC;wBACP,yBAAyB;oBAC3B,CAAC;gBACH,CAAC;gBACD,SAAS,CACP,yBAAyB,GAAG,CAAC,IAAI,EAAE,EACnC,0DAA0D,EAC1D,8BAA8B,GAAG,CAAC,IAAI,+NAA+N,CACtQ,CAAC;gBACF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;YACjG,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACnC,qEAAqE;gBACrE,sEAAsE;gBACtE,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;oBACnB,IAAI,CAAC;wBACH,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;oBAC9C,CAAC;oBAAC,MAAM,CAAC;wBACP,yBAAyB;oBAC3B,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;YACnG,CAAC;YACD,mEAAmE;YACnE,mEAAmE;YACnE,4CAA4C;YAC5C,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACP,yBAAyB;gBAC3B,CAAC;YACH,CAAC;YACD,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,eAAe;gBACxB,MAAM,EAAE,aAAa;gBACrB,MAAM,EAAE,cAAc,GAAG,CAAC,MAAM,EAAE;aACnC,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -67,17 +67,15 @@ export declare function parseSlackConversationKey(key: string): string | null;
|
|
|
67
67
|
/**
|
|
68
68
|
* Stable negative synthetic topic id for a Slack routing key.
|
|
69
69
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
70
|
+
* §4 (durable-conversation-identity, increment 2): the hash copy this module
|
|
71
|
+
* carried is RETIRED — this is a re-export of `candidateIdForRoutingKey` from
|
|
72
|
+
* the ONE consolidated identity surface, value-identical by golden parity
|
|
73
|
+
* (§10). It is the mint CANDIDATE, no longer an identity authority (the
|
|
74
|
+
* ConversationRegistry is the collision authority). RefreshResult keeps a
|
|
75
|
+
* numeric `topicId` for back-compat consumers (e.g. the restart-all log line
|
|
76
|
+
* reads result.topicId); Slack results carry this candidate id so those
|
|
75
77
|
* consumers stay type- and meaning-compatible with the rest of the system's
|
|
76
78
|
* Slack↔numeric bridging (PresenceProxy, resume heartbeat).
|
|
77
|
-
*
|
|
78
|
-
* NOTE for the integrating session: this is now the THIRD copy of the hash —
|
|
79
|
-
* consolidating server.ts + routes.ts onto this export is a wiring follow-up
|
|
80
|
-
* (both files are owned by other builders in this round).
|
|
81
79
|
*/
|
|
82
|
-
export
|
|
80
|
+
export { candidateIdForRoutingKey as slackRoutingKeySyntheticId } from './conversationIdentity.js';
|
|
83
81
|
//# sourceMappingURL=slackRefreshBinding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slackRefreshBinding.d.ts","sourceRoot":"","sources":["../../src/core/slackRefreshBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC;qEACiE;IACjE,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACzD;;;oCAGgC;IAChC,gCAAgC,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACtE;;;+BAG2B;IAC3B,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KACtD,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,eAAO,MAAM,6BAA6B,WAAW,CAAC;AAEtD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIpE;AAED
|
|
1
|
+
{"version":3,"file":"slackRefreshBinding.d.ts","sourceRoot":"","sources":["../../src/core/slackRefreshBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC;qEACiE;IACjE,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACzD;;;oCAGgC;IAChC,gCAAgC,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACtE;;;+BAG2B;IAC3B,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KACtD,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,eAAO,MAAM,6BAA6B,WAAW,CAAC;AAEtD,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIpE;AAED;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,wBAAwB,IAAI,0BAA0B,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -32,23 +32,15 @@ export function parseSlackConversationKey(key) {
|
|
|
32
32
|
/**
|
|
33
33
|
* Stable negative synthetic topic id for a Slack routing key.
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
35
|
+
* §4 (durable-conversation-identity, increment 2): the hash copy this module
|
|
36
|
+
* carried is RETIRED — this is a re-export of `candidateIdForRoutingKey` from
|
|
37
|
+
* the ONE consolidated identity surface, value-identical by golden parity
|
|
38
|
+
* (§10). It is the mint CANDIDATE, no longer an identity authority (the
|
|
39
|
+
* ConversationRegistry is the collision authority). RefreshResult keeps a
|
|
40
|
+
* numeric `topicId` for back-compat consumers (e.g. the restart-all log line
|
|
41
|
+
* reads result.topicId); Slack results carry this candidate id so those
|
|
40
42
|
* consumers stay type- and meaning-compatible with the rest of the system's
|
|
41
43
|
* Slack↔numeric bridging (PresenceProxy, resume heartbeat).
|
|
42
|
-
*
|
|
43
|
-
* NOTE for the integrating session: this is now the THIRD copy of the hash —
|
|
44
|
-
* consolidating server.ts + routes.ts onto this export is a wiring follow-up
|
|
45
|
-
* (both files are owned by other builders in this round).
|
|
46
44
|
*/
|
|
47
|
-
export
|
|
48
|
-
let hash = 0;
|
|
49
|
-
for (let i = 0; i < routingKey.length; i++) {
|
|
50
|
-
hash = ((hash << 5) - hash + routingKey.charCodeAt(i)) | 0;
|
|
51
|
-
}
|
|
52
|
-
return -(Math.abs(hash) + 1); // always negative, never 0
|
|
53
|
-
}
|
|
45
|
+
export { candidateIdForRoutingKey as slackRoutingKeySyntheticId } from './conversationIdentity.js';
|
|
54
46
|
//# sourceMappingURL=slackRefreshBinding.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slackRefreshBinding.js","sourceRoot":"","sources":["../../src/core/slackRefreshBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAgDH,MAAM,CAAC,MAAM,6BAA6B,GAAG,QAAQ,CAAC;AAEtD,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,OAAO,GAAG,6BAA6B,GAAG,UAAU,EAAE,CAAC;AACzD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACnE,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"slackRefreshBinding.js","sourceRoot":"","sources":["../../src/core/slackRefreshBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAgDH,MAAM,CAAC,MAAM,6BAA6B,GAAG,QAAQ,CAAC;AAEtD,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,OAAO,GAAG,6BAA6B,GAAG,UAAU,EAAE,CAAC;AACzD,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,6BAA6B,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACnE,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,wBAAwB,IAAI,0BAA0B,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -148,6 +148,15 @@ export type ModelTier = 'opus' | 'sonnet' | 'haiku';
|
|
|
148
148
|
export interface SessionManagerConfig {
|
|
149
149
|
/** Project name used as the stable local agent id for auth-bound calls. */
|
|
150
150
|
projectName: string;
|
|
151
|
+
/**
|
|
152
|
+
* durable-conversation-identity §7 (R4-M3): mint the per-session
|
|
153
|
+
* SELF-AUTHENTICATING bind token delivered through the spawn env
|
|
154
|
+
* (`INSTAR_BIND_TOKEN` in the tmux -e block — never over a route). The
|
|
155
|
+
* payload carries the session's authenticated bootstrap conversation ids;
|
|
156
|
+
* a durable-state open on a minted id is validated against that set.
|
|
157
|
+
* Absent → no token env is injected (legacy spawns).
|
|
158
|
+
*/
|
|
159
|
+
mintBindToken?: (sessionName: string, bootstrapConversationIds: number[]) => string | null;
|
|
151
160
|
/** Path to tmux binary */
|
|
152
161
|
tmuxPath: string;
|
|
153
162
|
/**
|