instar 0.28.76 → 0.28.78

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 (448) hide show
  1. package/dashboard/index.html +486 -0
  2. package/dist/cli.js +5 -8
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/discovery.d.ts.map +1 -1
  5. package/dist/commands/discovery.js +2 -2
  6. package/dist/commands/discovery.js.map +1 -1
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +22 -4
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/job.d.ts.map +1 -1
  11. package/dist/commands/job.js +2 -2
  12. package/dist/commands/job.js.map +1 -1
  13. package/dist/commands/ledgerCleanup.d.ts.map +1 -1
  14. package/dist/commands/ledgerCleanup.js +2 -2
  15. package/dist/commands/ledgerCleanup.js.map +1 -1
  16. package/dist/commands/listener.d.ts.map +1 -1
  17. package/dist/commands/listener.js +7 -12
  18. package/dist/commands/listener.js.map +1 -1
  19. package/dist/commands/nuke.d.ts.map +1 -1
  20. package/dist/commands/nuke.js +11 -21
  21. package/dist/commands/nuke.js.map +1 -1
  22. package/dist/commands/server.d.ts.map +1 -1
  23. package/dist/commands/server.js +79 -5
  24. package/dist/commands/server.js.map +1 -1
  25. package/dist/commands/setup.d.ts.map +1 -1
  26. package/dist/commands/setup.js +11 -15
  27. package/dist/commands/setup.js.map +1 -1
  28. package/dist/commands/slack-cli.d.ts.map +1 -1
  29. package/dist/commands/slack-cli.js +5 -8
  30. package/dist/commands/slack-cli.js.map +1 -1
  31. package/dist/commands/whatsapp.d.ts.map +1 -1
  32. package/dist/commands/whatsapp.js +2 -2
  33. package/dist/commands/whatsapp.js.map +1 -1
  34. package/dist/commands/worktree.d.ts.map +1 -1
  35. package/dist/commands/worktree.js +2 -2
  36. package/dist/commands/worktree.js.map +1 -1
  37. package/dist/core/AgentConnector.d.ts.map +1 -1
  38. package/dist/core/AgentConnector.js +9 -10
  39. package/dist/core/AgentConnector.js.map +1 -1
  40. package/dist/core/AgentRegistry.d.ts.map +1 -1
  41. package/dist/core/AgentRegistry.js +3 -4
  42. package/dist/core/AgentRegistry.js.map +1 -1
  43. package/dist/core/AutoDispatcher.d.ts.map +1 -1
  44. package/dist/core/AutoDispatcher.js +2 -2
  45. package/dist/core/AutoDispatcher.js.map +1 -1
  46. package/dist/core/AutoUpdater.d.ts.map +1 -1
  47. package/dist/core/AutoUpdater.js +2 -2
  48. package/dist/core/AutoUpdater.js.map +1 -1
  49. package/dist/core/AutonomousEvolution.d.ts.map +1 -1
  50. package/dist/core/AutonomousEvolution.js +2 -2
  51. package/dist/core/AutonomousEvolution.js.map +1 -1
  52. package/dist/core/BackupManager.d.ts.map +1 -1
  53. package/dist/core/BackupManager.js +2 -2
  54. package/dist/core/BackupManager.js.map +1 -1
  55. package/dist/core/BranchManager.d.ts.map +1 -1
  56. package/dist/core/BranchManager.js +3 -3
  57. package/dist/core/BranchManager.js.map +1 -1
  58. package/dist/core/CaffeinateManager.d.ts.map +1 -1
  59. package/dist/core/CaffeinateManager.js +2 -2
  60. package/dist/core/CaffeinateManager.js.map +1 -1
  61. package/dist/core/DeferredDispatchTracker.d.ts.map +1 -1
  62. package/dist/core/DeferredDispatchTracker.js +2 -2
  63. package/dist/core/DeferredDispatchTracker.js.map +1 -1
  64. package/dist/core/DispatchManager.d.ts.map +1 -1
  65. package/dist/core/DispatchManager.js +3 -4
  66. package/dist/core/DispatchManager.js.map +1 -1
  67. package/dist/core/EvolutionManager.d.ts.map +1 -1
  68. package/dist/core/EvolutionManager.js +2 -2
  69. package/dist/core/EvolutionManager.js.map +1 -1
  70. package/dist/core/ExecutionJournal.d.ts.map +1 -1
  71. package/dist/core/ExecutionJournal.js +2 -2
  72. package/dist/core/ExecutionJournal.js.map +1 -1
  73. package/dist/core/FeedbackManager.d.ts.map +1 -1
  74. package/dist/core/FeedbackManager.js +2 -2
  75. package/dist/core/FeedbackManager.js.map +1 -1
  76. package/dist/core/FileClassifier.d.ts.map +1 -1
  77. package/dist/core/FileClassifier.js +8 -17
  78. package/dist/core/FileClassifier.js.map +1 -1
  79. package/dist/core/ForegroundRestartWatcher.d.ts.map +1 -1
  80. package/dist/core/ForegroundRestartWatcher.js +3 -4
  81. package/dist/core/ForegroundRestartWatcher.js.map +1 -1
  82. package/dist/core/GitStateManager.d.ts.map +1 -1
  83. package/dist/core/GitStateManager.js +3 -12
  84. package/dist/core/GitStateManager.js.map +1 -1
  85. package/dist/core/GitSync.d.ts.map +1 -1
  86. package/dist/core/GitSync.js +6 -6
  87. package/dist/core/GitSync.js.map +1 -1
  88. package/dist/core/GlobalInstallCleanup.d.ts.map +1 -1
  89. package/dist/core/GlobalInstallCleanup.js +3 -4
  90. package/dist/core/GlobalInstallCleanup.js.map +1 -1
  91. package/dist/core/GlobalSecretStore.d.ts.map +1 -1
  92. package/dist/core/GlobalSecretStore.js +3 -4
  93. package/dist/core/GlobalSecretStore.js.map +1 -1
  94. package/dist/core/HandoffManager.d.ts.map +1 -1
  95. package/dist/core/HandoffManager.js +5 -5
  96. package/dist/core/HandoffManager.js.map +1 -1
  97. package/dist/core/JargonDetector.d.ts +28 -0
  98. package/dist/core/JargonDetector.d.ts.map +1 -0
  99. package/dist/core/JargonDetector.js +59 -0
  100. package/dist/core/JargonDetector.js.map +1 -0
  101. package/dist/core/LedgerSessionRegistry.d.ts.map +1 -1
  102. package/dist/core/LedgerSessionRegistry.js +2 -2
  103. package/dist/core/LedgerSessionRegistry.js.map +1 -1
  104. package/dist/core/MachineIdentity.d.ts.map +1 -1
  105. package/dist/core/MachineIdentity.js +2 -2
  106. package/dist/core/MachineIdentity.js.map +1 -1
  107. package/dist/core/MessagingToneGate.d.ts +42 -5
  108. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  109. package/dist/core/MessagingToneGate.js +40 -6
  110. package/dist/core/MessagingToneGate.js.map +1 -1
  111. package/dist/core/ParallelDevWiring.d.ts.map +1 -1
  112. package/dist/core/ParallelDevWiring.js +3 -6
  113. package/dist/core/ParallelDevWiring.js.map +1 -1
  114. package/dist/core/PostUpdateMigrator.d.ts +26 -0
  115. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  116. package/dist/core/PostUpdateMigrator.js +249 -46
  117. package/dist/core/PostUpdateMigrator.js.map +1 -1
  118. package/dist/core/ProjectMapper.d.ts.map +1 -1
  119. package/dist/core/ProjectMapper.js +5 -11
  120. package/dist/core/ProjectMapper.js.map +1 -1
  121. package/dist/core/RelationshipManager.d.ts.map +1 -1
  122. package/dist/core/RelationshipManager.js +4 -5
  123. package/dist/core/RelationshipManager.js.map +1 -1
  124. package/dist/core/SafeGitExecutor.d.ts +11 -5
  125. package/dist/core/SafeGitExecutor.d.ts.map +1 -1
  126. package/dist/core/SafeGitExecutor.js +87 -1
  127. package/dist/core/SafeGitExecutor.js.map +1 -1
  128. package/dist/core/ScopeVerifier.d.ts.map +1 -1
  129. package/dist/core/ScopeVerifier.js +3 -6
  130. package/dist/core/ScopeVerifier.js.map +1 -1
  131. package/dist/core/SecretStore.d.ts.map +1 -1
  132. package/dist/core/SecretStore.js +2 -2
  133. package/dist/core/SecretStore.js.map +1 -1
  134. package/dist/core/SharedStateLedger.d.ts.map +1 -1
  135. package/dist/core/SharedStateLedger.js +2 -2
  136. package/dist/core/SharedStateLedger.js.map +1 -1
  137. package/dist/core/SoulManager.d.ts.map +1 -1
  138. package/dist/core/SoulManager.js +3 -4
  139. package/dist/core/SoulManager.js.map +1 -1
  140. package/dist/core/StateManager.d.ts.map +1 -1
  141. package/dist/core/StateManager.js +4 -6
  142. package/dist/core/StateManager.js.map +1 -1
  143. package/dist/core/SyncOrchestrator.d.ts.map +1 -1
  144. package/dist/core/SyncOrchestrator.js +6 -7
  145. package/dist/core/SyncOrchestrator.js.map +1 -1
  146. package/dist/core/UpdateChecker.d.ts.map +1 -1
  147. package/dist/core/UpdateChecker.js +3 -4
  148. package/dist/core/UpdateChecker.js.map +1 -1
  149. package/dist/core/UpgradeGuideProcessor.d.ts.map +1 -1
  150. package/dist/core/UpgradeGuideProcessor.js +3 -4
  151. package/dist/core/UpgradeGuideProcessor.js.map +1 -1
  152. package/dist/core/WorktreeManager.d.ts.map +1 -1
  153. package/dist/core/WorktreeManager.js +9 -14
  154. package/dist/core/WorktreeManager.js.map +1 -1
  155. package/dist/knowledge/KnowledgeManager.d.ts.map +1 -1
  156. package/dist/knowledge/KnowledgeManager.js +2 -2
  157. package/dist/knowledge/KnowledgeManager.js.map +1 -1
  158. package/dist/lifeline/ServerSupervisor.d.ts +28 -0
  159. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  160. package/dist/lifeline/ServerSupervisor.js +171 -73
  161. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  162. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  163. package/dist/lifeline/TelegramLifeline.js +10 -4
  164. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  165. package/dist/lifeline/detectLaunchdSupervised.d.ts +43 -0
  166. package/dist/lifeline/detectLaunchdSupervised.d.ts.map +1 -0
  167. package/dist/lifeline/detectLaunchdSupervised.js +106 -0
  168. package/dist/lifeline/detectLaunchdSupervised.js.map +1 -0
  169. package/dist/lifeline/droppedMessages.d.ts.map +1 -1
  170. package/dist/lifeline/droppedMessages.js +2 -2
  171. package/dist/lifeline/droppedMessages.js.map +1 -1
  172. package/dist/memory/EpisodicMemory.d.ts.map +1 -1
  173. package/dist/memory/EpisodicMemory.js +2 -2
  174. package/dist/memory/EpisodicMemory.js.map +1 -1
  175. package/dist/memory/TopicMemory.d.ts.map +1 -1
  176. package/dist/memory/TopicMemory.js +5 -8
  177. package/dist/memory/TopicMemory.js.map +1 -1
  178. package/dist/messaging/AgentTokenManager.d.ts.map +1 -1
  179. package/dist/messaging/AgentTokenManager.js +2 -2
  180. package/dist/messaging/AgentTokenManager.js.map +1 -1
  181. package/dist/messaging/DropPickup.d.ts.map +1 -1
  182. package/dist/messaging/DropPickup.js +2 -2
  183. package/dist/messaging/DropPickup.js.map +1 -1
  184. package/dist/messaging/GitSyncTransport.d.ts.map +1 -1
  185. package/dist/messaging/GitSyncTransport.js +4 -6
  186. package/dist/messaging/GitSyncTransport.js.map +1 -1
  187. package/dist/messaging/MessageStore.d.ts.map +1 -1
  188. package/dist/messaging/MessageStore.js +3 -4
  189. package/dist/messaging/MessageStore.js.map +1 -1
  190. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  191. package/dist/messaging/TelegramAdapter.js +5 -8
  192. package/dist/messaging/TelegramAdapter.js.map +1 -1
  193. package/dist/messaging/backends/BaileysBackend.d.ts.map +1 -1
  194. package/dist/messaging/backends/BaileysBackend.js +3 -4
  195. package/dist/messaging/backends/BaileysBackend.js.map +1 -1
  196. package/dist/messaging/local-tone-check.d.ts +61 -0
  197. package/dist/messaging/local-tone-check.d.ts.map +1 -0
  198. package/dist/messaging/local-tone-check.js +78 -0
  199. package/dist/messaging/local-tone-check.js.map +1 -0
  200. package/dist/messaging/pending-relay-store.d.ts +153 -0
  201. package/dist/messaging/pending-relay-store.d.ts.map +1 -0
  202. package/dist/messaging/pending-relay-store.js +351 -0
  203. package/dist/messaging/pending-relay-store.js.map +1 -0
  204. package/dist/messaging/secret-patterns.d.ts +35 -0
  205. package/dist/messaging/secret-patterns.d.ts.map +1 -0
  206. package/dist/messaging/secret-patterns.js +70 -0
  207. package/dist/messaging/secret-patterns.js.map +1 -0
  208. package/dist/messaging/shared/EncryptedAuthStore.d.ts.map +1 -1
  209. package/dist/messaging/shared/EncryptedAuthStore.js +3 -4
  210. package/dist/messaging/shared/EncryptedAuthStore.js.map +1 -1
  211. package/dist/messaging/shared/MessageLogger.d.ts.map +1 -1
  212. package/dist/messaging/shared/MessageLogger.js +2 -2
  213. package/dist/messaging/shared/MessageLogger.js.map +1 -1
  214. package/dist/messaging/shared/PrivacyConsent.d.ts.map +1 -1
  215. package/dist/messaging/shared/PrivacyConsent.js +2 -2
  216. package/dist/messaging/shared/PrivacyConsent.js.map +1 -1
  217. package/dist/messaging/shared/SessionChannelRegistry.d.ts.map +1 -1
  218. package/dist/messaging/shared/SessionChannelRegistry.js +2 -2
  219. package/dist/messaging/shared/SessionChannelRegistry.js.map +1 -1
  220. package/dist/messaging/system-templates.d.ts +87 -0
  221. package/dist/messaging/system-templates.d.ts.map +1 -0
  222. package/dist/messaging/system-templates.js +236 -0
  223. package/dist/messaging/system-templates.js.map +1 -0
  224. package/dist/messaging/whoami-cache.d.ts +66 -0
  225. package/dist/messaging/whoami-cache.d.ts.map +1 -0
  226. package/dist/messaging/whoami-cache.js +149 -0
  227. package/dist/messaging/whoami-cache.js.map +1 -0
  228. package/dist/moltbridge/ProfileCompiler.d.ts.map +1 -1
  229. package/dist/moltbridge/ProfileCompiler.js +13 -7
  230. package/dist/moltbridge/ProfileCompiler.js.map +1 -1
  231. package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
  232. package/dist/monitoring/CommitmentTracker.js +2 -2
  233. package/dist/monitoring/CommitmentTracker.js.map +1 -1
  234. package/dist/monitoring/CredentialProvider.d.ts.map +1 -1
  235. package/dist/monitoring/CredentialProvider.js +2 -2
  236. package/dist/monitoring/CredentialProvider.js.map +1 -1
  237. package/dist/monitoring/DegradationReporter.d.ts +41 -0
  238. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  239. package/dist/monitoring/DegradationReporter.js +96 -4
  240. package/dist/monitoring/DegradationReporter.js.map +1 -1
  241. package/dist/monitoring/HealthChecker.d.ts.map +1 -1
  242. package/dist/monitoring/HealthChecker.js +2 -2
  243. package/dist/monitoring/HealthChecker.js.map +1 -1
  244. package/dist/monitoring/HookEventReceiver.d.ts.map +1 -1
  245. package/dist/monitoring/HookEventReceiver.js +2 -2
  246. package/dist/monitoring/HookEventReceiver.js.map +1 -1
  247. package/dist/monitoring/InstructionsVerifier.d.ts.map +1 -1
  248. package/dist/monitoring/InstructionsVerifier.js +2 -2
  249. package/dist/monitoring/InstructionsVerifier.js.map +1 -1
  250. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  251. package/dist/monitoring/PresenceProxy.js +5 -8
  252. package/dist/monitoring/PresenceProxy.js.map +1 -1
  253. package/dist/monitoring/QuotaTracker.d.ts.map +1 -1
  254. package/dist/monitoring/QuotaTracker.js +2 -2
  255. package/dist/monitoring/QuotaTracker.js.map +1 -1
  256. package/dist/monitoring/SessionMigrator.d.ts.map +1 -1
  257. package/dist/monitoring/SessionMigrator.js +2 -2
  258. package/dist/monitoring/SessionMigrator.js.map +1 -1
  259. package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
  260. package/dist/monitoring/SessionRecovery.js +2 -2
  261. package/dist/monitoring/SessionRecovery.js.map +1 -1
  262. package/dist/monitoring/TelemetryAuth.d.ts.map +1 -1
  263. package/dist/monitoring/TelemetryAuth.js +3 -4
  264. package/dist/monitoring/TelemetryAuth.js.map +1 -1
  265. package/dist/monitoring/TokenLedger.d.ts +130 -0
  266. package/dist/monitoring/TokenLedger.d.ts.map +1 -0
  267. package/dist/monitoring/TokenLedger.js +523 -0
  268. package/dist/monitoring/TokenLedger.js.map +1 -0
  269. package/dist/monitoring/TokenLedgerPoller.d.ts +26 -0
  270. package/dist/monitoring/TokenLedgerPoller.d.ts.map +1 -0
  271. package/dist/monitoring/TokenLedgerPoller.js +44 -0
  272. package/dist/monitoring/TokenLedgerPoller.js.map +1 -0
  273. package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -1
  274. package/dist/monitoring/TriageOrchestrator.js +3 -4
  275. package/dist/monitoring/TriageOrchestrator.js.map +1 -1
  276. package/dist/monitoring/WorktreeReaper.d.ts.map +1 -1
  277. package/dist/monitoring/WorktreeReaper.js +5 -7
  278. package/dist/monitoring/WorktreeReaper.js.map +1 -1
  279. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts +83 -0
  280. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts.map +1 -0
  281. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js +218 -0
  282. package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js.map +1 -0
  283. package/dist/monitoring/delivery-failure-sentinel.d.ts +177 -0
  284. package/dist/monitoring/delivery-failure-sentinel.d.ts.map +1 -0
  285. package/dist/monitoring/delivery-failure-sentinel.js +598 -0
  286. package/dist/monitoring/delivery-failure-sentinel.js.map +1 -0
  287. package/dist/monitoring/probes/PlatformProbe.d.ts.map +1 -1
  288. package/dist/monitoring/probes/PlatformProbe.js +3 -4
  289. package/dist/monitoring/probes/PlatformProbe.js.map +1 -1
  290. package/dist/monitoring/templates-drift-verifier.d.ts +109 -0
  291. package/dist/monitoring/templates-drift-verifier.d.ts.map +1 -0
  292. package/dist/monitoring/templates-drift-verifier.js +324 -0
  293. package/dist/monitoring/templates-drift-verifier.js.map +1 -0
  294. package/dist/paste/PasteManager.d.ts.map +1 -1
  295. package/dist/paste/PasteManager.js +5 -8
  296. package/dist/paste/PasteManager.js.map +1 -1
  297. package/dist/publishing/PrivateViewer.d.ts.map +1 -1
  298. package/dist/publishing/PrivateViewer.js +2 -2
  299. package/dist/publishing/PrivateViewer.js.map +1 -1
  300. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  301. package/dist/scheduler/JobScheduler.js +2 -2
  302. package/dist/scheduler/JobScheduler.js.map +1 -1
  303. package/dist/server/AgentServer.d.ts +22 -0
  304. package/dist/server/AgentServer.d.ts.map +1 -1
  305. package/dist/server/AgentServer.js +199 -1
  306. package/dist/server/AgentServer.js.map +1 -1
  307. package/dist/server/WebSocketManager.d.ts +11 -0
  308. package/dist/server/WebSocketManager.d.ts.map +1 -1
  309. package/dist/server/WebSocketManager.js +28 -0
  310. package/dist/server/WebSocketManager.js.map +1 -1
  311. package/dist/server/boot-id.d.ts +58 -0
  312. package/dist/server/boot-id.d.ts.map +1 -0
  313. package/dist/server/boot-id.js +121 -0
  314. package/dist/server/boot-id.js.map +1 -0
  315. package/dist/server/middleware.d.ts +14 -1
  316. package/dist/server/middleware.d.ts.map +1 -1
  317. package/dist/server/middleware.js +81 -1
  318. package/dist/server/middleware.js.map +1 -1
  319. package/dist/server/routes.d.ts +76 -0
  320. package/dist/server/routes.d.ts.map +1 -1
  321. package/dist/server/routes.js +626 -11
  322. package/dist/server/routes.js.map +1 -1
  323. package/dist/threadline/AgentDiscovery.d.ts.map +1 -1
  324. package/dist/threadline/AgentDiscovery.js +2 -2
  325. package/dist/threadline/AgentDiscovery.js.map +1 -1
  326. package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
  327. package/dist/threadline/AgentTrustManager.js +2 -2
  328. package/dist/threadline/AgentTrustManager.js.map +1 -1
  329. package/dist/threadline/BackfillCore.d.ts +70 -0
  330. package/dist/threadline/BackfillCore.d.ts.map +1 -0
  331. package/dist/threadline/BackfillCore.js +117 -0
  332. package/dist/threadline/BackfillCore.js.map +1 -0
  333. package/dist/threadline/CircuitBreaker.d.ts.map +1 -1
  334. package/dist/threadline/CircuitBreaker.js +2 -2
  335. package/dist/threadline/CircuitBreaker.js.map +1 -1
  336. package/dist/threadline/ComputeMeter.d.ts.map +1 -1
  337. package/dist/threadline/ComputeMeter.js +2 -2
  338. package/dist/threadline/ComputeMeter.js.map +1 -1
  339. package/dist/threadline/ContextThreadMap.d.ts.map +1 -1
  340. package/dist/threadline/ContextThreadMap.js +2 -2
  341. package/dist/threadline/ContextThreadMap.js.map +1 -1
  342. package/dist/threadline/HeartbeatWatchdog.d.ts +78 -0
  343. package/dist/threadline/HeartbeatWatchdog.d.ts.map +1 -0
  344. package/dist/threadline/HeartbeatWatchdog.js +212 -0
  345. package/dist/threadline/HeartbeatWatchdog.js.map +1 -0
  346. package/dist/threadline/HeartbeatWriter.d.ts +79 -0
  347. package/dist/threadline/HeartbeatWriter.d.ts.map +1 -0
  348. package/dist/threadline/HeartbeatWriter.js +109 -0
  349. package/dist/threadline/HeartbeatWriter.js.map +1 -0
  350. package/dist/threadline/InvitationManager.d.ts.map +1 -1
  351. package/dist/threadline/InvitationManager.js +2 -2
  352. package/dist/threadline/InvitationManager.js.map +1 -1
  353. package/dist/threadline/ListenerSessionManager.d.ts +59 -0
  354. package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
  355. package/dist/threadline/ListenerSessionManager.js +79 -0
  356. package/dist/threadline/ListenerSessionManager.js.map +1 -1
  357. package/dist/threadline/MCPAuth.d.ts.map +1 -1
  358. package/dist/threadline/MCPAuth.js +2 -2
  359. package/dist/threadline/MCPAuth.js.map +1 -1
  360. package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
  361. package/dist/threadline/PipeSessionSpawner.js +3 -4
  362. package/dist/threadline/PipeSessionSpawner.js.map +1 -1
  363. package/dist/threadline/RateLimiter.d.ts.map +1 -1
  364. package/dist/threadline/RateLimiter.js +2 -2
  365. package/dist/threadline/RateLimiter.js.map +1 -1
  366. package/dist/threadline/RelaySpawnFailureHandler.d.ts +53 -0
  367. package/dist/threadline/RelaySpawnFailureHandler.d.ts.map +1 -0
  368. package/dist/threadline/RelaySpawnFailureHandler.js +73 -0
  369. package/dist/threadline/RelaySpawnFailureHandler.js.map +1 -0
  370. package/dist/threadline/SessionLifecycle.d.ts.map +1 -1
  371. package/dist/threadline/SessionLifecycle.js +2 -2
  372. package/dist/threadline/SessionLifecycle.js.map +1 -1
  373. package/dist/threadline/SpawnLedger.d.ts +94 -0
  374. package/dist/threadline/SpawnLedger.d.ts.map +1 -0
  375. package/dist/threadline/SpawnLedger.js +194 -0
  376. package/dist/threadline/SpawnLedger.js.map +1 -0
  377. package/dist/threadline/SpawnNonce.d.ts +49 -0
  378. package/dist/threadline/SpawnNonce.d.ts.map +1 -0
  379. package/dist/threadline/SpawnNonce.js +99 -0
  380. package/dist/threadline/SpawnNonce.js.map +1 -0
  381. package/dist/threadline/TelegramBridge.d.ts +140 -0
  382. package/dist/threadline/TelegramBridge.d.ts.map +1 -0
  383. package/dist/threadline/TelegramBridge.js +224 -0
  384. package/dist/threadline/TelegramBridge.js.map +1 -0
  385. package/dist/threadline/TelegramBridgeConfig.d.ts +79 -0
  386. package/dist/threadline/TelegramBridgeConfig.d.ts.map +1 -0
  387. package/dist/threadline/TelegramBridgeConfig.js +168 -0
  388. package/dist/threadline/TelegramBridgeConfig.js.map +1 -0
  389. package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
  390. package/dist/threadline/ThreadlineBootstrap.js +2 -2
  391. package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
  392. package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
  393. package/dist/threadline/ThreadlineMCPServer.js +5 -0
  394. package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
  395. package/dist/threadline/ThreadlineObservability.d.ts +95 -0
  396. package/dist/threadline/ThreadlineObservability.d.ts.map +1 -0
  397. package/dist/threadline/ThreadlineObservability.js +310 -0
  398. package/dist/threadline/ThreadlineObservability.js.map +1 -0
  399. package/dist/threadline/WakeSocketServer.d.ts.map +1 -1
  400. package/dist/threadline/WakeSocketServer.js +3 -4
  401. package/dist/threadline/WakeSocketServer.js.map +1 -1
  402. package/dist/threadline/listener-daemon.d.ts.map +1 -1
  403. package/dist/threadline/listener-daemon.js +3 -4
  404. package/dist/threadline/listener-daemon.js.map +1 -1
  405. package/dist/users/UserManager.d.ts.map +1 -1
  406. package/dist/users/UserManager.js +2 -2
  407. package/dist/users/UserManager.js.map +1 -1
  408. package/dist/users/UserOnboarding.d.ts.map +1 -1
  409. package/dist/users/UserOnboarding.js +2 -2
  410. package/dist/users/UserOnboarding.js.map +1 -1
  411. package/dist/utils/jsonl-rotation.d.ts.map +1 -1
  412. package/dist/utils/jsonl-rotation.js +2 -2
  413. package/dist/utils/jsonl-rotation.js.map +1 -1
  414. package/package.json +1 -1
  415. package/scripts/analyze-release.js +7 -12
  416. package/scripts/check-contract-evidence.js +27 -10
  417. package/scripts/fix-better-sqlite3.cjs +0 -2
  418. package/scripts/instar-dev-precommit.js +0 -2
  419. package/scripts/lint-no-direct-destructive.js +24 -4
  420. package/scripts/lint-template-sha-history.ts +183 -0
  421. package/scripts/migrate-incident-2026-04-17.mjs +2 -2
  422. package/scripts/run-migration.js +500 -0
  423. package/scripts/test-bootstrap-relay.mjs +2 -2
  424. package/scripts/threadline-bridge-backfill.mjs +379 -0
  425. package/scripts/verify-deployed-templates.ts +87 -0
  426. package/src/data/builtin-manifest.json +140 -132
  427. package/src/templates/scripts/git-sync-gate.sh +0 -4
  428. package/src/templates/scripts/telegram-reply.sh +318 -13
  429. package/upgrades/0.28.77.md +133 -0
  430. package/upgrades/0.28.78.md +90 -0
  431. package/upgrades/side-effects/agent-health-alert-authority-routing.md +121 -0
  432. package/upgrades/side-effects/comprehensive-destructive-tool-containment-migration.md +82 -0
  433. package/upgrades/side-effects/deferral-detector-orphan-todo.md +101 -0
  434. package/upgrades/side-effects/lifeline-self-heal-hardening.md +151 -0
  435. package/upgrades/side-effects/relay-spawn-ghost-reply-phase1.md +139 -0
  436. package/upgrades/side-effects/telegram-delivery-robustness-layer-2.md +320 -0
  437. package/upgrades/side-effects/telegram-delivery-robustness-layer-3.md +202 -0
  438. package/upgrades/side-effects/telegram-delivery-robustness-layer-7.md +339 -0
  439. package/upgrades/side-effects/telegram-delivery-robustness.md +178 -0
  440. package/upgrades/side-effects/threadline-bridge-backfill.md +203 -0
  441. package/upgrades/side-effects/threadline-canonical-inbox-write.md +218 -0
  442. package/upgrades/side-effects/threadline-observability-tab.md +206 -0
  443. package/upgrades/side-effects/threadline-tg-bridge-module.md +196 -0
  444. package/upgrades/side-effects/threadline-tg-bridge-settings-surface.md +208 -0
  445. package/upgrades/side-effects/token-ledger-bounded-scan.md +230 -0
  446. package/upgrades/side-effects/token-ledger-phase1.md +123 -0
  447. package/upgrades/NEXT.md +0 -53
  448. /package/upgrades/side-effects/{telegram-lifeline-version-missing-info.md → 0.28.76.md} +0 -0
