instar 0.28.33 → 0.28.41

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.
Files changed (86) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +119 -47
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/CoherenceGate.d.ts +7 -0
  5. package/dist/core/CoherenceGate.d.ts.map +1 -1
  6. package/dist/core/CoherenceGate.js +7 -6
  7. package/dist/core/CoherenceGate.js.map +1 -1
  8. package/dist/core/CoherenceReviewer.d.ts +20 -5
  9. package/dist/core/CoherenceReviewer.d.ts.map +1 -1
  10. package/dist/core/CoherenceReviewer.js +36 -6
  11. package/dist/core/CoherenceReviewer.js.map +1 -1
  12. package/dist/core/MessagingToneGate.d.ts +42 -0
  13. package/dist/core/MessagingToneGate.d.ts.map +1 -0
  14. package/dist/core/MessagingToneGate.js +109 -0
  15. package/dist/core/MessagingToneGate.js.map +1 -0
  16. package/dist/core/SessionManager.d.ts +9 -0
  17. package/dist/core/SessionManager.d.ts.map +1 -1
  18. package/dist/core/SessionManager.js +18 -0
  19. package/dist/core/SessionManager.js.map +1 -1
  20. package/dist/messaging/TelegramAdapter.d.ts +8 -0
  21. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  22. package/dist/messaging/TelegramAdapter.js +42 -3
  23. package/dist/messaging/TelegramAdapter.js.map +1 -1
  24. package/dist/monitoring/CompactionSentinel.d.ts +143 -0
  25. package/dist/monitoring/CompactionSentinel.d.ts.map +1 -0
  26. package/dist/monitoring/CompactionSentinel.js +262 -0
  27. package/dist/monitoring/CompactionSentinel.js.map +1 -0
  28. package/dist/monitoring/SessionWatchdog.d.ts +26 -0
  29. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  30. package/dist/monitoring/SessionWatchdog.js +204 -26
  31. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  32. package/dist/monitoring/probes/MessagingProbe.d.ts +4 -0
  33. package/dist/monitoring/probes/MessagingProbe.d.ts.map +1 -1
  34. package/dist/monitoring/probes/MessagingProbe.js +24 -8
  35. package/dist/monitoring/probes/MessagingProbe.js.map +1 -1
  36. package/dist/server/AgentServer.d.ts +1 -0
  37. package/dist/server/AgentServer.d.ts.map +1 -1
  38. package/dist/server/AgentServer.js +1 -0
  39. package/dist/server/AgentServer.js.map +1 -1
  40. package/dist/server/routes.d.ts +5 -0
  41. package/dist/server/routes.d.ts.map +1 -1
  42. package/dist/server/routes.js +92 -2
  43. package/dist/server/routes.js.map +1 -1
  44. package/dist/threadline/adapters/RESTServer.d.ts +7 -1
  45. package/dist/threadline/adapters/RESTServer.d.ts.map +1 -1
  46. package/dist/threadline/adapters/RESTServer.js +62 -1
  47. package/dist/threadline/adapters/RESTServer.js.map +1 -1
  48. package/dist/threadline/relay/OfflineQueue.js +1 -1
  49. package/dist/threadline/relay/OfflineQueue.js.map +1 -1
  50. package/package.json +1 -1
  51. package/scripts/check-upgrade-guide.js +9 -115
  52. package/scripts/upgrade-guide-validator.mjs +221 -0
  53. package/src/data/builtin-manifest.json +52 -52
  54. package/src/templates/scripts/imessage-reply.sh +16 -3
  55. package/src/templates/scripts/slack-reply.sh +10 -0
  56. package/src/templates/scripts/telegram-reply.sh +11 -0
  57. package/src/templates/scripts/whatsapp-reply.sh +10 -0
  58. package/upgrades/0.28.34.md +17 -0
  59. package/upgrades/0.28.36.md +40 -0
  60. package/upgrades/0.28.37.md +69 -0
  61. package/upgrades/0.28.38.md +41 -0
  62. package/upgrades/0.28.39.md +29 -0
  63. package/upgrades/0.28.40.md +32 -0
  64. package/upgrades/0.28.41.md +41 -0
  65. package/upgrades/NEXT.md +18 -0
  66. package/upgrades/0.28.10.md +0 -19
  67. package/upgrades/0.28.11.md +0 -19
  68. package/upgrades/0.28.13.md +0 -11
  69. package/upgrades/0.28.15.md +0 -11
  70. package/upgrades/0.28.18.md +0 -12
  71. package/upgrades/0.28.20.md +0 -19
  72. package/upgrades/0.28.21.md +0 -23
  73. package/upgrades/0.28.22.md +0 -23
  74. package/upgrades/0.28.23.md +0 -19
  75. package/upgrades/0.28.24.md +0 -18
  76. package/upgrades/0.28.25.md +0 -21
  77. package/upgrades/0.28.26.md +0 -20
  78. package/upgrades/0.28.27.md +0 -20
  79. package/upgrades/0.28.28.md +0 -20
  80. package/upgrades/0.28.30.md +0 -25
  81. package/upgrades/0.28.31.md +0 -38
  82. package/upgrades/0.28.32.md +0 -22
  83. package/upgrades/0.28.33.md +0 -22
  84. package/upgrades/0.28.5.md +0 -17
  85. package/upgrades/0.28.7.md +0 -24
  86. package/upgrades/0.28.8.md +0 -21
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2PH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA81CD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAupItE;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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2PH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA81CD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4uItE;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"}
@@ -1789,23 +1789,55 @@ export async function startServer(options) {
1789
1789
  _topicResumeMap = new TopicResumeMap(config.stateDir, config.sessions.projectDir, config.sessions.tmuxPath);
1790
1790
  _projectDir = config.sessions.projectDir;
1791
1791
  // Shared intelligence provider — lightweight LLM for internal classification tasks.
1792
- // Prefer Anthropic API (faster, no tmux) → Claude CLI fallback.
1792
+ // Priority: Claude CLI subscription (zero extra cost, default) → Anthropic API (explicit opt-in)
1793
1793
  // Components that need LLM intelligence (Sentinel, TelegramAdapter, etc.) share this.
1794
+ //
1795
+ // Rationale: Instar must not depend on an API key. The subscription path is the default so
1796
+ // every agent gets LLM-gated features out of the box. Users who prefer direct API access can
1797
+ // set `intelligenceProvider: "anthropic-api"` in config.json.
1794
1798
  let sharedIntelligence;
1795
- try {
1796
- const apiProvider = AnthropicIntelligenceProvider.fromEnv();
1797
- if (apiProvider) {
1798
- sharedIntelligence = apiProvider;
1799
+ const explicitIntelligenceProvider = config.intelligenceProvider;
1800
+ let intelligenceSource = 'none';
1801
+ if (explicitIntelligenceProvider === 'anthropic-api') {
1802
+ try {
1803
+ const apiProvider = AnthropicIntelligenceProvider.fromEnv();
1804
+ if (apiProvider) {
1805
+ sharedIntelligence = apiProvider;
1806
+ intelligenceSource = 'Anthropic API (explicit opt-in)';
1807
+ }
1808
+ else {
1809
+ console.log(pc.yellow(' intelligenceProvider: "anthropic-api" set but ANTHROPIC_API_KEY not found — falling back to Claude CLI'));
1810
+ }
1799
1811
  }
1812
+ catch { /* no API key available */ }
1800
1813
  }
1801
- catch { /* no API key available */ }
1802
1814
  if (!sharedIntelligence) {
1803
1815
  try {
1804
1816
  sharedIntelligence = new ClaudeCliIntelligenceProvider(config.sessions.claudePath);
1817
+ intelligenceSource = 'Claude CLI subscription';
1805
1818
  }
1806
1819
  catch { /* CLI not available */ }
1807
1820
  }
1821
+ if (!sharedIntelligence && explicitIntelligenceProvider !== 'anthropic-api') {
1822
+ // Last resort: if user has API key but didn't explicitly opt in, use it rather than
1823
+ // leaving the agent flying blind. We prefer subscription, but degrading to heuristics
1824
+ // is worse than using whatever LLM is available.
1825
+ try {
1826
+ const apiProvider = AnthropicIntelligenceProvider.fromEnv();
1827
+ if (apiProvider) {
1828
+ sharedIntelligence = apiProvider;
1829
+ intelligenceSource = 'Anthropic API (CLI unavailable — last resort)';
1830
+ }
1831
+ }
1832
+ catch { /* no API key available */ }
1833
+ }
1808
1834
  _sharedIntelligence = sharedIntelligence ?? null;
1835
+ if (sharedIntelligence) {
1836
+ console.log(pc.gray(` Intelligence: ${intelligenceSource}`));
1837
+ }
1838
+ else {
1839
+ console.log(pc.yellow(' Intelligence: none (no Claude CLI, no API key) — LLM-gated features degraded'));
1840
+ }
1809
1841
  // Wire intelligence into git sync for LLM conflict resolution (Tier 1 → 2)
1810
1842
  if (gitSync && sharedIntelligence) {
1811
1843
  gitSync.setIntelligence(sharedIntelligence);
@@ -3765,15 +3797,31 @@ export async function startServer(options) {
3765
3797
  const hookEventReceiver = new HookEventReceiver({ stateDir: config.stateDir });
3766
3798
  console.log(pc.green(' Hook event receiver enabled'));
3767
3799
  // ── Compaction Resume: unified recovery for one session ──────────────
3768
- // Robust against subsystem misconfiguration: works with or without
3769
- // triageOrchestrator. If the orchestrator is available we prefer it
3770
- // (richer recovery semantics); otherwise we fall back to a direct
3771
- // tmux re-injection of the unanswered user message.
3800
+ // After compaction, the session's working context is gone. Rather than
3801
+ // replaying the user's last message (which assumes the agent still has
3802
+ // thread context), we inject a prompt telling the agent to re-read recent
3803
+ // topic messages and continue. The agent fetches its own history, so this
3804
+ // restores continuity without pretending no compaction happened.
3805
+ //
3806
+ // Note: we deliberately bypass triageOrchestrator here. Its reinject_message
3807
+ // heuristic unconditionally re-sends the last user message from topic
3808
+ // history — fine for "message lost mid-flight" stalls, wrong for compaction
3809
+ // recovery where the agent needs to re-orient first.
3772
3810
  //
3773
3811
  // Three independent triggers call into this:
3774
3812
  // 1. PreCompact hook event (Claude Code fires it — unreliable)
3775
3813
  // 2. SessionWatchdog 'compaction-idle' polling (default-enabled)
3776
3814
  // 3. POST /internal/compaction-resume (compaction-recovery.sh hook)
3815
+ // After compaction the agent needs three things: orientation, user-facing
3816
+ // transparency, and a clear handoff back to whatever they were doing.
3817
+ // (1) "read previous messages" ensures re-orientation on the current thread
3818
+ // before responding — if the agent just replies from a blank slate it
3819
+ // will answer the wrong question.
3820
+ // (2) "let the user know compaction occurred" keeps the user informed so
3821
+ // a sudden shift in tone or awareness isn't mysterious.
3822
+ // (3) "continue where you left off" tells the agent not to re-ask or
3823
+ // re-litigate, just pick up.
3824
+ const COMPACTION_RESUME_PROMPT = 'Your session just went through context compaction. Read the recent messages in this topic to re-orient, briefly let the user know compaction occurred, then continue where you left off.';
3777
3825
  const recoverCompactedSession = async (sessionName, triggerLabel) => {
3778
3826
  if (!sessionManager.isSessionAlive(sessionName))
3779
3827
  return false;
@@ -3785,17 +3833,8 @@ export async function startServer(options) {
3785
3833
  const lastMsg = history[history.length - 1];
3786
3834
  if (lastMsg?.fromUser) {
3787
3835
  console.log(`[CompactionResume] (${triggerLabel}) topic ${topicId} session "${sessionName}" has unanswered message — recovering`);
3788
- if (triageOrchestrator) {
3789
- try {
3790
- await triageOrchestrator.activate(topicId, sessionName, 'watchdog', lastMsg.text, Date.now());
3791
- return true;
3792
- }
3793
- catch (err) {
3794
- console.warn(`[CompactionResume] orchestrator failed, falling back to direct inject:`, err);
3795
- }
3796
- }
3797
- // Fallback: direct injection with topic tag so InputGuard accepts it.
3798
- const tagged = `[telegram:${topicId}] ${lastMsg.text}`;
3836
+ // Direct injection with topic tag so InputGuard accepts it.
3837
+ const tagged = `[telegram:${topicId}] ${COMPACTION_RESUME_PROMPT}`;
3799
3838
  const ok = sessionManager.injectMessage(sessionName, tagged);
3800
3839
  if (ok) {
3801
3840
  console.log(`[CompactionResume] (${triggerLabel}) direct re-inject OK for topic ${topicId}`);
@@ -3816,7 +3855,26 @@ export async function startServer(options) {
3816
3855
  }
3817
3856
  return false;
3818
3857
  };
3819
- // Trigger 1: PreCompact hook event — wired unconditionally now.
3858
+ // ── CompactionSentinel ────────────────────────────────────────────
3859
+ // Owns the full recovery lifecycle: detect → inject → verify (jsonl
3860
+ // growth) → retry on failure → finalize. Replaces the fire-and-forget
3861
+ // calls that used to live here. Dedupes across the three triggers and
3862
+ // vetoes zombie cleanup while a recovery is in flight.
3863
+ const { CompactionSentinel } = await import('../monitoring/CompactionSentinel.js');
3864
+ const compactionSentinel = new CompactionSentinel({
3865
+ recoverFn: recoverCompactedSession,
3866
+ projectDir: config.projectDir,
3867
+ getClaudeSessionId: (sessionName) => {
3868
+ const session = sessionManager.listRunningSessions()
3869
+ .find(s => s.tmuxSession === sessionName);
3870
+ return session?.claudeSessionId;
3871
+ },
3872
+ },
3873
+ // Defaults are production-sensible; override here only if needed.
3874
+ {});
3875
+ sessionManager.setActiveRecoveryChecker(session => compactionSentinel.isRecoveryActive(session.tmuxSession));
3876
+ console.log(pc.green(' CompactionSentinel enabled (verified recovery lifecycle)'));
3877
+ // Trigger 1: PreCompact hook event — report to sentinel.
3820
3878
  hookEventReceiver.on('PreCompact', () => {
3821
3879
  // Delay to let compaction + recovery hooks finish
3822
3880
  setTimeout(() => {
@@ -3824,22 +3882,26 @@ export async function startServer(options) {
3824
3882
  return;
3825
3883
  const topicSessions = telegram.getAllTopicSessions();
3826
3884
  for (const [, sessionName] of topicSessions) {
3827
- recoverCompactedSession(sessionName, 'PreCompact').catch(() => { });
3885
+ compactionSentinel.report(sessionName, 'PreCompact');
3828
3886
  }
3829
3887
  }, 10_000);
3830
3888
  });
3831
3889
  console.log(pc.green(' Compaction auto-resume wired (PreCompact hook event)'));
3832
- // Trigger 2: Watchdog 'compaction-idle' polling — wired unconditionally.
3890
+ // Trigger 2: Watchdog 'compaction-idle' polling — report to sentinel.
3833
3891
  if (watchdog) {
3834
3892
  watchdog.on('compaction-idle', (sessionName) => {
3835
- recoverCompactedSession(sessionName, 'watchdog-poll').catch(() => { });
3893
+ compactionSentinel.report(sessionName, 'watchdog-poll');
3836
3894
  });
3837
3895
  console.log(pc.green(' Compaction auto-resume wired (watchdog poll)'));
3838
3896
  }
3839
- // Trigger 3: stash the recovery function on globalThis so the HTTP route
3840
- // (registered later in AgentServer) and the compaction-recovery.sh hook
3841
- // can invoke it via POST /internal/compaction-resume.
3842
- globalThis.__instarCompactionRecover = recoverCompactedSession;
3897
+ // Trigger 3: stash a function on globalThis so the HTTP route (registered
3898
+ // later in AgentServer) and the compaction-recovery.sh hook can invoke it
3899
+ // via POST /internal/compaction-resume. Routes into the sentinel so the
3900
+ // dedupe/verify/retry lifecycle applies to this path too.
3901
+ globalThis.__instarCompactionRecover = (sessionName, triggerLabel) => {
3902
+ compactionSentinel.report(sessionName, triggerLabel || 'recovery-hook');
3903
+ return Promise.resolve(true);
3904
+ };
3843
3905
  // Subagent Tracker — monitors subagent lifecycle via hook events
3844
3906
  const { SubagentTracker } = await import('../monitoring/SubagentTracker.js');
3845
3907
  const subagentTracker = new SubagentTracker({ stateDir: config.stateDir });
@@ -3983,7 +4045,6 @@ export async function startServer(options) {
3983
4045
  const channelId = _slack.getChannelForSession(sessionName);
3984
4046
  if (!channelId)
3985
4047
  return false;
3986
- const syntheticId = slackChannelToSyntheticId(channelId);
3987
4048
  const slackLogPath = path.join(config.stateDir, 'slack-messages.jsonl');
3988
4049
  let lastUserMsg = null;
3989
4050
  try {
@@ -4004,18 +4065,9 @@ export async function startServer(options) {
4004
4065
  catch { /* no log */ }
4005
4066
  if (!lastUserMsg)
4006
4067
  return false;
4007
- const text = lastUserMsg.text || 'message after compaction';
4008
4068
  console.log(`[CompactionResume] (${triggerLabel}) Slack channel ${channelId} has unanswered message — recovering`);
4009
- if (triageOrchestrator) {
4010
- try {
4011
- await triageOrchestrator.activate(syntheticId, sessionName, 'watchdog', text, Date.now());
4012
- return true;
4013
- }
4014
- catch (err) {
4015
- console.warn(`[CompactionResume] Slack orchestrator failed, falling back to direct inject:`, err);
4016
- }
4017
- }
4018
- const ok = sessionManager.injectMessage(sessionName, text);
4069
+ // Direct injection — bypass triage (see comment on recoverCompactedSession).
4070
+ const ok = sessionManager.injectMessage(sessionName, COMPACTION_RESUME_PROMPT);
4019
4071
  if (ok) {
4020
4072
  console.log(`[CompactionResume] (${triggerLabel}) Slack direct re-inject OK for channel ${channelId}`);
4021
4073
  return true;
@@ -5022,23 +5074,43 @@ export async function startServer(options) {
5022
5074
  // Non-fatal — agent works without Threadline
5023
5075
  console.warn(pc.yellow(` Threadline: failed to bootstrap — ${err instanceof Error ? err.message : String(err)}`));
5024
5076
  }
5025
- // Response Review Pipeline (Coherence Gate)evaluates agent responses before delivery
5077
+ // Messaging Tone Gate — always-on tone check on outbound messaging routes.
5078
+ // Uses the shared IntelligenceProvider (Claude CLI subscription by default,
5079
+ // Anthropic API if key is set). No opt-in. Catches CLI commands, file paths,
5080
+ // config syntax, and other technical leakage in agent-to-user messages.
5081
+ let messagingToneGate;
5082
+ if (sharedIntelligence) {
5083
+ const { MessagingToneGate } = await import('../core/MessagingToneGate.js');
5084
+ messagingToneGate = new MessagingToneGate(sharedIntelligence);
5085
+ console.log(pc.green(' Messaging tone gate: active (Haiku via shared IntelligenceProvider)'));
5086
+ }
5087
+ else {
5088
+ console.log(pc.yellow(' Messaging tone gate: inactive (no IntelligenceProvider available)'));
5089
+ }
5090
+ // Response Review Pipeline (Coherence Gate) — evaluates agent responses before delivery.
5091
+ // Prefers the shared IntelligenceProvider (subscription-compatible) so the gate works
5092
+ // even without ANTHROPIC_API_KEY. Falls back to direct Anthropic API if a key is set
5093
+ // and no intelligence is available.
5026
5094
  let responseReviewGate;
5027
5095
  if (config.responseReview?.enabled) {
5028
- const anthropicKey = process.env['ANTHROPIC_API_KEY']?.trim();
5029
- if (anthropicKey) {
5096
+ const anthropicKey = process.env['ANTHROPIC_API_KEY']?.trim() ?? '';
5097
+ if (sharedIntelligence || anthropicKey) {
5030
5098
  const { CoherenceGate } = await import('../core/CoherenceGate.js');
5031
5099
  responseReviewGate = new CoherenceGate({
5032
5100
  config: config.responseReview,
5033
5101
  stateDir: config.stateDir,
5034
5102
  apiKey: anthropicKey,
5103
+ intelligence: sharedIntelligence,
5035
5104
  relationships: relationships ?? undefined,
5036
5105
  adaptiveTrust: adaptiveTrust ?? undefined,
5037
5106
  });
5038
- console.log(pc.green(` Response review pipeline: enabled (${Object.keys(config.responseReview.reviewers ?? {}).length} reviewers configured)`));
5107
+ const backend = sharedIntelligence
5108
+ ? 'via shared IntelligenceProvider'
5109
+ : 'via Anthropic API (direct)';
5110
+ console.log(pc.green(` Response review pipeline: enabled ${backend} (${Object.keys(config.responseReview.reviewers ?? {}).length} reviewers configured)`));
5039
5111
  }
5040
5112
  else {
5041
- console.warn(pc.yellow(` Response review pipeline: configured but ANTHROPIC_API_KEY not set`));
5113
+ console.warn(pc.yellow(` Response review pipeline: configured but no IntelligenceProvider or ANTHROPIC_API_KEY available`));
5042
5114
  }
5043
5115
  }
5044
5116
  // Feature Registry (Consent & Discovery Framework — Phase 1)
@@ -5114,7 +5186,7 @@ export async function startServer(options) {
5114
5186
  return { content: lines.join('\n'), truncated: false, elapsedMs: Date.now() - start };
5115
5187
  }, { description: 'Feature discovery state and behavioral contract summary' });
5116
5188
  }
5117
- 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, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, unifiedTrust, liveConfig });
5189
+ 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, messageRouter, summarySentinel, spawnManager, systemReviewer, capabilityMapper, selfKnowledgeTree, coverageAuditor, topicResumeMap: _topicResumeMap ?? undefined, autonomyManager, trustElevationTracker, autonomousEvolution, coordinator: coordinator.enabled ? coordinator : undefined, localSigningKeyPem, whatsapp: whatsappAdapter, slack: slackAdapter, imessage: imessageAdapter, whatsappBusinessBackend, messageBridge, hookEventReceiver, worktreeMonitor, subagentTracker, instructionsVerifier, handshakeManager: threadlineHandshake, threadlineRouter, threadlineRelayClient, threadlineReplyWaiters, listenerManager: listenerManager ?? undefined, responseReviewGate, messagingToneGate, telemetryHeartbeat, pasteManager, featureRegistry, discoveryEvaluator, unifiedTrust, liveConfig });
5118
5190
  await server.start();
5119
5191
  // Connect DegradationReporter downstream systems now that everything is initialized.
5120
5192
  // Any degradation events queued during startup will drain to feedback + telegram.