instar 1.3.1661 → 1.3.1663
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 +195 -30
- package/dist/commands/server.js.map +1 -1
- package/dist/core/ClaudeKeyHealth.d.ts +21 -0
- package/dist/core/ClaudeKeyHealth.d.ts.map +1 -1
- package/dist/core/ClaudeKeyHealth.js +81 -5
- package/dist/core/ClaudeKeyHealth.js.map +1 -1
- package/dist/core/MeshRpc.d.ts +14 -0
- package/dist/core/MeshRpc.d.ts.map +1 -1
- package/dist/core/MeshRpc.js +1 -0
- package/dist/core/MeshRpc.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +18 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +8 -6
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SlackReplyRelayInstaller.d.ts.map +1 -1
- package/dist/core/SlackReplyRelayInstaller.js +2 -0
- package/dist/core/SlackReplyRelayInstaller.js.map +1 -1
- package/dist/core/StateManager.d.ts +8 -0
- package/dist/core/StateManager.d.ts.map +1 -1
- package/dist/core/StateManager.js +11 -0
- package/dist/core/StateManager.js.map +1 -1
- package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
- package/dist/core/WriteDomainRegistry.js +9 -0
- package/dist/core/WriteDomainRegistry.js.map +1 -1
- package/dist/core/claudeKeyRecovery.d.ts +102 -0
- package/dist/core/claudeKeyRecovery.d.ts.map +1 -0
- package/dist/core/claudeKeyRecovery.js +178 -0
- package/dist/core/claudeKeyRecovery.js.map +1 -0
- package/dist/core/memorySessionPolicy.d.ts +12 -0
- package/dist/core/memorySessionPolicy.d.ts.map +1 -1
- package/dist/core/memorySessionPolicy.js +20 -0
- package/dist/core/memorySessionPolicy.js.map +1 -1
- package/dist/core/pickSessionByTmux.d.ts +11 -0
- package/dist/core/pickSessionByTmux.d.ts.map +1 -0
- package/dist/core/pickSessionByTmux.js +11 -0
- package/dist/core/pickSessionByTmux.js.map +1 -0
- package/dist/core/types.d.ts +14 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/data/standards-guard-index.json +2 -2
- package/dist/data/standards-guard-index.meta.json +3 -3
- package/dist/data/standards-registry.md +12 -2
- package/dist/data/standards-registry.meta.json +3 -3
- package/dist/feedback-factory/execute/changeSet.d.ts.map +1 -1
- package/dist/feedback-factory/execute/changeSet.js +18 -1
- package/dist/feedback-factory/execute/changeSet.js.map +1 -1
- package/dist/feedback-factory/execute/executePolicy.d.ts +1 -1
- package/dist/feedback-factory/execute/executePolicy.d.ts.map +1 -1
- package/dist/feedback-factory/execute/executePolicy.js +2 -2
- package/dist/feedback-factory/execute/executePolicy.js.map +1 -1
- package/dist/messaging/SpawnRequestManager.d.ts +31 -0
- package/dist/messaging/SpawnRequestManager.d.ts.map +1 -1
- package/dist/messaging/SpawnRequestManager.js +149 -11
- package/dist/messaging/SpawnRequestManager.js.map +1 -1
- package/dist/messaging/TelegramAdapter.d.ts +11 -11
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
- package/dist/messaging/TelegramAdapter.js +59 -14
- package/dist/messaging/TelegramAdapter.js.map +1 -1
- package/dist/messaging/slack/SlackAdapter.d.ts +23 -0
- package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
- package/dist/messaging/slack/SlackAdapter.js +69 -0
- package/dist/messaging/slack/SlackAdapter.js.map +1 -1
- package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
- package/dist/native/instar-desktop-host +0 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +9 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +1 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +4 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +99 -4
- package/dist/server/routes.js.map +1 -1
- package/dist/testing/selfActionRegistry.d.ts.map +1 -1
- package/dist/testing/selfActionRegistry.js +48 -0
- package/dist/testing/selfActionRegistry.js.map +1 -1
- package/dist/threadline/A2ADeliveryTracker.d.ts +49 -0
- package/dist/threadline/A2ADeliveryTracker.d.ts.map +1 -1
- package/dist/threadline/A2ADeliveryTracker.js +81 -2
- package/dist/threadline/A2ADeliveryTracker.js.map +1 -1
- package/dist/threadline/InboundMessageGate.d.ts.map +1 -1
- package/dist/threadline/InboundMessageGate.js +12 -0
- package/dist/threadline/InboundMessageGate.js.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.js +13 -2
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.js +9 -0
- package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts +25 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.js +38 -1
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
- package/dist/threadline/ThreadlineMcpHttpService.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMcpHttpService.js +6 -2
- package/dist/threadline/ThreadlineMcpHttpService.js.map +1 -1
- package/dist/threadline/ThreadlineRouter.d.ts +17 -1
- package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
- package/dist/threadline/ThreadlineRouter.js +22 -2
- package/dist/threadline/ThreadlineRouter.js.map +1 -1
- package/dist/threadline/TopicLinkageHandler.d.ts +9 -0
- package/dist/threadline/TopicLinkageHandler.d.ts.map +1 -1
- package/dist/threadline/TopicLinkageHandler.js +13 -2
- package/dist/threadline/TopicLinkageHandler.js.map +1 -1
- package/dist/threadline/autoAck.d.ts +37 -21
- package/dist/threadline/autoAck.d.ts.map +1 -1
- package/dist/threadline/autoAck.js +34 -19
- package/dist/threadline/autoAck.js.map +1 -1
- package/dist/threadline/client/MessageEncryptor.d.ts +5 -0
- package/dist/threadline/client/MessageEncryptor.d.ts.map +1 -1
- package/dist/threadline/client/MessageEncryptor.js.map +1 -1
- package/dist/threadline/client/ThreadlineClient.d.ts +26 -0
- package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -1
- package/dist/threadline/client/ThreadlineClient.js +70 -4
- package/dist/threadline/client/ThreadlineClient.js.map +1 -1
- package/dist/threadline/inboundIdLedgerWiring.d.ts.map +1 -1
- package/dist/threadline/inboundIdLedgerWiring.js +4 -1
- package/dist/threadline/inboundIdLedgerWiring.js.map +1 -1
- package/dist/threadline/mcp-http-client.d.ts +11 -0
- package/dist/threadline/mcp-http-client.d.ts.map +1 -1
- package/dist/threadline/mcp-http-client.js +34 -0
- package/dist/threadline/mcp-http-client.js.map +1 -1
- package/dist/threadline/mcp-stdio-entry.js +4 -1
- package/dist/threadline/mcp-stdio-entry.js.map +1 -1
- package/dist/threadline/requiredAck.d.ts +64 -0
- package/dist/threadline/requiredAck.d.ts.map +1 -0
- package/dist/threadline/requiredAck.js +117 -0
- package/dist/threadline/requiredAck.js.map +1 -0
- package/dist/threadline/requiredAckService.d.ts +223 -0
- package/dist/threadline/requiredAckService.d.ts.map +1 -0
- package/dist/threadline/requiredAckService.js +565 -0
- package/dist/threadline/requiredAckService.js.map +1 -0
- package/dist/threadline/requiredAckStore.d.ts +149 -0
- package/dist/threadline/requiredAckStore.d.ts.map +1 -0
- package/dist/threadline/requiredAckStore.js +283 -0
- package/dist/threadline/requiredAckStore.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +66 -66
- package/src/data/feature-ladders.json +3 -1
- package/src/data/standards-guard-index.json +2 -2
- package/src/data/standards-guard-index.meta.json +3 -3
- package/src/data/standards-registry.md +12 -2
- package/src/data/standards-registry.meta.json +3 -3
- package/src/scaffold/templates.ts +9 -0
- package/src/templates/scripts/slack-reply.sh +7 -0
- package/upgrades/1.3.1663.md +77 -0
- package/upgrades/cloud-key-recovery-reply.eli16.md +19 -0
- package/upgrades/side-effects/a2a-required-acknowledgment.md +130 -0
- package/upgrades/side-effects/agent-health-quiet-default.md +74 -0
- package/upgrades/side-effects/cloud-key-recovery-reply.md +141 -0
- package/upgrades/side-effects/feedback-changeset-byte-cap-calibration.md +60 -0
- package/upgrades/side-effects/memory-privacy-ladder-off-by-default.md +100 -0
- package/upgrades/side-effects/memory-privacy-linux-replies.md +109 -0
- package/upgrades/side-effects/person-decides-counterpart.md +62 -0
- package/upgrades/side-effects/session-by-tmux.md +48 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAmIA,OAAO,EAAE,cAAc,EAAwD,MAAM,2BAA2B,CAAC;AAgBjH,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA6BjG,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":"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"}
|
package/dist/commands/server.js
CHANGED
|
@@ -280,6 +280,7 @@ import { ThreadLog } from '../threadline/ThreadLog.js';
|
|
|
280
280
|
import { ThreadMessageRecorder } from '../threadline/recordThreadMessage.js';
|
|
281
281
|
import { recordInboundAck } from '../threadline/recordInboundAck.js';
|
|
282
282
|
import { isAutoAckInbound, autoAckRecognition, looksLikeAutoAckText, createAckRateLimiter, runRelayAckStage, createRelayAckSettler, describeUndeliveredRouterResult } from '../threadline/autoAck.js';
|
|
283
|
+
import { parseKindedAck } from '../threadline/requiredAck.js';
|
|
283
284
|
/** ACT-091: the session manager's observed paste → the topic handler's inject outcome (starts the busy watch lazily). */
|
|
284
285
|
function liveInjectOutcomeFromObservation(r) {
|
|
285
286
|
if (r.state === 'queued-busy')
|
|
@@ -1132,6 +1133,12 @@ let _handbackSendOffer = null;
|
|
|
1132
1133
|
// `_a2aAskTopicOwner` are assigned where the MeshRpcClient exists; until then a
|
|
1133
1134
|
// standby answers today's 503 and a topic-bound reply takes today's path.
|
|
1134
1135
|
let _a2aRelayForwardCtx = null;
|
|
1136
|
+
// a2a-required-acknowledgment: one service per server. Late-bound, because the spawn
|
|
1137
|
+
// manager's callbacks are wired before the tracker it writes to exists.
|
|
1138
|
+
let _requiredAckService = null;
|
|
1139
|
+
let _requiredAckRelayRoute = null;
|
|
1140
|
+
let _requiredAckRelayClient = () => null;
|
|
1141
|
+
let _requiredAckTrustManager = () => null;
|
|
1135
1142
|
let _a2aAskTopicOwner = null;
|
|
1136
1143
|
let _deliverA2aToMachine = null;
|
|
1137
1144
|
// Subscription & Auth Standard P1.3 — quota-aware account-swap scheduler. Null
|
|
@@ -17908,7 +17915,7 @@ export async function startServer(options) {
|
|
|
17908
17915
|
const threadResumeMap = new ThreadResumeMap(config.stateDir, config.stateDir, undefined, undefined, {
|
|
17909
17916
|
// A thread bound to a claude-code session checks Claude transcripts only;
|
|
17910
17917
|
// an unknown session name tries every layout (the bounded lookups).
|
|
17911
|
-
frameworkResolver: (sessionName) => state.
|
|
17918
|
+
frameworkResolver: (sessionName) => state.findSessionByTmux(sessionName)?.framework,
|
|
17912
17919
|
});
|
|
17913
17920
|
// Threadline Phase 1 keystone: the Conversation single-source-of-truth +
|
|
17914
17921
|
// the warrants-a-reply gate. The gate runs once at the relay inbound funnel
|
|
@@ -18411,6 +18418,17 @@ export async function startServer(options) {
|
|
|
18411
18418
|
const state = memoryMonitor?.getState();
|
|
18412
18419
|
return !state || state.state === 'normal';
|
|
18413
18420
|
},
|
|
18421
|
+
// a2a-required-acknowledgment D7: a session limit with a slot now free. A live
|
|
18422
|
+
// read of the number admission reads; admission still decides.
|
|
18423
|
+
isDrainRefusalLiveCleared: (marker) => {
|
|
18424
|
+
if (!/session limit/i.test(marker.refusalSignature))
|
|
18425
|
+
return false;
|
|
18426
|
+
const limit = config.sessions?.maxSessions ?? config.maxSessions ?? 5;
|
|
18427
|
+
return sessionManager.listRunningSessions().length < limit;
|
|
18428
|
+
},
|
|
18429
|
+
// a2a-required-acknowledgment D3/D5.
|
|
18430
|
+
onQueuedMessageDropped: (receipt, cause) => _requiredAckService?.onQueueDropped(receipt, cause),
|
|
18431
|
+
onQueuedMessageDelivered: (receipt, session) => _requiredAckService?.onDelivered(receipt, session),
|
|
18414
18432
|
onDrainRearm: (event) => {
|
|
18415
18433
|
console.log(`[spawn-manager] drain give-up latch re-armed for ${event.agent} ` +
|
|
18416
18434
|
`(target=${event.targetKey}, signature="${event.refusalSignature}", quiet=${event.rearmCooldownMs}ms)`);
|
|
@@ -18743,6 +18761,50 @@ export async function startServer(options) {
|
|
|
18743
18761
|
degradations: DegradationReporter.getInstance(),
|
|
18744
18762
|
});
|
|
18745
18763
|
}
|
|
18764
|
+
// A sender is never left guessing (docs/specs/a2a-required-acknowledgment.md).
|
|
18765
|
+
// Always constructed: inbound kinded acks are consumed safely even when
|
|
18766
|
+
// threadline.requiredAck.enabled is false.
|
|
18767
|
+
{
|
|
18768
|
+
const ra = await import('../threadline/requiredAckService.js');
|
|
18769
|
+
const raConfig = config;
|
|
18770
|
+
const relayRoute = () => {
|
|
18771
|
+
const client = _requiredAckRelayClient();
|
|
18772
|
+
if (client && client.connectionState === 'connected') {
|
|
18773
|
+
return { kind: 'relay', send: (peerFp, ack, text, opts) => { client.sendKindedAck(peerFp, ack, text, opts); } };
|
|
18774
|
+
}
|
|
18775
|
+
return { kind: 'none' };
|
|
18776
|
+
};
|
|
18777
|
+
_requiredAckRelayRoute = relayRoute;
|
|
18778
|
+
_requiredAckService = new ra.RequiredAckService({
|
|
18779
|
+
tracker: a2aDeliveryTracker,
|
|
18780
|
+
enabled: () => ra.resolveRequiredAckEnabled(liveConfig.get('threadline.requiredAck.enabled', undefined), raConfig),
|
|
18781
|
+
thresholds: () => ra.resolveRequiredAckThresholds(raConfig),
|
|
18782
|
+
route: () => {
|
|
18783
|
+
const direct = relayRoute();
|
|
18784
|
+
if (direct.kind === 'relay')
|
|
18785
|
+
return direct;
|
|
18786
|
+
const forwardAck = _a2aRelayForwardCtx?.relaySuppressedByStandby === true ? _a2aRelayForwardCtx.forwardAck : null;
|
|
18787
|
+
return forwardAck ? { kind: 'forward', send: forwardAck } : { kind: 'none' };
|
|
18788
|
+
},
|
|
18789
|
+
isStandby: () => _a2aRelayForwardCtx?.relaySuppressedByStandby === true,
|
|
18790
|
+
hasTrustProfile: (fp) => {
|
|
18791
|
+
const p = _requiredAckTrustManager()?.getProfileByFingerprint(fp);
|
|
18792
|
+
return !!p && !(p.relayFirstContact && p.source === 'setup-default');
|
|
18793
|
+
},
|
|
18794
|
+
isPinned: (fp) => !!_requiredAckTrustManager()?.getProfileByFingerprint(fp)?.peerIdentityPub,
|
|
18795
|
+
isSessionAlive: (name) => sessionManager.isSessionAlive(name),
|
|
18796
|
+
injectReminder: (name, text) => sessionManager.injectMessage(name, text, { firstParty: { source: 'a2a-ack-reminder' } }),
|
|
18797
|
+
laneOf: (name) => {
|
|
18798
|
+
const lane = sessionManager.listRunningSessions().find((sess) => sess.tmuxSession === name)?.launchLane;
|
|
18799
|
+
return lane === 'headless' ? 'headless' : lane === 'rerouted-interactive' ? 'interactive' : null;
|
|
18800
|
+
},
|
|
18801
|
+
threadPeer: (threadId) => threadResumeMap.get(threadId)?.remoteAgent ?? null,
|
|
18802
|
+
});
|
|
18803
|
+
const interrupted = _requiredAckService.recoverAfterRestart();
|
|
18804
|
+
if (interrupted > 0)
|
|
18805
|
+
console.log(`[required-ack] ${interrupted} message(s) a restart interrupted; their senders will be told once the relay connects`);
|
|
18806
|
+
_requiredAckService.start();
|
|
18807
|
+
}
|
|
18746
18808
|
}
|
|
18747
18809
|
catch (err) {
|
|
18748
18810
|
// @silent-fallback-ok: cascade-isolation — a tracker open failure must never block
|
|
@@ -19296,6 +19358,9 @@ export async function startServer(options) {
|
|
|
19296
19358
|
}
|
|
19297
19359
|
}
|
|
19298
19360
|
catch { /* @silent-fallback-ok — an advisory startup note must never endanger boot */ }
|
|
19361
|
+
// a2a-required-acknowledgment: the service exists before the relay client does.
|
|
19362
|
+
_requiredAckRelayClient = () => threadlineRelayClient;
|
|
19363
|
+
_requiredAckTrustManager = () => (threadline.trustManager ?? null);
|
|
19299
19364
|
if (threadlineRelayClient) {
|
|
19300
19365
|
// Wire relay message delivery through ThreadlineRouter (Phase 1).
|
|
19301
19366
|
// Replaces the ad-hoc handler with proper thread persistence, auto-ack,
|
|
@@ -19402,23 +19467,33 @@ export async function startServer(options) {
|
|
|
19402
19467
|
// before it returns; an exit that settles nothing (a throw) sends no
|
|
19403
19468
|
// ack, which is the honest result when nothing received the message.
|
|
19404
19469
|
const isTopicBoundReply = !!msg.threadId && threadResumeMap.get(msg.threadId)?.originTopicId !== undefined;
|
|
19470
|
+
// a2a-required-acknowledgment D1: plaintext arrives relay-authenticated;
|
|
19471
|
+
// anything else came through the decrypt path, encrypted and signed.
|
|
19472
|
+
const arrivedEncrypted = decision.reason !== 'relay-authenticated' && decision.reason !== 'probe';
|
|
19405
19473
|
const relayAckDeps = {
|
|
19406
19474
|
autoAckEnabled: config.threadline?.autoAck !== false,
|
|
19407
19475
|
autoAckMessage: config.threadline?.autoAckMessage,
|
|
19408
19476
|
isAckRateLimited,
|
|
19409
19477
|
sendAck: (to, text, threadId) => { threadlineRelayClient.sendAck(to, text, threadId); },
|
|
19410
19478
|
recordDelivery: recordRelayDelivery,
|
|
19479
|
+
consumeKindedAck: (ack) => {
|
|
19480
|
+
_requiredAckService?.consumeInboundAck({ from: senderFingerprint, ack, arrivedEncrypted });
|
|
19481
|
+
},
|
|
19411
19482
|
};
|
|
19412
19483
|
const relayAckInput = {
|
|
19413
19484
|
isAutoAck, trustLevel, msgType, senderFingerprint, threadId: msg.threadId, ticket: ledgerTicket,
|
|
19485
|
+
kindedAck: parseKindedAck(msg.content),
|
|
19414
19486
|
deferSend: true,
|
|
19415
19487
|
};
|
|
19416
19488
|
const relayAck = createRelayAckSettler(relayAckDeps, relayAckInput);
|
|
19417
19489
|
const ackStage = runRelayAckStage(relayAckDeps, relayAckInput);
|
|
19418
19490
|
if (ackStage === 'ack-consumed') {
|
|
19419
|
-
console.log(`[relay] delivery ack from ${senderName} (thread: ${msg.threadId ?? 'none'}, by ${autoAckRecognition({ type: msgType, text: textContent })}) recorded — not acked, not routed`);
|
|
19491
|
+
console.log(`[relay] ${relayAckInput.kindedAck ? 'kinded' : 'delivery'} ack from ${senderName} (thread: ${msg.threadId ?? 'none'}, by ${autoAckRecognition({ type: msgType, text: textContent })}) ${relayAckInput.kindedAck ? 'consumed' : 'recorded'} — not acked, not routed`);
|
|
19420
19492
|
return;
|
|
19421
19493
|
}
|
|
19494
|
+
// a2a-required-acknowledgment D1: after the trust check, per ordinary message.
|
|
19495
|
+
if (msgType !== 'status' && decision.reason !== 'probe')
|
|
19496
|
+
_requiredAckService?.notePeerMessage(senderFingerprint, msg.content);
|
|
19422
19497
|
// Canonical inbox write — single source of truth across all routing branches.
|
|
19423
19498
|
// Runs once at relay-ingest, BEFORE pipe / warm-listener / cold-spawn branching,
|
|
19424
19499
|
// so .instar/threadline/inbox.jsonl.active reflects every inbound message regardless
|
|
@@ -19646,12 +19721,17 @@ export async function startServer(options) {
|
|
|
19646
19721
|
// (trustMeetsFloor), NEVER string `>=`. When false (or feature off), the
|
|
19647
19722
|
// router takes the proven cold-spawn path byte-for-byte.
|
|
19648
19723
|
const preferWarmSession = warmEnabled && !isTopicBoundReply && trustMeetsFloor(trustLevel, warmTrustFloor);
|
|
19724
|
+
// a2a-required-acknowledgment D4: pipe and listener paths never get here.
|
|
19725
|
+
const requiredAckHandle = decision.reason === 'probe' ? null : (_requiredAckService?.prepare({
|
|
19726
|
+
peerFp: senderFingerprint, messageId: msg.messageId, threadId: msg.threadId ?? null, triggerEncrypted: arrivedEncrypted,
|
|
19727
|
+
}) ?? null);
|
|
19649
19728
|
const relayContext = {
|
|
19650
19729
|
trust: { kind: 'plaintext-tofu', senderFingerprint },
|
|
19651
19730
|
senderFingerprint,
|
|
19652
19731
|
senderName,
|
|
19653
19732
|
trustLevel,
|
|
19654
19733
|
preferWarmSession,
|
|
19734
|
+
...(requiredAckHandle ? { requiredAck: { instruction: requiredAckHandle.instruction, receipt: requiredAckHandle.receipt } } : {}),
|
|
19655
19735
|
};
|
|
19656
19736
|
let result = await threadlineRouter.handleInboundMessage(envelope, relayContext, { resentNotice: ledgerNotice });
|
|
19657
19737
|
// Fallback only when a threadless message could not be associated
|
|
@@ -19664,6 +19744,8 @@ export async function startServer(options) {
|
|
|
19664
19744
|
}
|
|
19665
19745
|
// Inbound-id ledger: the outcome of the LAST path tried, through the allowlist.
|
|
19666
19746
|
ledgerTicket?.recordRouterResult(result);
|
|
19747
|
+
// a2a-required-acknowledgment D2/D5: tell the sender what really happened.
|
|
19748
|
+
_requiredAckService?.settleRouterResult(requiredAckHandle, result);
|
|
19667
19749
|
if (result.error)
|
|
19668
19750
|
console.warn(`[relay] Router error: ${result.error}`);
|
|
19669
19751
|
if (result.spawned)
|
|
@@ -20936,7 +21018,11 @@ export async function startServer(options) {
|
|
|
20936
21018
|
// A dead sign-in key on a key-only agent: confirmed, told, recovered (spec cloud-key-internal-calls).
|
|
20937
21019
|
// Wired here, outside the subscription pool block, because these agents may have no pool.
|
|
20938
21020
|
{
|
|
20939
|
-
const { ClaudeKeyHealth, claudeKeyFingerprint, setActiveClaudeKeyHealth } = await import('../core/ClaudeKeyHealth.js');
|
|
21021
|
+
const { ClaudeKeyHealth, claudeKeyFingerprint, setActiveClaudeKeyHealth, KEY_NOTICE_TEXTS } = await import('../core/ClaudeKeyHealth.js');
|
|
21022
|
+
const { heldMessages, answeredSince, buildKeyRecoveryPrompt, deliverOperatorNotice, operatorSlackIds, slackConversationLines } = await import('../core/claudeKeyRecovery.js');
|
|
21023
|
+
const { deriveRole: deriveOrgRole } = await import('../permissions/SlackPrincipalResolver.js');
|
|
21024
|
+
const { SESSION_BACK_NOTICE: keyBackNotice } = await import('../messaging/userNotices.js');
|
|
21025
|
+
const keyNoticeTexts = [...KEY_NOTICE_TEXTS, keyBackNotice];
|
|
20940
21026
|
const { buildClaudeKeyProbe } = await import('../core/claudeKeyProbe.js');
|
|
20941
21027
|
const { configuredClaudeOauthKey, setClaudeCallOutcomeListener } = await import('../core/claudeChildAuth.js');
|
|
20942
21028
|
const keyHealthOn = () => liveConfig.get('sessions.claudeKeyHealth.enabled', true) !== false;
|
|
@@ -20946,6 +21032,51 @@ export async function startServer(options) {
|
|
|
20946
21032
|
};
|
|
20947
21033
|
// The disk read covers a topic bound after this server booted, as SessionRefresh does.
|
|
20948
21034
|
const topicForSession = (name) => telegram?.getTopicForSession(name) ?? telegram?.resolveTopicForSessionFromDisk?.(name) ?? null;
|
|
21035
|
+
// One conversation's recent lines, platform-neutral. Slack: the ring buffer (it knows which
|
|
21036
|
+
// messages were not addressed to the agent), or Slack itself when the buffer is empty or
|
|
21037
|
+
// `authoritative` is asked for.
|
|
21038
|
+
const keyConversationLines = async (sessionName, authoritative = false) => {
|
|
21039
|
+
const topicId = topicForSession(sessionName);
|
|
21040
|
+
if (topicId !== null && telegram) {
|
|
21041
|
+
// Server automation (standby notes, notices) is neither a person nor the agent answering.
|
|
21042
|
+
const lines = telegram.getTopicHistory(topicId, 50)
|
|
21043
|
+
.filter((e) => e.fromUser || e.provenance !== 'automation')
|
|
21044
|
+
.map((e) => ({
|
|
21045
|
+
at: Date.parse(e.timestamp), fromAgent: !e.fromUser, who: e.senderName || e.senderUsername || 'someone', text: e.text ?? '',
|
|
21046
|
+
}));
|
|
21047
|
+
return { lines, channel: { platform: 'telegram', topicId } };
|
|
21048
|
+
}
|
|
21049
|
+
const routingKey = _slackAdapter?.getChannelForSession(sessionName) ?? null;
|
|
21050
|
+
if (routingKey === null || !_slackAdapter)
|
|
21051
|
+
return null;
|
|
21052
|
+
const slack = _slackAdapter;
|
|
21053
|
+
const { channelId, threadTs } = slack.parseRoutingKey(routingKey);
|
|
21054
|
+
// A thread session is its thread. A channel session serves the whole channel, threads
|
|
21055
|
+
// included, and replies into the thread its latest message came from.
|
|
21056
|
+
const inConversation = (m) => threadTs ? (m.thread_ts === threadTs || m.ts === threadTs) : true;
|
|
21057
|
+
let messages = authoritative ? [] : slack.getChannelMessages(channelId, 200).filter(inConversation);
|
|
21058
|
+
if (messages.length === 0)
|
|
21059
|
+
messages = await slack.recentConversationMessages(routingKey, 50);
|
|
21060
|
+
const lines = slackConversationLines(messages, {
|
|
21061
|
+
botUserId: slack.getBotUserId?.() ?? null,
|
|
21062
|
+
isPerson: (userId) => slack.isAuthorized(userId),
|
|
21063
|
+
isServerPost: (ts) => slack.isServerAutomationPost(channelId, ts),
|
|
21064
|
+
});
|
|
21065
|
+
return { lines, channel: { platform: 'slack', channelId, ...(threadTs ? { threadTs } : {}) } };
|
|
21066
|
+
};
|
|
21067
|
+
// The operator on Slack: authorized people whose profile is an owner or admin (read fresh,
|
|
21068
|
+
// so a profile added after boot counts).
|
|
21069
|
+
const keyOperators = (slack) => {
|
|
21070
|
+
let profiles = [];
|
|
21071
|
+
try {
|
|
21072
|
+
profiles = new UserManager(config.stateDir, config.users).listUsers()
|
|
21073
|
+
.map((u) => ({ slackUserId: u.slackUserId, role: deriveOrgRole(u.permissions, u.orgRole) }));
|
|
21074
|
+
}
|
|
21075
|
+
catch (err) { /* @silent-fallback-ok: no profiles means a small authorized list stands in (operatorSlackIds) */
|
|
21076
|
+
console.warn(`[ClaudeKeyHealth] could not read user profiles: ${err instanceof Error ? err.message : String(err)}`);
|
|
21077
|
+
}
|
|
21078
|
+
return operatorSlackIds(slack.getAuthorizedUserIds(), profiles);
|
|
21079
|
+
};
|
|
20949
21080
|
const claudeKeyHealth = new ClaudeKeyHealth({
|
|
20950
21081
|
stateFile: path.join(config.stateDir, 'state', 'claude-key-health.json'),
|
|
20951
21082
|
currentKey: () => (keyHealthOn() ? configuredClaudeOauthKey() : undefined),
|
|
@@ -20965,30 +21096,27 @@ export async function startServer(options) {
|
|
|
20965
21096
|
baseUrl: () => config.sessions.anthropicBaseUrl,
|
|
20966
21097
|
}),
|
|
20967
21098
|
// Fixed server text straight to the adapters: the model is what is down, and `notify` returns
|
|
20968
|
-
// nothing, so it can't say whether anyone was told.
|
|
20969
|
-
|
|
20970
|
-
|
|
21099
|
+
// nothing, so it can't say whether anyone was told. Delivered means a person can read it:
|
|
21100
|
+
// a Slack alert channel with none of the agent's people in it reaches nobody (2026-11-04
|
|
21101
|
+
// drill), so then each of them gets a direct message.
|
|
21102
|
+
notifyOperator: (text) => {
|
|
20971
21103
|
const hubTopicId = state.get('agent-attention-topic') ?? 0;
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
|
|
20976
|
-
|
|
20977
|
-
|
|
20978
|
-
|
|
20979
|
-
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
|
|
20983
|
-
|
|
20984
|
-
await
|
|
20985
|
-
|
|
20986
|
-
}
|
|
20987
|
-
|
|
20988
|
-
console.warn(`[ClaudeKeyHealth] Slack notice failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
20989
|
-
}
|
|
20990
|
-
}
|
|
20991
|
-
return delivered;
|
|
21104
|
+
const slack = _slackAdapter;
|
|
21105
|
+
return deliverOperatorNotice({
|
|
21106
|
+
telegram: telegram && hubTopicId ? async (t) => { await telegram.sendToTopic(hubTopicId, t); } : undefined,
|
|
21107
|
+
slack: slack ? {
|
|
21108
|
+
attentionChannel: state.get('slack-attention-channel') ?? null,
|
|
21109
|
+
readersOf: async (channelId) => {
|
|
21110
|
+
const members = await slack.authorizedMembersOf(channelId);
|
|
21111
|
+
const operators = keyOperators(slack);
|
|
21112
|
+
return operators.length > 0 ? members.filter((id) => operators.includes(id)) : members;
|
|
21113
|
+
},
|
|
21114
|
+
post: async (channelId, t) => { await slack.sendToChannel(channelId, t); },
|
|
21115
|
+
people: () => keyOperators(slack),
|
|
21116
|
+
directMessage: async (userId, t) => { await slack.sendDirectMessage(userId, t); },
|
|
21117
|
+
} : undefined,
|
|
21118
|
+
warn: (m) => console.warn(`[ClaudeKeyHealth] ${m}`),
|
|
21119
|
+
}, text);
|
|
20992
21120
|
},
|
|
20993
21121
|
notifyPerson: async (sessionName, text) => {
|
|
20994
21122
|
const topicId = topicForSession(sessionName);
|
|
@@ -21008,6 +21136,25 @@ export async function startServer(options) {
|
|
|
21008
21136
|
const launched = sessionManager.sessionLaunchKey(tmuxSession);
|
|
21009
21137
|
return launched ? claudeKeyFingerprint(launched) : null;
|
|
21010
21138
|
},
|
|
21139
|
+
recoveryPrompt: async (sessionName) => {
|
|
21140
|
+
const convo = await keyConversationLines(sessionName);
|
|
21141
|
+
if (!convo)
|
|
21142
|
+
return null;
|
|
21143
|
+
const held = heldMessages(convo.lines, keyNoticeTexts);
|
|
21144
|
+
return { prompt: buildKeyRecoveryPrompt(convo.channel, held), held: held.length };
|
|
21145
|
+
},
|
|
21146
|
+
answeredSince: async (sessionName, sinceMs) => {
|
|
21147
|
+
const convo = await keyConversationLines(sessionName);
|
|
21148
|
+
if (!convo)
|
|
21149
|
+
return null;
|
|
21150
|
+
if (answeredSince(convo.lines, sinceMs, keyNoticeTexts))
|
|
21151
|
+
return true;
|
|
21152
|
+
if (convo.channel.platform !== 'slack')
|
|
21153
|
+
return false;
|
|
21154
|
+
// The ring buffer can miss the agent's own post; Slack itself settles it.
|
|
21155
|
+
const fresh = await keyConversationLines(sessionName, true);
|
|
21156
|
+
return fresh ? answeredSince(fresh.lines, sinceMs, keyNoticeTexts) : null;
|
|
21157
|
+
},
|
|
21011
21158
|
refresh: async (sessionName, prompt) => {
|
|
21012
21159
|
if (!_sessionRefresh)
|
|
21013
21160
|
return { ok: false, reason: 'session refresh not available' };
|
|
@@ -25876,7 +26023,7 @@ export async function startServer(options) {
|
|
|
25876
26023
|
terminateSession: async (sk, reason, opts) => {
|
|
25877
26024
|
const topicNum = Number(sk);
|
|
25878
26025
|
const tmux = Number.isFinite(topicNum) ? telegram?.getSessionForTopic(topicNum) : null;
|
|
25879
|
-
const rec = tmux ? state.
|
|
26026
|
+
const rec = tmux ? state.findSessionByTmux(tmux) : undefined;
|
|
25880
26027
|
if (!rec)
|
|
25881
26028
|
return { terminated: false, skipped: 'no-local-session' };
|
|
25882
26029
|
return terminateWithAuthority(rec.id, reason, {
|
|
@@ -26083,6 +26230,14 @@ export async function startServer(options) {
|
|
|
26083
26230
|
counters: fwd.counters,
|
|
26084
26231
|
});
|
|
26085
26232
|
},
|
|
26233
|
+
// a2a-required-acknowledgment D4: the holder sends a standby's kinded ack.
|
|
26234
|
+
// The handler is the gate; it refuses when the feature is off here.
|
|
26235
|
+
'a2a-relay-forward-ack': async (cmd) => {
|
|
26236
|
+
if (!_requiredAckService)
|
|
26237
|
+
return { outcome: 'refused', reason: 'required-ack-not-wired' };
|
|
26238
|
+
const route = _requiredAckRelayRoute?.();
|
|
26239
|
+
return _requiredAckService.handleForwardedAck(cmd, { relay: route?.kind === 'relay' ? route : null });
|
|
26240
|
+
},
|
|
26086
26241
|
// §5 — type a reply into THIS machine's own live session for the
|
|
26087
26242
|
// topic (the confirmed paste). Never spawns, never moves the topic.
|
|
26088
26243
|
'a2a-topic-reply-inject': async (cmd) => {
|
|
@@ -26653,6 +26808,15 @@ export async function startServer(options) {
|
|
|
26653
26808
|
send: (peer, command, timeoutMs) => meshClient.send({ machineId: peer.machineId, url: peer.url }, command, 0, { timeoutMs }),
|
|
26654
26809
|
});
|
|
26655
26810
|
_a2aRelayForwardCtx.forward = (command) => relayForwarder.forward(command);
|
|
26811
|
+
// a2a-required-acknowledgment D4: a kinded ack through my relay-holding
|
|
26812
|
+
// machine. A holder that lacks the verb refuses it; the row stays pending.
|
|
26813
|
+
_a2aRelayForwardCtx.forwardAck = async (payload) => {
|
|
26814
|
+
const peer = await holderFinder.find();
|
|
26815
|
+
if (!peer)
|
|
26816
|
+
return 'refused';
|
|
26817
|
+
const res = await meshClient.send({ machineId: peer.machineId, url: peer.url }, { type: 'a2a-relay-forward-ack', ...payload }, 0, { timeoutMs: 15_000 });
|
|
26818
|
+
return res.ok && res.result?.outcome === 'sent' ? 'sent' : 'refused';
|
|
26819
|
+
};
|
|
26656
26820
|
_a2aAskTopicOwner = (machineId, payload, timeoutMs) => fwdMod.askTopicOwner(async (id, command, t) => {
|
|
26657
26821
|
const url = peerUrl(id);
|
|
26658
26822
|
if (!url)
|
|
@@ -29148,7 +29312,7 @@ export async function startServer(options) {
|
|
|
29148
29312
|
if (hasUsableBotToken && meshSelfId) {
|
|
29149
29313
|
// §4.1/§4.2 — settle, forward to the holder, ladder, then hold durably.
|
|
29150
29314
|
const runtime = telegramOriginBoot.runtime;
|
|
29151
|
-
const outcome = await originForwardMod.forwardReplyToHolder(forwardDeps(runtime), { topicId, chatId: tg.chatId, text, silent: opts?.silent, formatMode: tg.formatMode, kindMetadata: opts?.kindMetadata });
|
|
29315
|
+
const outcome = await originForwardMod.forwardReplyToHolder(forwardDeps(runtime), { topicId, chatId: tg.chatId, text, silent: opts?.silent, formatMode: opts?.formatMode ?? tg.formatMode, kindMetadata: opts?.kindMetadata });
|
|
29152
29316
|
if (outcome.kind === 'local')
|
|
29153
29317
|
throw new OriginForwardSettledLocallyError();
|
|
29154
29318
|
if (outcome.kind === 'sent')
|
|
@@ -29163,7 +29327,7 @@ export async function startServer(options) {
|
|
|
29163
29327
|
throw new TelegramOriginHoldError('origin-credential-owner-unavailable');
|
|
29164
29328
|
const { relayOriginBot } = await import('../messaging/telegram-origin/OriginMeshRelay.js');
|
|
29165
29329
|
return relayOriginBot({ runtime: telegramOriginBoot.runtime, topicId, text, chatId: tg.chatId,
|
|
29166
|
-
silent: opts?.silent, formatMode: tg.formatMode, kindMetadata: opts?.kindMetadata,
|
|
29330
|
+
silent: opts?.silent, formatMode: opts?.formatMode ?? tg.formatMode, kindMetadata: opts?.kindMetadata,
|
|
29167
29331
|
send: command => meshClient.send({ machineId: holder, url }, command, 0, { timeoutMs: relayTimeoutMs }) });
|
|
29168
29332
|
}
|
|
29169
29333
|
const r = await relayOutbound(topicId, text, opts, {
|
|
@@ -30507,7 +30671,7 @@ export async function startServer(options) {
|
|
|
30507
30671
|
const server = new AgentServer({ config, ecosystemLedger: _ecosystemLedger ?? undefined, recommendedServicesLedger: _recommendedServicesLedger ?? undefined, singleInstanceLock, agentIdentity: _agentIdentityDeps, terminateSessionAuthority: terminateWithAuthority, subscriptionEmailBinding: credentialLocationLedger, subscriptionEmailBarrier, subscriptionIdentityOracle, sessionManager, llmQueue: sharedLlmQueue, state, scheduler, telegram, telegramOrigin: telegramOriginBoot?.runtime, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, jobAnomalySendAutomationReply: sendAutomationReply, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, cartographerRoots: cartographerRoots ?? undefined, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, subscriptionPool, accountFollowMePeerViews: async () => { const nickById = new Map((_listPoolMachines?.() ?? []).map((m) => [m.machineId, verifiedEntityName(m.machineId, m.nickname) ?? ''])); let peers = (_resolvePeerUrls?.() ?? []).map((p) => ({ machineId: p.machineId, nickname: nickById.get(p.machineId) ?? '', url: p.url })); if (peers.length === 0) {
|
|
30508
30672
|
peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: verifiedEntityName(m.machineId, m.nickname) ?? '', url: m.lastKnownUrl }));
|
|
30509
30673
|
} if (peers.length === 0)
|
|
30510
|
-
return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, usageWallRescue: _usageWallRescue ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, localVerify: localVerifyService ?? undefined, localVerifyStatus: localVerifyStatus ?? undefined, guardLatchStore: guardLatchStore ?? undefined, agentStopSurfacer: agentStopSurfacer ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, topicProfile: _topicProfileCtx ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, meshBindActive: coordinator.managers.identityManager.hasIdentity() && config.multiMachine?.meshTransport?.enabled !== false, localSigningKeyPem, leaseTransport, peerEndpointRecorder, getSelfMeshEndpoints, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, conversationRegistry, conversationBindAuth, appConversations: _appConversationService ?? undefined, slackInboundDispatch: () => _slackInboundDispatch, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, peerHomebaseRelay, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, pairingInvites: threadlinePairingInvites, getLastRelayEvent: threadlineGetLastRelayEvent, a2aRelayForward: _a2aRelayForwardCtx ?? undefined, threadlineReplyWaiters, threadlineMcpHttp, memoryPrivacy: _memoryPrivacyWired ?? undefined, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, relayVerdictCounters: threadlineRelayClient ? (() => ({ ...threadlineRelayClient.relayVerdictCounters, expiredMismatchIgnored: a2aDeliveryTracker?.expiredMismatchIgnored ?? 0 })) : undefined, inboundIdLedger: _inboundIdLedger ?? undefined, inboundIdLedgerDaemonDeferred: () => _inboundIdLedgerDaemonDeferred, responseReviewGate, reviewCanaryBattery, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, ropeHealthMonitor, writeAdmission: writeAdmission ?? undefined, getInboundQueue: () => _inboundQueue, getMachineCoherence: () => _machineCoherenceSentinel, getSingleMachineFailoverGap: () => _singleMachineFailoverGap, getMissingLoginSession: () => _missingLoginSession, getSessionPoolFailoverRunner: () => _sessionPoolFailoverRunnerDriver?.status() ?? null, sessionPoolPromotionActivation: _sessionPoolPromotionActivation, meshRpcDispatcher, deliverA2aToMachine: _deliverA2aToMachine ?? undefined, workingSetPullCoordinator, workingSetArtifactManager, orchestratorPoller, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, replicatedStoreReconciler, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, jevMemoryPicker, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, claimTopicOwnershipOnSpawn: (topicId) => _claimOwnershipForAutonomousSpawn ? _claimOwnershipForAutonomousSpawn(topicId) : 'unwired', topicPinStore: _topicPinStore ?? undefined, topicPinSkewQuarantine: _topicPinSkewQuarantine ?? undefined, topicPinFoldView: _topicPinFoldView ?? undefined, ownershipReconciler: _ownershipReconciler ?? undefined, staleOwnerEngine: _staleOwnerEngine ?? undefined, duplicateReconciler: _duplicateReconciler ?? undefined, ownerDarkLadder: _ownerDarkLadder ?? undefined, spawnAdmission: _spawnAdmission ?? undefined, judgmentProvenance: _judgmentProvenance ?? undefined, leaseHandback: _leaseHandbackCtx ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, recordRopeResult: _recordRopeResult ?? undefined, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, passkeyRevokeOutbox: _passkeyRevokeOutbox ? () => _passkeyRevokeOutbox : undefined, passkeyPeerOnline: _passkeyPeerOnline, passkeyPoolReader: _passkeyPoolReader ? () => _passkeyPoolReader : undefined, passkeyProofBrowser: async (profileDir) => { const { ChromeCdpReloginBrowser } = await import('../core/ChromeCdpReloginBrowser.js'); return new ChromeCdpReloginBrowser({ userDataDir: profileDir, passkeyMode: true, headless: true, launchTimeoutMs: 30_000, operationTimeoutMs: 20_000 }); }, poolLink: _poolLink ?? undefined, poolPollCache: _poolPollCache ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, externalHogSentinel, orphanedWorkSentinel, mcpProcessReaper, codexArmSessionSweeper, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, standDownRegistry: _standDownRegistry ?? undefined, standDownAudit: _standDownAudit ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx });
|
|
30674
|
+
return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, usageWallRescue: _usageWallRescue ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, localVerify: localVerifyService ?? undefined, localVerifyStatus: localVerifyStatus ?? undefined, guardLatchStore: guardLatchStore ?? undefined, agentStopSurfacer: agentStopSurfacer ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, topicProfile: _topicProfileCtx ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, meshBindActive: coordinator.managers.identityManager.hasIdentity() && config.multiMachine?.meshTransport?.enabled !== false, localSigningKeyPem, leaseTransport, peerEndpointRecorder, getSelfMeshEndpoints, onLeasePullRequest: () => leaseCoordinatorRef?.currentLease() ?? null, liveTailReceiver, handoffWireTransport, onHandoffBegin, onHandoffInitiate: handoffInitiate, handoffInProgress: handoffSentinelInProgress, messageLedger, currentInboundByTopic, replyMarkerTransport, onReplyMarker: messageLedger ? (marker) => { const m = marker; messageLedger.applyRemoteReplyMarker(m.dedupeKey, { platform: m.platform, replyIdempotencyKey: m.replyIdempotencyKey, epoch: m.epoch, topic: m.topic ?? null }); } : undefined, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, conversationRegistry, conversationBindAuth, appConversations: _appConversationService ?? undefined, slackInboundDispatch: () => _slackInboundDispatch, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, peerHomebaseRelay, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, pairingInvites: threadlinePairingInvites, getLastRelayEvent: threadlineGetLastRelayEvent, a2aRelayForward: _a2aRelayForwardCtx ?? undefined, threadlineReplyWaiters, threadlineMcpHttp, memoryPrivacy: _memoryPrivacyWired ?? undefined, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, requiredAck: _requiredAckService ?? undefined, relayVerdictCounters: threadlineRelayClient ? (() => ({ ...threadlineRelayClient.relayVerdictCounters, expiredMismatchIgnored: a2aDeliveryTracker?.expiredMismatchIgnored ?? 0 })) : undefined, inboundIdLedger: _inboundIdLedger ?? undefined, inboundIdLedgerDaemonDeferred: () => _inboundIdLedgerDaemonDeferred, responseReviewGate, reviewCanaryBattery, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, machinePoolRegistry, ropeHealthMonitor, writeAdmission: writeAdmission ?? undefined, getInboundQueue: () => _inboundQueue, getMachineCoherence: () => _machineCoherenceSentinel, getSingleMachineFailoverGap: () => _singleMachineFailoverGap, getMissingLoginSession: () => _missingLoginSession, getSessionPoolFailoverRunner: () => _sessionPoolFailoverRunnerDriver?.status() ?? null, sessionPoolPromotionActivation: _sessionPoolPromotionActivation, meshRpcDispatcher, deliverA2aToMachine: _deliverA2aToMachine ?? undefined, workingSetPullCoordinator, workingSetArtifactManager, orchestratorPoller, commitmentReplicaStore, preferenceReplicaStore, replicatedRecordEmitter, replicatedStoreReconciler, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, jevMemoryPicker, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, claimTopicOwnershipOnSpawn: (topicId) => _claimOwnershipForAutonomousSpawn ? _claimOwnershipForAutonomousSpawn(topicId) : 'unwired', topicPinStore: _topicPinStore ?? undefined, topicPinSkewQuarantine: _topicPinSkewQuarantine ?? undefined, topicPinFoldView: _topicPinFoldView ?? undefined, ownershipReconciler: _ownershipReconciler ?? undefined, staleOwnerEngine: _staleOwnerEngine ?? undefined, duplicateReconciler: _duplicateReconciler ?? undefined, ownerDarkLadder: _ownerDarkLadder ?? undefined, spawnAdmission: _spawnAdmission ?? undefined, judgmentProvenance: _judgmentProvenance ?? undefined, leaseHandback: _leaseHandbackCtx ?? undefined, streamTicketStore: _streamTicketStore ?? undefined, poolStreamAllowRemoteInput: config.dashboard?.poolStream?.allowRemoteInput ?? false, poolStreamConnector: _poolStreamConnector ?? undefined, secretSync: _secretSyncHandle ?? undefined, meshSelfId: _meshSelfId ?? undefined, resolveRouterUrl: _resolveRouterUrl ?? undefined, resolvePeerUrls: _resolvePeerUrls ?? undefined, recordRopeResult: _recordRopeResult ?? undefined, guardRegistry, listPoolMachines: _listPoolMachines ?? undefined, deliverMandateToMachine: _deliverMandateToMachine ?? undefined, passkeyRevokeOutbox: _passkeyRevokeOutbox ? () => _passkeyRevokeOutbox : undefined, passkeyPeerOnline: _passkeyPeerOnline, passkeyPoolReader: _passkeyPoolReader ? () => _passkeyPoolReader : undefined, passkeyProofBrowser: async (profileDir) => { const { ChromeCdpReloginBrowser } = await import('../core/ChromeCdpReloginBrowser.js'); return new ChromeCdpReloginBrowser({ userDataDir: profileDir, passkeyMode: true, headless: true, launchTimeoutMs: 30_000, operationTimeoutMs: 20_000 }); }, poolLink: _poolLink ?? undefined, poolPollCache: _poolPollCache ?? undefined, sessionPoolE2EResultStore, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, agentWorktreeReaper, externalHogSentinel, orphanedWorkSentinel, mcpProcessReaper, codexArmSessionSweeper, geminiLoopRunner, sleepController, agentActivityState, reapLog, resumeQueue, resumeDrainer, autonomousLivenessReconciler, enforcedTerminationStatus: () => enforcedTerminationWatchdog?.guardStatus() ?? null, prHandLease: prHandLease ?? undefined, standDownRegistry: _standDownRegistry ?? undefined, standDownAudit: _standDownAudit ?? undefined, operatorStopRecorder: recordOperatorStop, sleepWakeDetector, unjustifiedStopGate, stopGateDb, stopNotifier, liveTestGate, liveTestGateMode, liveTestRunnerCtx });
|
|
30511
30675
|
if (_pendingCompactionEvidence)
|
|
30512
30676
|
featureEvidence.record('multiMachine.coherenceJournal.replication.compaction', _pendingCompactionEvidence); // Resolve the late-bound topic-operator getter (increment 2e): routing was
|
|
30513
30677
|
const readIdentityProjectionPeerRows = async () => {
|
|
@@ -32040,6 +32204,7 @@ export async function startServer(options) {
|
|
|
32040
32204
|
} // Warm-Session A2A reap tick
|
|
32041
32205
|
a2aSweep?.stop();
|
|
32042
32206
|
a2aSweep = null; // honest-delivery silence sweep
|
|
32207
|
+
_requiredAckService?.stop(); // a2a-required-acknowledgment 30-second timer
|
|
32043
32208
|
try {
|
|
32044
32209
|
_topicProfileOrchestrator?.dispose();
|
|
32045
32210
|
}
|