@@ -21,13 +21,15 @@
21
21
  import fs from 'node:fs';
22
22
  import path from 'node:path';
23
23
  import crypto from 'node:crypto';
24
- import { execSync } from 'node:child_process';
24
+ import { SafeGitExecutor } from './SafeGitExecutor.js';
25
25
  import { fileURLToPath } from 'node:url';
26
26
  import { TreeGenerator } from '../knowledge/TreeGenerator.js';
27
27
  import { HTTP_HOOK_TEMPLATES, buildHttpHookSettings } from '../data/http-hook-templates.js';
28
28
  import { getMigrationDefaults, applyDefaults } from '../config/ConfigDefaults.js';
29
29
  import { installBuiltinSkills } from '../commands/init.js';
30
30
  import { ELIGIBILITY_SCHEMA_SQL, ELIGIBILITY_SCHEMA_SQL_SHA256, PUSH_GATE_SH, PUSH_GATE_SH_SHA256, INSTAR_PR_GATE_WORKFLOW_YML, INSTAR_PR_GATE_WORKFLOW_YML_SHA256, PR_GATE_SETUP_MD, PR_GATE_SETUP_MD_SHA256, } from '../data/pr-gate-artifacts.js';
31
+ import { SafeFsExecutor } from './SafeFsExecutor.js';
32
+ import { DegradationReporter } from '../monitoring/DegradationReporter.js';
31
33
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
32
34
  export class PostUpdateMigrator {
33
35
  config;
@@ -485,8 +487,7 @@ export class PostUpdateMigrator {
485
487
  try {
486
488
  // Move built-in hooks to instar/ — they'll be overwritten by the current
487
489
  // migrateHooks() call anyway, but cleaning up the old location is important
488
- // safe-git-allow: incremental-migration
489
- fs.unlinkSync(oldPath);
490
+ SafeFsExecutor.safeUnlinkSync(oldPath, { operation: 'src/core/PostUpdateMigrator.ts:524' });
490
491
  }
491
492
  catch {
492
493
  // If we can't remove, it's not critical — the new hooks will be written
@@ -1316,24 +1317,22 @@ The user has been talking to you (possibly for days). A generic greeting like "H
1316
1317
  }
1317
1318
  }
1318
1319
  else {
1319
- try {
1320
- const existing = fs.readFileSync(scriptPath, 'utf-8');
1321
- // Only overwrite if the existing copy is an older version (lacks 408
1322
- // handling) AND looks like the shipped version (starts with the
1323
- // shipped shebang comment). Don't stomp custom user scripts.
1324
- const looksShipped = existing.includes('telegram-reply.sh Send a message back to a Telegram topic via instar server');
1325
- const hasNewHandling = existing.includes('HTTP_CODE" = "408"');
1326
- if (looksShipped && !hasNewHandling) {
1327
- fs.writeFileSync(scriptPath, newContent, { mode: 0o755 });
1328
- result.upgraded.push('scripts/telegram-reply.sh (upgraded to HTTP 408 ambiguous-outcome handling)');
1329
- }
1330
- else {
1331
- result.skipped.push('scripts/telegram-reply.sh (already exists)');
1332
- }
1333
- }
1334
- catch (err) {
1335
- result.errors.push(`telegram-reply.sh migration: ${err instanceof Error ? err.message : String(err)}`);
1336
- }
1320
+ // SHA-based migrator (spec § Layer 1, migration). Replaces the
1321
+ // marker-string match which silently overwrote any user
1322
+ // customization that happened to keep the shipped header line.
1323
+ // The new flow is hash-only: if the on-disk SHA matches a
1324
+ // known prior shipped version, back up + overwrite; if it
1325
+ // matches the new template, no-op; otherwise leave the
1326
+ // original alone, write a `.new` candidate, and surface a
1327
+ // degradation event so the operator sees the customization
1328
+ // and can resolve it.
1329
+ this.migrateReplyScriptToPortConfig({
1330
+ scriptPath,
1331
+ newContent,
1332
+ label: 'scripts/telegram-reply.sh',
1333
+ stateDir: this.config.stateDir,
1334
+ result,
1335
+ });
1337
1336
  }
1338
1337
  }
