instar 1.3.61 → 1.3.63
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 +176 -10
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +36 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +45 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ReapGuard.d.ts +79 -0
- package/dist/core/ReapGuard.d.ts.map +1 -0
- package/dist/core/ReapGuard.js +114 -0
- package/dist/core/ReapGuard.js.map +1 -0
- package/dist/core/SessionLivenessOracle.d.ts +104 -0
- package/dist/core/SessionLivenessOracle.d.ts.map +1 -0
- package/dist/core/SessionLivenessOracle.js +201 -0
- package/dist/core/SessionLivenessOracle.js.map +1 -0
- package/dist/core/SessionManager.d.ts +90 -10
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +200 -40
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SessionRefresh.d.ts +10 -0
- package/dist/core/SessionRefresh.d.ts.map +1 -1
- package/dist/core/SessionRefresh.js +12 -2
- package/dist/core/SessionRefresh.js.map +1 -1
- package/dist/core/types.d.ts +70 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/ContextWedgeSentinel.d.ts +118 -0
- package/dist/monitoring/ContextWedgeSentinel.d.ts.map +1 -0
- package/dist/monitoring/ContextWedgeSentinel.js +238 -0
- package/dist/monitoring/ContextWedgeSentinel.js.map +1 -0
- package/dist/monitoring/ReapLog.d.ts +51 -0
- package/dist/monitoring/ReapLog.d.ts.map +1 -0
- package/dist/monitoring/ReapLog.js +82 -0
- package/dist/monitoring/ReapLog.js.map +1 -0
- package/dist/monitoring/ReapNotifier.d.ts +66 -0
- package/dist/monitoring/ReapNotifier.d.ts.map +1 -0
- package/dist/monitoring/ReapNotifier.js +112 -0
- package/dist/monitoring/ReapNotifier.js.map +1 -0
- package/dist/monitoring/SentinelNotifier.d.ts +1 -1
- package/dist/monitoring/SentinelNotifier.d.ts.map +1 -1
- package/dist/monitoring/SentinelNotifier.js.map +1 -1
- package/dist/monitoring/SessionReaper.d.ts +4 -0
- package/dist/monitoring/SessionReaper.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.js +19 -42
- package/dist/monitoring/SessionReaper.js.map +1 -1
- package/dist/monitoring/StaleSessionBackstop.d.ts +89 -0
- package/dist/monitoring/StaleSessionBackstop.d.ts.map +1 -0
- package/dist/monitoring/StaleSessionBackstop.js +176 -0
- package/dist/monitoring/StaleSessionBackstop.js.map +1 -0
- package/dist/monitoring/sentinelWiring.d.ts +23 -0
- package/dist/monitoring/sentinelWiring.d.ts.map +1 -1
- package/dist/monitoring/sentinelWiring.js +36 -0
- package/dist/monitoring/sentinelWiring.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +5 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +3 -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 +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +33 -11
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/src/scaffold/templates.ts +5 -0
- package/upgrades/1.3.62.md +87 -0
- package/upgrades/1.3.63.md +87 -0
- package/upgrades/side-effects/context-wedge-sentinel.md +69 -0
- package/upgrades/side-effects/unified-session-lifecycle-robustness.md +241 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+RH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAksDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+RH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAksDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAi6NtE;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
|
@@ -3880,6 +3880,54 @@ export async function startServer(options) {
|
|
|
3880
3880
|
// WorkingMemoryAssembler is initialized after activitySentinel (see below)
|
|
3881
3881
|
// so it can wire episodicMemory from the sentinel.
|
|
3882
3882
|
let workingMemory;
|
|
3883
|
+
// ── Reap observability + notify (UNIFIED-SESSION-LIFECYCLE §P3/§P4) ──
|
|
3884
|
+
// Wired BEFORE the boot purge so even boot-time reaps land in the reap-log
|
|
3885
|
+
// and surface a notice. The awake-checker is also wired here so the boot
|
|
3886
|
+
// purge is lease-gated (a standby never reaps another machine's sessions).
|
|
3887
|
+
// (The KEEP-guard is wired later, once its tracker deps exist — that is safe:
|
|
3888
|
+
// the boot purge passes knownDead and bypasses the guard, and the only other
|
|
3889
|
+
// guard consumers (monitorTick #2 age-limit / #3 idle-zombie) cannot fire a
|
|
3890
|
+
// kill in the first monitoring seconds — they require multi-hour age or 15+m
|
|
3891
|
+
// of observed idle — long after the guard is set below.)
|
|
3892
|
+
const { ReapLog } = await import('../monitoring/ReapLog.js');
|
|
3893
|
+
const { ReapNotifier } = await import('../monitoring/ReapNotifier.js');
|
|
3894
|
+
const reapLog = new ReapLog(config.stateDir, () => (coordinator.enabled ? coordinator.identity?.machineId : undefined));
|
|
3895
|
+
const reapNotifier = new ReapNotifier({
|
|
3896
|
+
resolveTopic: (tmuxSession) => {
|
|
3897
|
+
const t = telegram?.getTopicForSession(tmuxSession);
|
|
3898
|
+
if (t == null)
|
|
3899
|
+
return null;
|
|
3900
|
+
const n = typeof t === 'number' ? t : Number(t);
|
|
3901
|
+
return Number.isFinite(n) ? n : null;
|
|
3902
|
+
},
|
|
3903
|
+
lifelineTopic: () => telegram?.getLifelineTopicId() ?? null,
|
|
3904
|
+
// SUMMARY tier → through the formatter/tone-gate (HTML-escaped, quiet-hours
|
|
3905
|
+
// aware). The notifier already coalesces, so a burst is one message.
|
|
3906
|
+
send: (topicId, text) => notify('SUMMARY', 'session-reap', text, topicId),
|
|
3907
|
+
}, {
|
|
3908
|
+
enabled: config.monitoring?.reapNotify?.enabled ?? true,
|
|
3909
|
+
coalesceWindowMs: config.monitoring?.reapNotify?.coalesceWindowMs ?? 60_000,
|
|
3910
|
+
});
|
|
3911
|
+
sessionManager.setAwakeChecker(() => !coordinator.enabled || coordinator.isAwake);
|
|
3912
|
+
sessionManager.on('sessionReaped', (e) => {
|
|
3913
|
+
reapLog.recordReaped({
|
|
3914
|
+
session: e.session.name,
|
|
3915
|
+
tmuxSession: e.session.tmuxSession,
|
|
3916
|
+
reason: e.reason,
|
|
3917
|
+
disposition: e.disposition,
|
|
3918
|
+
origin: e.origin,
|
|
3919
|
+
});
|
|
3920
|
+
reapNotifier.onReaped({ session: e.session, reason: e.reason, disposition: e.disposition, origin: e.origin });
|
|
3921
|
+
});
|
|
3922
|
+
sessionManager.on('reapBlocked', (e) => {
|
|
3923
|
+
reapLog.recordSkipped({
|
|
3924
|
+
session: e.session.name,
|
|
3925
|
+
tmuxSession: e.session.tmuxSession,
|
|
3926
|
+
reason: e.reason,
|
|
3927
|
+
skipped: e.skipped,
|
|
3928
|
+
origin: e.origin,
|
|
3929
|
+
});
|
|
3930
|
+
});
|
|
3883
3931
|
// Fast startup purge — remove session records for dead tmux sessions BEFORE
|
|
3884
3932
|
// monitoring starts. Prevents the death spiral where stale sessions overwhelm
|
|
3885
3933
|
// the health endpoint (synchronous tmux has-session calls) and cause the
|
|
@@ -5178,10 +5226,12 @@ export async function startServer(options) {
|
|
|
5178
5226
|
// replace"). undefined when the corresponding sentinel is disabled.
|
|
5179
5227
|
let socketRecoveryActive;
|
|
5180
5228
|
let silenceRecoveryActive;
|
|
5229
|
+
let wedgeRecoveryActive;
|
|
5181
5230
|
{
|
|
5182
5231
|
const { SocketDisconnectSentinel } = await import('../monitoring/SocketDisconnectSentinel.js');
|
|
5183
5232
|
const { ActiveWorkSilenceSentinel } = await import('../monitoring/ActiveWorkSilenceSentinel.js');
|
|
5184
|
-
const {
|
|
5233
|
+
const { ContextWedgeSentinel } = await import('../monitoring/ContextWedgeSentinel.js');
|
|
5234
|
+
const { buildSocketDisconnectDeps, buildActiveWorkSilenceDeps, buildContextWedgeDeps, OutputActivityTracker, } = await import('../monitoring/sentinelWiring.js');
|
|
5185
5235
|
const { SentinelNotifier } = await import('../monitoring/SentinelNotifier.js');
|
|
5186
5236
|
const sessionSurface = {
|
|
5187
5237
|
captureOutput: (s, lines) => sessionManager.captureOutput(s, lines),
|
|
@@ -5249,6 +5299,45 @@ export async function startServer(options) {
|
|
|
5249
5299
|
? ' ActiveWorkSilenceSentinel enabled (silent-freeze watchdog — Telegram escalation ON, consolidated)'
|
|
5250
5300
|
: ' ActiveWorkSilenceSentinel enabled (silent-freeze watchdog — logs only, Telegram escalation OFF)'));
|
|
5251
5301
|
}
|
|
5302
|
+
// ── ContextWedgeSentinel — thinking-block-400 fast-fail wedge ──
|
|
5303
|
+
// Detection + audit ship default-ON (harmless housekeeping). The
|
|
5304
|
+
// destructive fresh-respawn is gated by autoRecovery (default OFF +
|
|
5305
|
+
// dryRun) and rides the Graduated Feature Rollout track. freshRespawn is
|
|
5306
|
+
// late-bound to _sessionRefresh (assigned later in boot) and only invoked
|
|
5307
|
+
// at recovery time; it uses fresh-mode so the new session never --resume-s
|
|
5308
|
+
// the corrupted transcript. Spec: docs/specs/context-wedge-sentinel.md.
|
|
5309
|
+
const wedgeCfg = config.monitoring?.contextWedgeSentinel ?? { enabled: true };
|
|
5310
|
+
if (wedgeCfg.enabled !== false) {
|
|
5311
|
+
const autoRecovery = wedgeCfg.autoRecovery ?? { enabled: false, dryRun: true };
|
|
5312
|
+
const wedgeSentinel = new ContextWedgeSentinel(buildContextWedgeDeps({
|
|
5313
|
+
sessions: sessionSurface,
|
|
5314
|
+
escalate: (name, text) => notifier.escalate('context-wedge', name, text),
|
|
5315
|
+
autoRecovery,
|
|
5316
|
+
freshRespawn: async (name) => {
|
|
5317
|
+
if (!_sessionRefresh)
|
|
5318
|
+
return false;
|
|
5319
|
+
const result = await _sessionRefresh.refreshSession({
|
|
5320
|
+
sessionName: name,
|
|
5321
|
+
fresh: true,
|
|
5322
|
+
reason: 'context-wedge-400',
|
|
5323
|
+
});
|
|
5324
|
+
return result.ok;
|
|
5325
|
+
},
|
|
5326
|
+
}), {
|
|
5327
|
+
enabled: wedgeCfg.enabled,
|
|
5328
|
+
tickIntervalMs: wedgeCfg.tickIntervalMs,
|
|
5329
|
+
confirmWindowMs: wedgeCfg.confirmWindowMs,
|
|
5330
|
+
});
|
|
5331
|
+
wedgeSentinel.on('detected', (e) => notifier.record('detected', 'context-wedge', e.sessionName));
|
|
5332
|
+
wedgeSentinel.on('recovered', (e) => notifier.record('recovered', 'context-wedge', e.sessionName, 'fresh respawn'));
|
|
5333
|
+
wedgeSentinel.on('dry-run', (e) => notifier.record('dry-run', 'context-wedge', e.sessionName, 'would fresh-respawn'));
|
|
5334
|
+
wedgeSentinel.on('false-alarm', (e) => notifier.record('false-alarm', 'context-wedge', e.sessionName, 'signature scrolled out of tail'));
|
|
5335
|
+
wedgeSentinel.on('recovery-error', (e) => notifier.record('recovery-error', 'context-wedge', e.sessionName, e.err instanceof Error ? e.err.message : String(e.err)));
|
|
5336
|
+
wedgeSentinel.start();
|
|
5337
|
+
wedgeRecoveryActive = (s) => wedgeSentinel.isRecoveryActive(s);
|
|
5338
|
+
const mode = autoRecovery.enabled ? (autoRecovery.dryRun ? 'auto-recover dry-run' : 'auto-recover LIVE') : 'detect-only';
|
|
5339
|
+
console.log(pc.green(` ContextWedgeSentinel enabled (thinking-block-400 wedge — ${mode})`));
|
|
5340
|
+
}
|
|
5252
5341
|
}
|
|
5253
5342
|
// Recompose the zombie-kill veto to include ALL four recovery sentinels now
|
|
5254
5343
|
// that socket + silence exist (the interim set above covered only compaction
|
|
@@ -5259,7 +5348,8 @@ export async function startServer(options) {
|
|
|
5259
5348
|
const composedRecoveryActive = (session) => compactionSentinel.isRecoveryActive(session.tmuxSession) ||
|
|
5260
5349
|
rateLimitSentinel.isRecoveryActive(session.tmuxSession) ||
|
|
5261
5350
|
(socketRecoveryActive?.(session.tmuxSession) ?? false) ||
|
|
5262
|
-
(silenceRecoveryActive?.(session.tmuxSession) ?? false)
|
|
5351
|
+
(silenceRecoveryActive?.(session.tmuxSession) ?? false) ||
|
|
5352
|
+
(wedgeRecoveryActive?.(session.tmuxSession) ?? false);
|
|
5263
5353
|
sessionManager.setActiveRecoveryChecker(composedRecoveryActive);
|
|
5264
5354
|
// Trigger 1: PreCompact hook event — report to sentinel.
|
|
5265
5355
|
hookEventReceiver.on('PreCompact', () => {
|
|
@@ -7679,14 +7769,15 @@ export async function startServer(options) {
|
|
|
7679
7769
|
const n = typeof t === 'number' ? t : Number(t);
|
|
7680
7770
|
return Number.isFinite(n) ? n : null;
|
|
7681
7771
|
};
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7772
|
+
// Shared stateless KEEP-guard deps (UNIFIED-SESSION-LIFECYCLE §P2). Built
|
|
7773
|
+
// once here and used to back BOTH the SessionReaper and the ReapAuthority's
|
|
7774
|
+
// guard (`sessionManager.setReapGuard`), so a killer cannot end a session the
|
|
7775
|
+
// reaper would have kept — the same chain protects every kill path.
|
|
7776
|
+
const reapGuardDeps = {
|
|
7777
|
+
protectedSessions: () => sessionManager.getProtectedSessions(),
|
|
7687
7778
|
isRecoveryActive: (session) => composedRecoveryActive(session),
|
|
7688
|
-
isRelayLeaseActive: (id) => sessionManager.isRelayLeaseActive(id),
|
|
7689
7779
|
hasPendingInjection: (s) => sessionManager.getPendingInjection(s) != null,
|
|
7780
|
+
isRelayLeaseActive: (id) => sessionManager.isRelayLeaseActive(id),
|
|
7690
7781
|
topicBinding: _resolveTopic,
|
|
7691
7782
|
// Gate I is a v1 stub (returns false): active conversation is already
|
|
7692
7783
|
// covered by the relay-lease + pending-injection gates and by render
|
|
@@ -7723,7 +7814,23 @@ export async function startServer(options) {
|
|
|
7723
7814
|
return true;
|
|
7724
7815
|
return fresh(path.join(config.stateDir, 'state', 'build', 'build-state.json'));
|
|
7725
7816
|
},
|
|
7726
|
-
|
|
7817
|
+
hasActiveProcesses: (s) => sessionManager.hasActiveProcesses(s),
|
|
7818
|
+
};
|
|
7819
|
+
// Wire the ReapAuthority's KEEP-guard. minAgeMs:0 disables spawn-grace here —
|
|
7820
|
+
// the killers that consult this guard (age-limit #2, idle-zombie #3) already
|
|
7821
|
+
// gate on their own age/idle thresholds, so the reaper-specific spawn-grace
|
|
7822
|
+
// would otherwise delay legitimate zombie kills for young-but-stuck sessions.
|
|
7823
|
+
{
|
|
7824
|
+
const { ReapGuard } = await import('../core/ReapGuard.js');
|
|
7825
|
+
sessionManager.setReapGuard(new ReapGuard(reapGuardDeps, { minAgeMs: 0 }));
|
|
7826
|
+
}
|
|
7827
|
+
// (setAwakeChecker is wired earlier, before the boot purge, so the purge is
|
|
7828
|
+
// lease-gated — see the §P3/§P4 block above.)
|
|
7829
|
+
const sessionReaper = new SessionReaper({
|
|
7830
|
+
...reapGuardDeps,
|
|
7831
|
+
listRunningSessions: () => sessionManager.listRunningSessions(),
|
|
7832
|
+
captureOutput: (s, n) => sessionManager.captureOutput(s, n) ?? '',
|
|
7833
|
+
frameworkForSession: (s) => sessionManager.frameworkForSession(s),
|
|
7727
7834
|
pressure: () => {
|
|
7728
7835
|
const total = _os.totalmem();
|
|
7729
7836
|
const freePct = total > 0 ? (_os.freemem() / total) * 100 : 100;
|
|
@@ -7736,6 +7843,65 @@ export async function startServer(options) {
|
|
|
7736
7843
|
audit: fileAuditSink(config.stateDir),
|
|
7737
7844
|
}, config.monitoring?.sessionReaper);
|
|
7738
7845
|
sessionReaper.start();
|
|
7846
|
+
// ── Unkillability backstop (UNIFIED-SESSION-LIFECYCLE §P5) ───────────────
|
|
7847
|
+
// Signal-only: raises ONE deduped Attention item (never auto-kills) when a
|
|
7848
|
+
// session is KEPT forever despite faking work, or is stuck indeterminate.
|
|
7849
|
+
{
|
|
7850
|
+
const { StaleSessionBackstop } = await import('../monitoring/StaleSessionBackstop.js');
|
|
7851
|
+
const { probeTranscript } = await import('../monitoring/transcriptProber.js');
|
|
7852
|
+
const { makeAttentionPoster } = await import('../monitoring/sentinelWiring.js');
|
|
7853
|
+
const _crypto = await import('node:crypto');
|
|
7854
|
+
const staleCfg = config.monitoring?.staleBackstop ?? {};
|
|
7855
|
+
const progressFloorBytes = staleCfg.progressFloorBytes ?? 512;
|
|
7856
|
+
const hash = (s) => _crypto.createHash('sha1').update(s).digest('hex').slice(0, 16);
|
|
7857
|
+
const backstop = new StaleSessionBackstop({
|
|
7858
|
+
listRunningSessions: () => sessionManager.listRunningSessions(),
|
|
7859
|
+
probeLiveness: (names) => sessionManager.probeLivenessBatch(names),
|
|
7860
|
+
snapshot: (session) => {
|
|
7861
|
+
const framework = session.framework ?? sessionManager.frameworkForSession(session.tmuxSession) ?? 'claude-code';
|
|
7862
|
+
const sessionId = framework === 'claude-code' ? (session.claudeSessionId ?? '') : '';
|
|
7863
|
+
const tp = probeTranscript({ framework, sessionId, projectDir: '' });
|
|
7864
|
+
// Tail hash: read the last progressFloorBytes so a heartbeat-byte append
|
|
7865
|
+
// (same tail) is NOT counted as a meaningful advance.
|
|
7866
|
+
let tailHash = null;
|
|
7867
|
+
if (tp.resolved && tp.path) {
|
|
7868
|
+
try {
|
|
7869
|
+
const fd = fs.openSync(tp.path, 'r');
|
|
7870
|
+
try {
|
|
7871
|
+
const start = Math.max(0, tp.size - progressFloorBytes);
|
|
7872
|
+
const len = tp.size - start;
|
|
7873
|
+
const buf = Buffer.alloc(len);
|
|
7874
|
+
fs.readSync(fd, buf, 0, len, start);
|
|
7875
|
+
tailHash = hash(buf.toString('utf-8'));
|
|
7876
|
+
}
|
|
7877
|
+
finally {
|
|
7878
|
+
fs.closeSync(fd);
|
|
7879
|
+
}
|
|
7880
|
+
}
|
|
7881
|
+
catch {
|
|
7882
|
+
// @silent-fallback-ok — an unreadable transcript tail just means
|
|
7883
|
+
// "no meaningful-advance signal this tick"; the backstop treats a
|
|
7884
|
+
// null tail as ambiguous (never as progress), which is safe.
|
|
7885
|
+
tailHash = null;
|
|
7886
|
+
}
|
|
7887
|
+
}
|
|
7888
|
+
const frame = sessionManager.captureOutput(session.tmuxSession, 8) ?? '';
|
|
7889
|
+
return {
|
|
7890
|
+
transcriptResolved: tp.resolved,
|
|
7891
|
+
transcriptSize: tp.size,
|
|
7892
|
+
transcriptTailHash: tailHash,
|
|
7893
|
+
mainProcessActive: sessionManager.hasActiveProcesses(session.tmuxSession),
|
|
7894
|
+
idleStateToken: hash(frame),
|
|
7895
|
+
};
|
|
7896
|
+
},
|
|
7897
|
+
raiseAttention: makeAttentionPoster({ port: config.port, authToken: config.authToken ?? '' }),
|
|
7898
|
+
setLongIndeterminate: (id, isLong) => sessionManager.markLongIndeterminate(id, isLong),
|
|
7899
|
+
}, staleCfg);
|
|
7900
|
+
backstop.start();
|
|
7901
|
+
if (staleCfg.enabled !== false) {
|
|
7902
|
+
console.log(pc.green(' Unkillability backstop enabled (§P5 — signal-only, never auto-kills)'));
|
|
7903
|
+
}
|
|
7904
|
+
}
|
|
7739
7905
|
if (config.monitoring?.sessionReaper?.enabled) {
|
|
7740
7906
|
console.log(pc.green(config.monitoring.sessionReaper.dryRun === false
|
|
7741
7907
|
? ' SessionReaper enabled (idle-session reaper — LIVE)'
|
|
@@ -7888,7 +8054,7 @@ export async function startServer(options) {
|
|
|
7888
8054
|
}
|
|
7889
8055
|
}
|
|
7890
8056
|
}
|
|
7891
|
-
const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, leaseTransport, 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, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, unjustifiedStopGate, stopGateDb, stopNotifier });
|
|
8057
|
+
const server = new AgentServer({ config, sessionManager, state, scheduler, telegram, relationships, feedback, feedbackAnomalyDetector, dispatches, updateChecker, autoUpdater, autoDispatcher, quotaTracker, quotaManager, publisher, viewer, tunnel, evolution, watchdog, topicMemory, triageNurse, projectMapper, coherenceGate: scopeVerifier, contextHierarchy, canonicalState, operationGate, sentinel, adaptiveTrust, memoryMonitor, orphanReaper, coherenceMonitor, commitmentTracker, semanticMemory, activitySentinel, rateLimitSentinel, releaseReadinessSentinel: releaseReadinessSentinel ?? undefined, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, sessionRefresh: _sessionRefresh ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, leaseTransport, 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, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, conversationStore, warrantsReplyGate, collaborationSurfacer, threadResumeMap, topicLinkageHandler: topicLinkageHandler ?? undefined, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, outboundDedupGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, completionEvaluator, unifiedTrust, liveConfig, sharedStateLedger, ledgerSessionRegistry, worktreeManager, oidcEnrolledRepos: parallelDevConfig?.oidcEnrolledRepos, initiativeTracker, projectRoundRunner, projectDriftChecker, machineHeartbeat, proxyCoordinator, topicIntentStore, topicIntentArcCheck, usherSignalStore, intelligence: sharedIntelligence ?? undefined, telegramBridgeConfig, telegramBridge: telegramBridge ?? undefined, threadlineObservability, briefDeps, workingMemory, taskFlowRegistry, threadlineFlowBridge, sessionReaper, reapLog, unjustifiedStopGate, stopGateDb, stopNotifier });
|
|
7892
8058
|
// Boot-recovery (tunnel-failure-resilience spec Part 6): if the agent
|
|
7893
8059
|
// died mid-relay-episode, the persisted tunnel.json carries
|
|
7894
8060
|
// rotationPending=true. Rotate the dashboard PIN + authToken BEFORE
|