instar 1.3.1323 → 1.3.1324
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 +130 -8
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +9 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/BackupManager.d.ts.map +1 -1
- package/dist/core/BackupManager.js +3 -0
- package/dist/core/BackupManager.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +14 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +6 -0
- package/dist/core/devGatedFeatures.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/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/messaging/MessageRouter.d.ts +8 -0
- package/dist/messaging/MessageRouter.d.ts.map +1 -1
- package/dist/messaging/MessageRouter.js +14 -1
- package/dist/messaging/MessageRouter.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +4 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +7 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +42 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +9 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +176 -6
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/A2ADeliveryTracker.d.ts +3 -1
- package/dist/threadline/A2ADeliveryTracker.d.ts.map +1 -1
- package/dist/threadline/A2ADeliveryTracker.js +15 -6
- package/dist/threadline/A2ADeliveryTracker.js.map +1 -1
- package/dist/threadline/InboundIdLedger.d.ts +373 -0
- package/dist/threadline/InboundIdLedger.d.ts.map +1 -0
- package/dist/threadline/InboundIdLedger.js +932 -0
- package/dist/threadline/InboundIdLedger.js.map +1 -0
- package/dist/threadline/InboundMessageGate.d.ts +22 -0
- package/dist/threadline/InboundMessageGate.d.ts.map +1 -1
- package/dist/threadline/InboundMessageGate.js +87 -17
- package/dist/threadline/InboundMessageGate.js.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.d.ts +6 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.js +8 -2
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.d.ts +14 -0
- package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.js +83 -2
- package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
- package/dist/threadline/ThreadlineRouter.d.ts +19 -0
- package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
- package/dist/threadline/ThreadlineRouter.js +41 -18
- package/dist/threadline/ThreadlineRouter.js.map +1 -1
- package/dist/threadline/client/MessageEncryptor.d.ts +9 -1
- package/dist/threadline/client/MessageEncryptor.d.ts.map +1 -1
- package/dist/threadline/client/MessageEncryptor.js +5 -3
- package/dist/threadline/client/MessageEncryptor.js.map +1 -1
- package/dist/threadline/client/ThreadlineClient.d.ts +10 -4
- package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -1
- package/dist/threadline/client/ThreadlineClient.js +19 -10
- package/dist/threadline/client/ThreadlineClient.js.map +1 -1
- package/dist/threadline/inboundIdLedgerWiring.d.ts +105 -0
- package/dist/threadline/inboundIdLedgerWiring.d.ts.map +1 -0
- package/dist/threadline/inboundIdLedgerWiring.js +257 -0
- package/dist/threadline/inboundIdLedgerWiring.js.map +1 -0
- package/dist/threadline/recordInboundAck.d.ts +4 -1
- package/dist/threadline/recordInboundAck.d.ts.map +1 -1
- package/dist/threadline/recordInboundAck.js +4 -3
- package/dist/threadline/recordInboundAck.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +65 -65
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/src/scaffold/templates.ts +4 -0
- package/upgrades/1.3.1324.md +32 -0
- package/upgrades/a2a-inbound-id-ledger.eli16.md +7 -0
- package/upgrades/side-effects/a2a-inbound-id-ledger.md +101 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAuGA,OAAO,EAAE,cAAc,EAAwD,MAAM,2BAA2B,CAAC;AAUjH,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA4BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAoI7D,OAAO,KAAK,EAAW,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAmFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AA0ID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoDD,+EAA+E;AAC/E,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,IAAI,CAAC,OAAO,2BAA2B,EAAE,cAAc,EAAE,QAAQ,CAAC,GAAG,IAAI,EACpF,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAuGA,OAAO,EAAE,cAAc,EAAwD,MAAM,2BAA2B,CAAC;AAUjH,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA4BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAoI7D,OAAO,KAAK,EAAW,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAmFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AA0ID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoDD,+EAA+E;AAC/E,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,IAAI,CAAC,OAAO,2BAA2B,EAAE,cAAc,EAAE,QAAQ,CAAC,GAAG,IAAI,EACpF,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAqfD,wBAAsB,oBAAoB,CACxC,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,kBAAkB,CAAC,EAAE,MAAM;AAC3B;;qCAEqC;AACrC,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AACzD;;wEAEwE;AACxE,SAAS,CAAC,EAAE;IACV,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;sEAGkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC,MAAM,CAAC,CAqYjB;AA02BD;;;;;;;;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,CA8yBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2zwBtE;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
|
@@ -644,6 +644,50 @@ let _resolveRouterUrl = null;
|
|
|
644
644
|
/** Every OTHER active machine with a known URL — backs GET /sessions?scope=pool
|
|
645
645
|
* (pool-wide session aggregation for the dashboard). Set in the same mesh block. */
|
|
646
646
|
let _resolvePeerUrls = null;
|
|
647
|
+
/** A2A inbound message-id ledger controller (docs/specs/a2a-inbound-id-ledger.md).
|
|
648
|
+
* Built at the inbound-queue sweep's boot site (before recoverPendingInjects),
|
|
649
|
+
* shared with the relay consumer and AgentServer. Null ⇒ never constructed. */
|
|
650
|
+
let _inboundIdLedger = null;
|
|
651
|
+
/** True while the listener daemon owns inbound relay handling (no capability then). */
|
|
652
|
+
let _inboundIdLedgerDaemonDeferred = false;
|
|
653
|
+
/** Late-bound holder for the pool registry (assigned where it is constructed) —
|
|
654
|
+
* read by annotatePeerHandoff for online status + routerReceivedAt ordering. */
|
|
655
|
+
let _machinePoolRegistryForAnnotation = null;
|
|
656
|
+
let _peerHandoffAnnotator = null;
|
|
657
|
+
/**
|
|
658
|
+
* Inbound-id ledger §4: the annotate-only peer read for a marked resend. Asks
|
|
659
|
+
* at most 8 online peers (ordered by routerReceivedAt), 500 ms shared timeout,
|
|
660
|
+
* 16 in flight process-wide, a per-peer breaker, early return on the first
|
|
661
|
+
* `handed-off`. Its answer ONLY words the resent-copy notice — it can never
|
|
662
|
+
* stop a message. Never PoolPollCache: a direct, uncached fetch.
|
|
663
|
+
*/
|
|
664
|
+
async function annotatePeerHandoff(config, ledger, senderKey, messageId) {
|
|
665
|
+
if (!_peerHandoffAnnotator) {
|
|
666
|
+
const { createPeerHandoffAnnotator } = await import('../threadline/inboundIdLedgerWiring.js');
|
|
667
|
+
_peerHandoffAnnotator = createPeerHandoffAnnotator({
|
|
668
|
+
peers: () => (_resolvePeerUrls?.() ?? [])
|
|
669
|
+
.map((p) => ({ ...p, cap: _machinePoolRegistryForAnnotation?.getCapacity(p.machineId) ?? null }))
|
|
670
|
+
.filter((p) => p.cap?.online !== false)
|
|
671
|
+
.map((p) => ({ machineId: p.machineId, url: p.url, routerReceivedAt: p.cap?.routerReceivedAt ?? null })),
|
|
672
|
+
isUrlAllowed: (url) => isPeerUrlAllowedForCredentials(url, config.multiMachine?.peerUrlAllowlist).ok,
|
|
673
|
+
authToken: config.authToken ?? '',
|
|
674
|
+
agentId: config.projectName,
|
|
675
|
+
counters: {
|
|
676
|
+
annotated: () => _inboundIdLedger?.peek()?.bump('peerAnnotated'),
|
|
677
|
+
unavailable: (reason) => _inboundIdLedger?.peek()?.bumpPeerCheckUnavailable(reason),
|
|
678
|
+
},
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
void ledger;
|
|
682
|
+
try {
|
|
683
|
+
return await _peerHandoffAnnotator(senderKey, messageId);
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
// @silent-fallback-ok — annotate-only read: a failure is counted and only changes the notice wording.
|
|
687
|
+
_inboundIdLedger?.peek()?.bumpPeerCheckUnavailable('error');
|
|
688
|
+
return false;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
647
691
|
/** WS1.2 sender leg: order a REMOTE owner to drain `sessionKey` for a transfer
|
|
648
692
|
* to `target` (signed mesh `drain` verb). Set in the mesh-client block; null =
|
|
649
693
|
* pool dark / no client — the transfer route degrades to today's pin path. */
|
|
@@ -10355,6 +10399,41 @@ export async function startServer(options) {
|
|
|
10355
10399
|
// the health endpoint (synchronous tmux has-session calls) and cause the
|
|
10356
10400
|
// lifeline to restart the server in a tight loop.
|
|
10357
10401
|
await sessionManager.purgeDeadSessions();
|
|
10402
|
+
// ── A2A inbound message-id ledger (docs/specs/a2a-inbound-id-ledger.md) ──
|
|
10403
|
+
// Opened HERE, at the inbound-queue sweep's boot site and BEFORE
|
|
10404
|
+
// recoverPendingInjects, when the feature resolves on (dev gate when
|
|
10405
|
+
// `enabled` is omitted). Read LIVE: a false→true flip opens lazily on the
|
|
10406
|
+
// first ingress; true→false closes it and stops its timers. An unopenable
|
|
10407
|
+
// file leaves the ledger dark (today's behaviour) with one degradation.
|
|
10408
|
+
try {
|
|
10409
|
+
const { buildInboundIdLedgerController } = await import('../threadline/InboundIdLedger.js');
|
|
10410
|
+
_inboundIdLedger = buildInboundIdLedgerController({
|
|
10411
|
+
stateDir: config.stateDir,
|
|
10412
|
+
agentId: config.projectName,
|
|
10413
|
+
developmentAgent: config.developmentAgent,
|
|
10414
|
+
readBlock: () => {
|
|
10415
|
+
const live = liveConfig.get('threadline', undefined);
|
|
10416
|
+
return (live?.inboundIdLedger
|
|
10417
|
+
?? config.threadline?.inboundIdLedger);
|
|
10418
|
+
},
|
|
10419
|
+
reportDegradation: (d) => DegradationReporter.getInstance().report(d),
|
|
10420
|
+
});
|
|
10421
|
+
const bootLedger = _inboundIdLedger.current();
|
|
10422
|
+
if (bootLedger) {
|
|
10423
|
+
console.log(pc.dim(` [inbound-id-ledger] open (${bootLedger.deadEpochAdmittedAtBoot} row(s) left admitted by a prior process)`));
|
|
10424
|
+
}
|
|
10425
|
+
}
|
|
10426
|
+
catch (err) {
|
|
10427
|
+
// @silent-fallback-ok — ledger dark is today's behaviour; logged, and a file-open failure reports its own degradation.
|
|
10428
|
+
console.warn(`[server] inbound-id ledger construction failed (non-fatal, ledger dark): ${err instanceof Error ? err.message : String(err)}`);
|
|
10429
|
+
// Hand AgentServer a DARK controller so it never builds its own (the HTTP
|
|
10430
|
+
// routes must not advertise a ledger the relay socket is running without).
|
|
10431
|
+
try {
|
|
10432
|
+
const { InboundIdLedgerController } = await import('../threadline/InboundIdLedger.js');
|
|
10433
|
+
_inboundIdLedger = new InboundIdLedgerController({ isEnabled: () => false, open: () => { throw new Error('ledger dark'); } });
|
|
10434
|
+
}
|
|
10435
|
+
catch { /* @silent-fallback-ok — AgentServer falls back to its own construction */ }
|
|
10436
|
+
}
|
|
10358
10437
|
// ── Durable Inbound Message Queue: unconditional boot sweep (§5.3) ──
|
|
10359
10438
|
// MUST run BEFORE recoverPendingInjects (boot ordering, spec §3.4): the
|
|
10360
10439
|
// sweep consults injection receipts and vetoes PIS records for
|
|
@@ -16986,6 +17065,24 @@ export async function startServer(options) {
|
|
|
16986
17065
|
threadlineShutdown = threadline.shutdown;
|
|
16987
17066
|
threadlineRelayClient = threadline.relayClient;
|
|
16988
17067
|
threadlineGetLastRelayEvent = threadline.getLastRelayEvent;
|
|
17068
|
+
// Inbound-id ledger §3/§6: daemon-inbox mode is not covered — never advertise there.
|
|
17069
|
+
_inboundIdLedgerDaemonDeferred = threadline.daemonHandlingRelay === true;
|
|
17070
|
+
// Inbound-id ledger §1: the gate consults the ledger AFTER the operation-
|
|
17071
|
+
// permission check and BEFORE the rate limiter counts a data message; a
|
|
17072
|
+
// terminal-row replay is dropped there and handed to the duplicate handler.
|
|
17073
|
+
if (threadline.inboundGate) {
|
|
17074
|
+
const { recordDuplicateAck } = await import('../threadline/inboundIdLedgerWiring.js');
|
|
17075
|
+
threadline.inboundGate.setLedgerLookup((fp, id) => _inboundIdLedger?.current()?.lookup(fp, id) ?? 'unavailable', (fp, id) => {
|
|
17076
|
+
const l = _inboundIdLedger?.current();
|
|
17077
|
+
if (!l)
|
|
17078
|
+
return;
|
|
17079
|
+
l.bump('dedupById');
|
|
17080
|
+
l.bumpReplayDropped(fp);
|
|
17081
|
+
const row = l.getRow(fp, id);
|
|
17082
|
+
if (row)
|
|
17083
|
+
recordDuplicateAck(a2aDeliveryTracker, row);
|
|
17084
|
+
});
|
|
17085
|
+
}
|
|
16989
17086
|
// Honest delivery (docs/specs/a2a-honest-delivery-outcomes.md §5): ONE
|
|
16990
17087
|
// writer for relay verdicts on the long-lived ThreadlineClient.
|
|
16991
17088
|
if (threadlineRelayClient) {
|
|
@@ -17064,9 +17161,22 @@ export async function startServer(options) {
|
|
|
17064
17161
|
if (threadline.inboundGate) {
|
|
17065
17162
|
threadline.inboundGate.setRouter(threadlineRouter);
|
|
17066
17163
|
}
|
|
17164
|
+
const { runRelayInboundWithLedger } = await import('../threadline/inboundIdLedgerWiring.js');
|
|
17165
|
+
const { InboundMessageGate: InboundGateStatics } = await import('../threadline/InboundMessageGate.js');
|
|
17067
17166
|
threadlineRelayClient.on('gate-passed', async (decision) => {
|
|
17068
|
-
|
|
17069
|
-
|
|
17167
|
+
// Inbound-id ledger (docs/specs/a2a-inbound-id-ledger.md §1) — THE
|
|
17168
|
+
// COMMIT POINT: runRelayInboundWithLedger commits as the first statement
|
|
17169
|
+
// after the null-check and the probe exclusion, BEFORE every side effect
|
|
17170
|
+
// (waiter, auto-ack, inbox append, implicit ack, warrants state,
|
|
17171
|
+
// dispatch), and finishes the attempt-owned ticket in a `finally`.
|
|
17172
|
+
await runRelayInboundWithLedger(decision, {
|
|
17173
|
+
ledger: () => _inboundIdLedger?.current() ?? null,
|
|
17174
|
+
tracker: () => a2aDeliveryTracker,
|
|
17175
|
+
extractMessageId: (m) => InboundGateStatics.extractMessageId(m),
|
|
17176
|
+
annotate: (ledger, senderKey, messageId) => annotatePeerHandoff(config, ledger, senderKey, messageId),
|
|
17177
|
+
}, (ledgerTicket, ledgerNotice) => handleGatePassedRelayMessage(decision, ledgerTicket, ledgerNotice));
|
|
17178
|
+
});
|
|
17179
|
+
async function handleGatePassedRelayMessage(decision, ledgerTicket, ledgerNotice) {
|
|
17070
17180
|
const msg = decision.message;
|
|
17071
17181
|
const senderFingerprint = msg.from;
|
|
17072
17182
|
const senderName = senderFingerprint.slice(0, 8);
|
|
@@ -17197,6 +17307,12 @@ export async function startServer(options) {
|
|
|
17197
17307
|
humanInLoop: false,
|
|
17198
17308
|
});
|
|
17199
17309
|
if (decision.suppress) {
|
|
17310
|
+
// Inbound-id ledger: a pure no-reply verdict → `no-reply` (terminal);
|
|
17311
|
+
// a loop-budget suppression depends on loop state → `refused`.
|
|
17312
|
+
if (decision.verdict.budgetExhausted)
|
|
17313
|
+
ledgerTicket?.recordRefused('loop-budget');
|
|
17314
|
+
else
|
|
17315
|
+
ledgerTicket?.recordNoReply();
|
|
17200
17316
|
console.log(`[relay] warrants-reply gate suppressed reply (${decision.verdict.signal}) for ${senderName} thread ${gateThreadId.slice(0, 8)}`);
|
|
17201
17317
|
// On budget exhaustion, surface ONE status notice — never silently
|
|
17202
17318
|
// drop. CMT-519: route it to the SILENT Threadline hub (not a
|
|
@@ -17261,12 +17377,13 @@ export async function startServer(options) {
|
|
|
17261
17377
|
if (intent === 'pipe') {
|
|
17262
17378
|
const result = await pipeSpawner.spawn({
|
|
17263
17379
|
threadId: msg.threadId,
|
|
17264
|
-
messageText: textContent,
|
|
17380
|
+
messageText: ledgerNotice ? `[server notice: ${ledgerNotice}]\n\n${textContent}` : textContent,
|
|
17265
17381
|
fromFingerprint: senderFingerprint,
|
|
17266
17382
|
fromName: senderName,
|
|
17267
17383
|
trustLevel,
|
|
17268
17384
|
});
|
|
17269
17385
|
if (result.spawned) {
|
|
17386
|
+
ledgerTicket?.recordHandoff('pipe');
|
|
17270
17387
|
console.log(`[relay] Pipe session spawned for ${senderName} (thread: ${msg.threadId.slice(0, 8)})`);
|
|
17271
17388
|
return;
|
|
17272
17389
|
}
|
|
@@ -17288,7 +17405,8 @@ export async function startServer(options) {
|
|
|
17288
17405
|
// `!threadResumeMap.get(...)` guard, now that get() no longer nulls them.)
|
|
17289
17406
|
const isTopicBoundReply = !!msg.threadId && threadResumeMap.get(msg.threadId)?.originTopicId !== undefined;
|
|
17290
17407
|
if (listenerManager && listenerManager.shouldUseListener(trustLevel, textContent.length) && !isTopicBoundReply) {
|
|
17291
|
-
listenerManager.writeToInbox({ from: senderFingerprint, senderName, trustLevel, threadId: msg.threadId ?? getSyntheticThreadId(senderFingerprint), text: textContent });
|
|
17408
|
+
listenerManager.writeToInbox({ from: senderFingerprint, senderName, trustLevel, threadId: msg.threadId ?? getSyntheticThreadId(senderFingerprint), text: ledgerNotice ? `[server notice: ${ledgerNotice}]\n\n${textContent}` : textContent });
|
|
17409
|
+
ledgerTicket?.recordHandoff('listener');
|
|
17292
17410
|
console.log(`[relay] Routed to listener inbox from ${senderName} (trust: ${trustLevel})`);
|
|
17293
17411
|
return;
|
|
17294
17412
|
}
|
|
@@ -17313,22 +17431,24 @@ export async function startServer(options) {
|
|
|
17313
17431
|
trustLevel,
|
|
17314
17432
|
preferWarmSession,
|
|
17315
17433
|
};
|
|
17316
|
-
let result = await threadlineRouter.handleInboundMessage(envelope, relayContext);
|
|
17434
|
+
let result = await threadlineRouter.handleInboundMessage(envelope, relayContext, { resentNotice: ledgerNotice });
|
|
17317
17435
|
// Fallback only when a threadless message could not be associated
|
|
17318
17436
|
// with any thread. A refusal can be unhandled while still carrying
|
|
17319
17437
|
// the router-resolved threadId; retrying that payload would hand the
|
|
17320
17438
|
// same refused message to the router twice.
|
|
17321
17439
|
if (!result.handled && !result.threadId && !msg.threadId) {
|
|
17322
17440
|
envelope.message.threadId = getSyntheticThreadId(senderFingerprint);
|
|
17323
|
-
result = await threadlineRouter.handleInboundMessage(envelope, relayContext);
|
|
17441
|
+
result = await threadlineRouter.handleInboundMessage(envelope, relayContext, { resentNotice: ledgerNotice });
|
|
17324
17442
|
}
|
|
17443
|
+
// Inbound-id ledger: the outcome of the LAST path tried, through the allowlist.
|
|
17444
|
+
ledgerTicket?.recordRouterResult(result);
|
|
17325
17445
|
if (result.error)
|
|
17326
17446
|
console.warn(`[relay] Router error: ${result.error}`);
|
|
17327
17447
|
if (result.spawned)
|
|
17328
17448
|
console.log(`[relay] Spawned session for ${senderName} (trust: ${trustLevel}, thread: ${result.threadId})`);
|
|
17329
17449
|
if (result.resumed)
|
|
17330
17450
|
console.log(`[relay] Resumed session for ${senderName} (thread: ${result.threadId})`);
|
|
17331
|
-
}
|
|
17451
|
+
}
|
|
17332
17452
|
// Relay client is passed to AgentServer → RouteContext for the /threadline/relay-send endpoint
|
|
17333
17453
|
console.log(pc.green(` Threadline: relay connected to ${config.threadline?.relayUrl ?? DEFAULT_RELAY_HOST}`));
|
|
17334
17454
|
}
|
|
@@ -20189,6 +20309,8 @@ export async function startServer(options) {
|
|
|
20189
20309
|
// B4 Decision 10 — hand the skew-immune registry to the lease-liveness
|
|
20190
20310
|
// closures (forward-ref declared at function-body scope above the lease).
|
|
20191
20311
|
leaseLivenessRegistry = machinePoolRegistry;
|
|
20312
|
+
// Inbound-id ledger §4: annotatePeerHandoff reads online status + order here.
|
|
20313
|
+
_machinePoolRegistryForAnnotation = machinePoolRegistry;
|
|
20192
20314
|
const poolSelfId = machineHeartbeat?.config?.machineId ??
|
|
20193
20315
|
(poolIdMgr.hasIdentity() ? poolIdMgr.loadIdentity().machineId : null);
|
|
20194
20316
|
// WS4.3 journal-lease cutover (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3,
|
|
@@ -26227,7 +26349,7 @@ export async function startServer(options) {
|
|
|
26227
26349
|
const server = new AgentServer({ config, singleInstanceLock, 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, 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, m.nickname ?? m.machineId])); let peers = (_resolvePeerUrls?.() ?? []).map((p) => ({ machineId: p.machineId, nickname: nickById.get(p.machineId) ?? p.machineId, url: p.url })); if (peers.length === 0) {
|
|
26228
26350
|
peers = (_listPoolMachines?.() ?? []).filter((m) => m.machineId !== _meshSelfId && !!m.lastKnownUrl).map((m) => ({ machineId: m.machineId, nickname: m.nickname ?? m.machineId, url: m.lastKnownUrl }));
|
|
26229
26351
|
} if (peers.length === 0)
|
|
26230
|
-
return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, guardLatchStore: guardLatchStore ?? 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, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, getLastRelayEvent: threadlineGetLastRelayEvent, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, a2aDeliveryTracker: a2aDeliveryTracker ?? undefined, relayVerdictCounters: threadlineRelayClient ? (() => ({ ...threadlineRelayClient.relayVerdictCounters, expiredMismatchIgnored: a2aDeliveryTracker?.expiredMismatchIgnored ?? 0 })) : undefined, 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, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, jevMemoryPicker, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, 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, 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, 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 }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
|
|
26352
|
+
return []; const { fetchPeerSubscriptionViews } = await import('../core/fetchPeerSubscriptionViews.js'); return fetchPeerSubscriptionViews({ peers: () => peers, fetchImpl: fetch, authToken: config.authToken ?? '' }); }, quotaPoller, quotaAwareScheduler: _quotaAwareScheduler ?? undefined, proactiveSwapMonitor: _proactiveSwapMonitor ?? undefined, inUseAccountResolver, enrollmentWizard, accountFollowMeRevocation, credentialRepointing, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, greenPrAutoMerger: greenPrAutoMerger ?? undefined, guardLatchStore: guardLatchStore ?? 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, conversationFollowThrough, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, threadLog, threadMessageRecorder, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, getLastRelayEvent: threadlineGetLastRelayEvent, threadlineReplyWaiters, 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, conflictStore, rollbackUnmerge, droppedOriginRegistry, preferencesUnionReader, jevMemoryPicker, forwardCommitmentMutate, sessionOwnershipRegistry, sendDrain: _sendDrain ?? undefined, 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, 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, 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 }); // Resolve the late-bound topic-operator getter (increment 2e): routing was
|
|
26231
26353
|
const readIdentityProjectionPeerRows = async () => {
|
|
26232
26354
|
const peers = _resolvePeerUrls?.() ?? [];
|
|
26233
26355
|
const extra = config.multiMachine?.peerUrlAllowlist;
|