1339
1338
  // Slack reply script — file-presence gated (migrator has no hasSlack
@@ -1933,11 +1932,11 @@ The user has been talking to you (possibly for days). A generic greeting like "H
1933
1932
  };
1934
1933
  const getRemote = (name) => {
1935
1934
  try {
1936
- // safe-git-allow: incremental-migration
1937
- return execSync(`git remote get-url ${name}`, {
1935
+ return SafeGitExecutor.readSync(['remote', 'get-url', name], {
1938
1936
  cwd: this.config.projectDir,
1939
1937
  stdio: ['ignore', 'pipe', 'ignore'],
1940
1938
  encoding: 'utf-8',
1939
+ operation: 'src/core/PostUpdateMigrator.ts:getRemote',
1941
1940
  });
1942
1941
  }
1943
1942
  catch {
@@ -3055,12 +3054,20 @@ echo "=== END IDENTITY RECOVERY ==="
3055
3054
  }
3056
3055
  getDeferralDetectorHook() {
3057
3056
  return `#!/usr/bin/env node
3058
- // Deferral detector — catches agents deferring work they could do themselves.
3059
- // PreToolUse hook for Bash commands. Scans outgoing messages for deferral patterns.
3057
+ // Deferral detector — catches agents deferring work they could do themselves
3058
+ // AND catches agents proposing orphan-TODO follow-ups with no infrastructure.
3059
+ // PreToolUse hook for Bash commands. Scans outgoing messages for the patterns.
3060
3060
  // When detected, injects a due diligence checklist (does NOT block).
3061
3061
  //
3062
- // Born from an agent saying "This is credential input I cannot do myself"
3063
- // when it already had the token available via CLI tools.
3062
+ // Born from two failure modes:
3063
+ // 1) An agent saying "This is credential input I cannot do myself" when it
3064
+ // already had the token available via CLI tools.
3065
+ // 2) An agent saying "queue for next session" / "loop back later" / "we
3066
+ // can pick this up in a follow-up" with no /schedule cron and no
3067
+ // /commit-action tracker — the orphan-TODO trap that makes
3068
+ // promised follow-through evaporate (incident: 2026-04-27, when
3069
+ // Echo proposed exactly this pattern after Layer 1 of a multi-layer
3070
+ // build shipped without infra to ensure follow-on layers landed).
3064
3071
 
3065
3072
  let data = '';
3066
3073
  process.stdin.on('data', chunk => data += chunk);
@@ -3082,8 +3089,8 @@ process.stdin.on('end', () => {
3082
3089
  // Exempt: genuinely human-only actions
3083
3090
  if (/password|captcha|legal|billing|payment credential/i.test(command)) process.exit(0);
3084
3091
 
3085
- // Deferral patterns
3086
- const patterns = [
3092
+ // Inability / passing-the-buck patterns (original detector scope)
3093
+ const inabilityPatterns = [
3087
3094
  { re: /(?:I |i )(?:can'?t|cannot|am (?:not |un)able to)/i, type: 'inability_claim' },
3088
3095
  { re: /(?:this |it )(?:requires|needs) (?:your|human|manual) (?:input|intervention|action)/i, type: 'human_required' },
3089
3096
  { re: /you(?:'ll| will)? need to (?:do|handle|complete|input|enter|run|execute|click)/i, type: 'directing_human' },
@@ -3092,25 +3099,78 @@ process.stdin.on('end', () => {
3092
3099
  { re: /(?:blocker|blocking issue|can'?t proceed (?:without|until))/i, type: 'claimed_blocker' },
3093
3100
  ];
3094
3101
 
3095
- const matches = patterns.filter(p => p.re.test(command));
3096
- if (matches.length === 0) process.exit(0);
3102
+ // Orphan-TODO patterns proposing future-self follow-up without infrastructure.
3103
+ // The danger: "later" without /schedule or /commit-action evaporates between
3104
+ // sessions because there is no automatic carry-over.
3105
+ const orphanPatterns = [
3106
+ { re: /queue (?:them |it |this )?(?:up |for )?(?:the )?(?:next session|later|future|follow[- ]?up)/i, type: 'queue_for_later' },
3107
+ { re: /(?:pick (?:this |it )?up|circle back|loop back|come back) (?:later|in (?:a |the )?(?:next|future|follow[- ]?up))/i, type: 'pick_up_later' },
3108
+ { re: /(?:in |for )(?:a |the |another )?(?:follow[- ]?up|next session|future session|later session)/i, type: 'follow_up_session' },
3109
+ { re: /(?:i'?ll |i will |i can |we (?:can|could) )(?:address|tackle|handle|fix|do|build|implement) (?:that |this |it )?(?:later|next time|in (?:the |a )?(?:future|follow[- ]?up))/i, type: 'self_promised_later' },
3110
+ { re: /(?:deferred|defer|deferring) (?:to|until|for) (?:a |the |next |another )?(?:follow[- ]?up|session|later|future)/i, type: 'explicit_defer' },
3111
+ { re: /(?:next time|future work|left for later|future iteration|TODO:?\\s*later)/i, type: 'future_work_marker' },
3112
+ ];
3097
3113
 
3098
- const checklist = [
3099
- 'DEFERRAL DETECTEDBefore claiming you cannot do something, verify:',
3100
- '',
3101
- '1. Did you check --help or docs for the tool you are using?',
3102
- '2. Did you search for a token/API-based alternative to interactive auth?',
3103
- '3. Do you already have credentials/tokens that might work? (env vars, CLI auth, saved configs)',
3104
- '4. Can you use browser automation to complete interactive flows?',
3105
- '5. Is this GENUINELY beyond your access? (e.g., typing a password, solving a CAPTCHA)',
3106
- '',
3107
- 'If ANY check might work — try it first.',
3108
- 'The pattern: You are DESCRIBING work instead of DOING work.',
3109
- '',
3110
- 'Detected: ' + matches.map(m => m.type).join(', '),
3111
- ].join('\\n');
3114
+ // Anti-trigger: messages that DO back the deferral with infrastructure
3115
+ // get a pass they are not orphan TODOs. The same message that mentions
3116
+ // /schedule, /commit-action, a cron expression, or a tracked deadline
3117
+ // is doing it right.
3118
+ const infrastructureBackedPatterns = [
3119
+ /\\/schedule\\b/i,
3120
+ /\\/commit[-_ ]?action\\b/i,
3121
+ /commit-action\\b/i,
3122
+ /scheduled (?:agent|run|cron|routine)/i,
3123
+ /cron expression|cron schedule/i,
3124
+ /tracked (?:commitment|deadline|action[- ]?item)/i,
3125
+ /follow[- ]?up (?:PR|commit|branch)\\b/i,
3126
+ ];
3127
+ const isInfrastructureBacked = infrastructureBackedPatterns.some(p => p.test(command));
3128
+
3129
+ const inabilityMatches = inabilityPatterns.filter(p => p.re.test(command));
3130
+ const orphanMatches = isInfrastructureBacked
3131
+ ? [] // Backed by real infra — not an orphan TODO.
3132
+ : orphanPatterns.filter(p => p.re.test(command));
3133
+
3134
+ const allMatches = [...inabilityMatches, ...orphanMatches];
3135
+ if (allMatches.length === 0) process.exit(0);
3136
+
3137
+ const checklist = [];
3138
+
3139
+ if (inabilityMatches.length > 0) {
3140
+ checklist.push(
3141
+ 'DEFERRAL DETECTED — Before claiming you cannot do something, verify:',
3142
+ '',
3143
+ '1. Did you check --help or docs for the tool you are using?',
3144
+ '2. Did you search for a token/API-based alternative to interactive auth?',
3145
+ '3. Do you already have credentials/tokens that might work? (env vars, CLI auth, saved configs)',
3146
+ '4. Can you use browser automation to complete interactive flows?',
3147
+ '5. Is this GENUINELY beyond your access? (e.g., typing a password, solving a CAPTCHA)',
3148
+ '',
3149
+ 'If ANY check might work — try it first.',
3150
+ 'The pattern: You are DESCRIBING work instead of DOING work.',
3151
+ );
3152
+ }
3153
+
3154
+ if (orphanMatches.length > 0) {
3155
+ if (checklist.length > 0) checklist.push('');
3156
+ checklist.push(
3157
+ 'ORPHAN-TODO TRAP DETECTED — You proposed deferring work to "later" or "next session" without backing infrastructure.',
3158
+ '',
3159
+ 'Without one of these, the work will not actually happen:',
3160
+ ' - /schedule a remote agent (cron or one-shot) to do the work',
3161
+ ' - /commit-action with a deadline so it surfaces on the work queue',
3162
+ ' - A same-branch follow-up commit chained to merge before you stop',
3163
+ ' - Tying the deferred work to an existing tracked spec/issue',
3164
+ '',
3165
+ 'If none of those apply, the deferral evaporates between sessions.',
3166
+ 'Either back the deferral with infrastructure NOW, or do the work NOW.',
3167
+ '"I will get to it next time" is not infrastructure.',
3168
+ );
3169
+ }
3170
+
3171
+ checklist.push('', 'Detected: ' + allMatches.map(m => m.type).join(', '));
3112
3172
 
3113
- process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: checklist }));
3173
+ process.stdout.write(JSON.stringify({ decision: 'approve', additionalContext: checklist.join('\\n') }));
3114
3174
  } catch { /* don't break on errors */ }
3115
3175
  process.exit(0);
3116
3176
  });
@@ -3483,6 +3543,149 @@ process.stdin.on('end', async () => {
3483
3543
  * telegram-reply.sh migration uses similar logic inline because it ALSO
3484
3544
  * installs on first run (hasTelegram gate); these two are upgrade-only.
3485
3545
  */
3546
+ /**
3547
+ * Known-shipped SHA-256 hashes of `src/templates/scripts/telegram-reply.sh`.
3548
+ *
3549
+ * The migrator overwrites an on-disk copy only when its SHA matches one
3550
+ * of these — meaning it is a verbatim prior shipped version. Any other
3551
+ * content (user customization, partial edits, accidental damage) is
3552
+ * preserved. The new template is written alongside as `.new` and a
3553
+ * degradation event is raised so the operator can resolve it manually.
3554
+ *
3555
+ * Add the prior shipped SHA when shipping a new template; never remove
3556
+ * old SHAs (they remain valid migration sources).
3557
+ */
3558
+ // eslint-disable-next-line @typescript-eslint/naming-convention
3559
+ static TELEGRAM_REPLY_PRIOR_SHIPPED_SHAS = new Set([
3560
+ // Tier-1 initial-init shipped version. Shipped at 362ff59d.
3561
+ '98f70b86856e37f2719c39ecec152adf07ec30ce73c8134ab831b35c5b1c25b3',
3562
+ // Rebrand to Instar (no behavioral change). Shipped at 686f5758.
3563
+ '6ebc835e0077dc1cd52ec15820722b7059cf11bf5796775902f82034d43b29c4',
3564
+ // Batch feedback fixes — auth headers, job topics race, session limits.
3565
+ // Shipped at d28120f0.
3566
+ 'ce73a2fd1941381b63eb591d7c30ed761496202437a8c7fffa4926c6dfa2b7cb',
3567
+ // Tone-gate inline check on outbound messaging (no 408 handling yet).
3568
+ // Shipped at 2cb50a9a.
3569
+ 'f3aa0c8aae3f3275d0efb45b333ad83c14f7513a9e27c743039a9a113c0d16ff',
3570
+ // Adds 120s timeout + HTTP 408 ambiguous-outcome path (no port-from-
3571
+ // config yet). Shipped at a049fc5f.
3572
+ '4f8787df1bf6384545dd7f19093fd77daa1bf993ed48a8ab02b6598d41a2007c',
3573
+ // Pre-port-config version (HTTP 408 handling, INSTAR_PORT-or-4040 default,
3574
+ // no agent-id header). Shipped through 2026-04-27.
3575
+ '3d08c63c6280d0a7ba94a345c259673a461ee5c1d116cb47c95c7626c67cee23',
3576
+ // Layer 1 shipped version (port-from-config + agent-id header, no
3577
+ // recoverable-class detection). Shipped 2026-04-27 with the Layer 1
3578
+ // PR #100. Adding here so the Layer 2 migration cleanly upgrades from
3579
+ // a Layer-1-deployed copy without producing a `.new` candidate.
3580
+ '5ec2eb19bf35310471f107cb54219097698abad1c11166eb14daf746a63a2f08',
3581
+ // Layer 2 shipped version (durable SQLite queue + structured failure
3582
+ // events). Shipped 2026-04-27 with the Layer 2 PR #101. Recorded here
3583
+ // (rather than left as the implicit current-template SHA) because the
3584
+ // verifier and lint both treat any deployed SHA matching this set as
3585
+ // a known-shipped instar version, not user-modified content.
3586
+ '371d7e8f4f72146bf8bd07115873bdbbaaf32e851ac6e1318ba5b8929cd06e68',
3587
+ ]);
3588
+ /**
3589
+ * SHA-based migrator for telegram-reply.sh — replaces marker-string
3590
+ * detection with content-hash detection. See spec
3591
+ * docs/specs/telegram-delivery-robustness.md § Layer 1 "Migration".
3592
+ *
3593
+ * Three branches:
3594
+ * - on-disk SHA ∈ prior-shipped → back up and overwrite with new template.
3595
+ * - on-disk SHA == new-template SHA → no-op (idempotent).
3596
+ * - otherwise → write `<scriptPath>.new`, raise a
3597
+ * `relay-script-modified-locally` degradation event, leave the
3598
+ * original untouched.
3599
+ */
3600
+ migrateReplyScriptToPortConfig(opts) {
3601
+ let existing;
3602
+ try {
3603
+ existing = fs.readFileSync(opts.scriptPath, 'utf-8');
3604
+ }
3605
+ catch (err) {
3606
+ opts.result.errors.push(`${opts.label} migration: ${err instanceof Error ? err.message : String(err)}`);
3607
+ return;
3608
+ }
3609
+ const existingSha = crypto.createHash('sha256').update(existing).digest('hex');
3610
+ const newSha = crypto.createHash('sha256').update(opts.newContent).digest('hex');
3611
+ if (existingSha === newSha) {
3612
+ // Idempotent path — already on the new template. Assert this by
3613
+ // recording a no-op result; never write, never back up.
3614
+ opts.result.skipped.push(`${opts.label} (already current)`);
3615
+ return;
3616
+ }
3617
+ if (PostUpdateMigrator.TELEGRAM_REPLY_PRIOR_SHIPPED_SHAS.has(existingSha)) {
3618
+ // Backup-then-overwrite. Backup directory lives under the agent's
3619
+ // state dir (so it follows backup/restore semantics already
3620
+ // configured for .instar/).
3621
+ const backupDir = path.join(opts.stateDir, 'backups');
3622
+ try {
3623
+ fs.mkdirSync(backupDir, { recursive: true });
3624
+ const backupPath = path.join(backupDir, `telegram-reply.sh.${Date.now()}`);
3625
+ fs.writeFileSync(backupPath, existing, { mode: 0o644 });
3626
+ fs.writeFileSync(opts.scriptPath, opts.newContent, { mode: 0o755 });
3627
+ opts.result.upgraded.push(`${opts.label} (upgraded to port-from-config + agent-id binding; ` +
3628
+ `prior version backed up to ${path.relative(opts.stateDir, backupPath)})`);
3629
+ }
3630
+ catch (err) {
3631
+ opts.result.errors.push(`${opts.label} migration: ${err instanceof Error ? err.message : String(err)}`);
3632
+ }
3633
+ return;
3634
+ }
3635
+ // Unknown content (user-modified or unknown version). Write a `.new`
3636
+ // candidate next to the original and raise a degradation event so
3637
+ // the operator can resolve it without us stomping their changes.
3638
+ //
3639
+ // Idempotency: if a `.new` file already exists with byte-identical
3640
+ // content (e.g., this is the second `instar update` against the same
3641
+ // user-modified script), skip the rewrite and the degradation event
3642
+ // so the operator doesn't get duplicate noise on every upgrade.
3643
+ const candidatePath = `${opts.scriptPath}.new`;
3644
+ let candidateAlreadyCurrent = false;
3645
+ try {
3646
+ const existingCandidate = fs.readFileSync(candidatePath, 'utf-8');
3647
+ if (existingCandidate === opts.newContent) {
3648
+ candidateAlreadyCurrent = true;
3649
+ }
3650
+ }
3651
+ catch {
3652
+ // No existing .new file — fall through to write.
3653
+ }
3654
+ if (!candidateAlreadyCurrent) {
3655
+ try {
3656
+ fs.writeFileSync(candidatePath, opts.newContent, { mode: 0o755 });
3657
+ }
3658
+ catch (err) {
3659
+ opts.result.errors.push(`${opts.label} migration: ${err instanceof Error ? err.message : String(err)}`);
3660
+ return;
3661
+ }
3662
+ // Only fire the degradation event the first time we detect the
3663
+ // drift OR when the new template content has shifted since the
3664
+ // last `.new` write. Re-running the migrator on the same unknown
3665
+ // on-disk SHA + same new template SHA is a no-op event-wise.
3666
+ try {
3667
+ const reporter = DegradationReporter.getInstance();
3668
+ if (reporter && typeof reporter.report === 'function') {
3669
+ reporter.report({
3670
+ feature: 'relay-script-modified-locally',
3671
+ primary: 'overwrite shipped relay script with new template',
3672
+ fallback: 'wrote new template alongside as .new — operator review required',
3673
+ reason: `${opts.label} content does not match any prior shipped SHA ` +
3674
+ `(found sha256:${existingSha.slice(0, 12)}…). New template ` +
3675
+ `written to ${path.basename(candidatePath)}.`,
3676
+ impact: 'Relay script keeps running with user-modified content; the ' +
3677
+ 'port-from-config + agent-id binding fix is NOT active until ' +
3678
+ 'the operator reconciles the .new file.',
3679
+ });
3680
+ }
3681
+ }
3682
+ catch {
3683
+ // DegradationReporter is best-effort; don't block migration on it.
3684
+ }
3685
+ }
3686
+ opts.result.skipped.push(`${opts.label} (user-modified — new version ` +
3687
+ `${candidateAlreadyCurrent ? 'already' : ''} written to ${path.basename(candidatePath)})`);
3688
+ }
3486
3689
  migrateReplyScriptTo408(opts) {
3487
3690
  if (!fs.existsSync(opts.scriptPath))
3488
3691
  return; // Not installed — not our responsibility here