instar 1.3.861 → 1.3.862
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 +49 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/core/SessionPoolLocalClaim.d.ts +24 -0
- package/dist/core/SessionPoolLocalClaim.d.ts.map +1 -0
- package/dist/core/SessionPoolLocalClaim.js +38 -0
- package/dist/core/SessionPoolLocalClaim.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/upgrades/1.3.862.md +27 -0
- package/upgrades/side-effects/session-pool-self-placement-confirmation.md +99 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0DH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA0BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0DH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA0BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA8H7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2pDD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,oBAAoB,GAAG,IAAI,GACxC;IACD,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAqBA;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,EAQrD,oBAAoB,CAAC,EAAE,MAAM;IAC3B,YAAY,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,GACP,IAAI,CAwtBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgloBtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -105,6 +105,7 @@ import { SessionMonitor } from '../monitoring/SessionMonitor.js';
|
|
|
105
105
|
import { SessionRecovery } from '../monitoring/SessionRecovery.js';
|
|
106
106
|
import { MultiMachineCoordinator } from '../core/MultiMachineCoordinator.js';
|
|
107
107
|
import { isRemotelyHandled } from '../core/SessionRouter.js';
|
|
108
|
+
import { confirmLocalPlacementAfterDelivery } from '../core/SessionPoolLocalClaim.js';
|
|
108
109
|
import { decideLeaseGatedSpawn, sharedG3SoakLedger, applyBindingCleanupOnKill } from '../core/leaseGatedSpawn.js';
|
|
109
110
|
import { isSlackSessionKey, reconstructSlackMessage } from '../core/SlackForwardBridge.js';
|
|
110
111
|
import { formatForwardedTopicContext } from '../core/ForwardedTopicContext.js';
|
|
@@ -474,6 +475,11 @@ let _topicResumeMap = null;
|
|
|
474
475
|
// is byte-identical to today's always-local dispatch. Set once in startServer().
|
|
475
476
|
let _sessionRouter = null;
|
|
476
477
|
let _sessionPoolStage = () => 'dark';
|
|
478
|
+
// Self-placement deliberately falls through from SessionRouter into this file's
|
|
479
|
+
// established local inject/spawn tail. Confirming inside SessionRouter would be
|
|
480
|
+
// premature because handleLocally is only that fall-through marker. This callback
|
|
481
|
+
// advances placing → active only after the local tail has actually succeeded.
|
|
482
|
+
let _confirmLocalSessionPoolClaim = null;
|
|
477
483
|
// ── Durable Inbound Message Queue (docs/specs/durable-inbound-message-queue.md) ──
|
|
478
484
|
// The custody engine (null = feature dark / gate failed / invariants violated —
|
|
479
485
|
// every consumer treats null as "refused → today's fall-through").
|
|
@@ -2396,6 +2402,20 @@ getHubClassifierDeps) {
|
|
|
2396
2402
|
console.warn(`[session-pool] route error for topic ${topicId} — falling back to local dispatch: ${err instanceof Error ? err.message : String(err)}`);
|
|
2397
2403
|
}
|
|
2398
2404
|
}
|
|
2405
|
+
// Safe after any successful local delivery. The registry-side callback is
|
|
2406
|
+
// idempotent and confirms only a placing row already owned by this machine,
|
|
2407
|
+
// so ordinary active-session traffic is a strict no-op.
|
|
2408
|
+
const confirmLocalSessionPoolClaim = () => {
|
|
2409
|
+
try {
|
|
2410
|
+
_confirmLocalSessionPoolClaim?.(String(topicId));
|
|
2411
|
+
}
|
|
2412
|
+
catch (err) {
|
|
2413
|
+
// Delivery has already succeeded. A registry read/CAS/emit error must
|
|
2414
|
+
// avoid reclassifying delivery as a spawn failure (or throwing out of
|
|
2415
|
+
// the live-injection handler). The row is re-read by normal routing.
|
|
2416
|
+
console.warn(`[session-pool] local claim confirmation errored for topic ${topicId}; ownership outcome will be re-read: ${err instanceof Error ? err.message : String(err)}`);
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2399
2419
|
// ── SpawnAdmission — the binding-verdict seam (ownership-gated-spawn §3.1,
|
|
2400
2420
|
// Layer A / the Ownership-Gated Side Effects standard). Consulted before
|
|
2401
2421
|
// EVERY local session-creating action below. Increment-1 posture: dryRun
|
|
@@ -2465,7 +2485,9 @@ getHubClassifierDeps) {
|
|
|
2465
2485
|
// Use toInjection() — types guarantee sender identity is included in the tag
|
|
2466
2486
|
const injection = toInjection(pipeline, targetSession);
|
|
2467
2487
|
console.log(`[telegram→session] Injecting into ${targetSession}: "${text.slice(0, 80)}"`);
|
|
2468
|
-
sessionManager.injectTelegramMessage(targetSession, topicId, text, pipeline.topicName, pipeline.sender.firstName, pipeline.sender.telegramUserId, parseInt(pipeline.id.replace('tg-', ''), 10) || undefined);
|
|
2488
|
+
const injected = sessionManager.injectTelegramMessage(targetSession, topicId, text, pipeline.topicName, pipeline.sender.firstName, pipeline.sender.telegramUserId, parseInt(pipeline.id.replace('tg-', ''), 10) || undefined);
|
|
2489
|
+
if (injected)
|
|
2490
|
+
confirmLocalSessionPoolClaim();
|
|
2469
2491
|
// Delivery confirmation — only when WE own polling. When lifeline owns
|
|
2470
2492
|
// polling (--no-telegram / standby), it already sends its own confirmation.
|
|
2471
2493
|
if (telegram.isPolling) {
|
|
@@ -2514,6 +2536,7 @@ getHubClassifierDeps) {
|
|
|
2514
2536
|
_topicResumeMap.remove(topicId);
|
|
2515
2537
|
}
|
|
2516
2538
|
respawnSessionForTopic(sessionManager, telegram, targetSession, topicId, text, topicMemory, resolvedUser ?? undefined)
|
|
2539
|
+
.then(() => confirmLocalSessionPoolClaim())
|
|
2517
2540
|
.catch(err => {
|
|
2518
2541
|
console.error(`[telegram→session] Context exhaustion respawn failed:`, err);
|
|
2519
2542
|
telegram.sendToTopic(topicId, `❌ Fresh session restart failed. Try sending your message again.`).catch(() => { });
|
|
@@ -2538,6 +2561,7 @@ getHubClassifierDeps) {
|
|
|
2538
2561
|
const _spawnTokB = spawningTopics.add(topicId);
|
|
2539
2562
|
telegram.sendToTopic(topicId, `🔄 Session restarting — message queued.`).catch(() => { });
|
|
2540
2563
|
respawnSessionForTopic(sessionManager, telegram, targetSession, topicId, text, topicMemory, resolvedUser ?? undefined)
|
|
2564
|
+
.then(() => confirmLocalSessionPoolClaim())
|
|
2541
2565
|
.catch(err => {
|
|
2542
2566
|
console.error(`[telegram→session] Respawn failed:`, err);
|
|
2543
2567
|
// G1 "Agent Is Always Reachable" corollary (2): no silent resource
|
|
@@ -2602,6 +2626,7 @@ getHubClassifierDeps) {
|
|
|
2602
2626
|
// Use the shared spawn helper that includes topic history + user context
|
|
2603
2627
|
spawnSessionForTopic(sessionManager, telegram, spawnName, topicId, text, topicMemory, resolvedUser ?? undefined).then((newSessionName) => {
|
|
2604
2628
|
telegram.registerTopicSession(topicId, newSessionName, spawnName);
|
|
2629
|
+
confirmLocalSessionPoolClaim();
|
|
2605
2630
|
telegram.sendToTopic(topicId, `Session starting up — reading your message now. One moment.`).catch(() => { });
|
|
2606
2631
|
console.log(`[telegram→session] Auto-spawned "${newSessionName}" for topic ${topicId}`);
|
|
2607
2632
|
}).catch((err) => {
|
|
@@ -20782,6 +20807,23 @@ export async function startServer(options) {
|
|
|
20782
20807
|
});
|
|
20783
20808
|
},
|
|
20784
20809
|
});
|
|
20810
|
+
_confirmLocalSessionPoolClaim = (sk) => {
|
|
20811
|
+
return confirmLocalPlacementAfterDelivery({
|
|
20812
|
+
selfMachineId: meshSelfId,
|
|
20813
|
+
readOwnership: (sessionKey) => ownReg.read(sessionKey),
|
|
20814
|
+
claimOwnership: (sessionKey, machineId) => {
|
|
20815
|
+
const prevOwner = ownReg.read(sessionKey)?.ownerMachineId;
|
|
20816
|
+
const r = ownReg.cas({ type: 'claim', machineId }, { sessionKey, sender: meshSelfId, nonce: `${meshSelfId}:lcl:${++routerNonce}` });
|
|
20817
|
+
return {
|
|
20818
|
+
confirmed: r.ok,
|
|
20819
|
+
afterConfirm: () => emitPlacement(sessionKey, r, 'placed', prevOwner),
|
|
20820
|
+
};
|
|
20821
|
+
},
|
|
20822
|
+
onError: (err) => {
|
|
20823
|
+
console.warn(`[session-pool] local ownership confirmation observer failed for ${sk}; authoritative state will be re-read: ${err instanceof Error ? err.message : String(err)}`);
|
|
20824
|
+
},
|
|
20825
|
+
}, sk);
|
|
20826
|
+
};
|
|
20785
20827
|
_sessionRouter = new routerMod.SessionRouter({
|
|
20786
20828
|
selfMachineId: meshSelfId,
|
|
20787
20829
|
placement: new placeMod.PlacementExecutor(undefined, {
|
|
@@ -20848,6 +20890,12 @@ export async function startServer(options) {
|
|
|
20848
20890
|
const r = ownReg.cas({ type: 'claim', machineId }, { sessionKey: sk, sender: meshSelfId, nonce: `${meshSelfId}:cl:${++routerNonce}` });
|
|
20849
20891
|
emitPlacement(sk, r, 'placed', prevOwner); // placing→active confirmation: a real epoch bump in the registry
|
|
20850
20892
|
},
|
|
20893
|
+
// The local delivery tail runs outside SessionRouter. Confirm its
|
|
20894
|
+
// self-placement only after that tail reports a successful inject or
|
|
20895
|
+
// spawn; a thrown/failed spawn therefore leaves the row in placing.
|
|
20896
|
+
// Guarding the current row makes repeated live injections idempotent.
|
|
20897
|
+
// The adjacent _confirmLocalSessionPoolClaim callback shares this
|
|
20898
|
+
// authoritative registry and nonce stream for the local tail.
|
|
20851
20899
|
deliverMessage: async (target, env) => {
|
|
20852
20900
|
const url = peerUrl(target);
|
|
20853
20901
|
if (!url)
|