instar 1.3.1649 → 1.3.1651

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 (498) hide show
  1. package/dashboard/console/accounts.js +2 -1
  2. package/dashboard/console/agents-model.js +3 -3
  3. package/dashboard/console/agents.js +7 -4
  4. package/dashboard/console/console.css +1 -0
  5. package/dashboard/console/console.js +35 -4
  6. package/dashboard/console/costs-model.js +12 -0
  7. package/dashboard/console/costs.js +6 -3
  8. package/dashboard/console/development-model.js +9 -3
  9. package/dashboard/console/development.js +7 -4
  10. package/dashboard/console/home-model.js +30 -14
  11. package/dashboard/console/mandates.js +3 -3
  12. package/dashboard/console/needs-model.js +105 -0
  13. package/dashboard/console/plans.js +2 -1
  14. package/dashboard/console/secrets.js +2 -2
  15. package/dashboard/console/ticket-model.js +36 -0
  16. package/dashboard/console/ui.js +3 -0
  17. package/dist/cli.js +8 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/install.d.ts +9 -7
  20. package/dist/commands/install.d.ts.map +1 -1
  21. package/dist/commands/install.js +2 -19
  22. package/dist/commands/install.js.map +1 -1
  23. package/dist/commands/machine.d.ts +2 -0
  24. package/dist/commands/machine.d.ts.map +1 -1
  25. package/dist/commands/machine.js +19 -0
  26. package/dist/commands/machine.js.map +1 -1
  27. package/dist/commands/reflect.d.ts.map +1 -1
  28. package/dist/commands/reflect.js +2 -0
  29. package/dist/commands/reflect.js.map +1 -1
  30. package/dist/commands/route.d.ts.map +1 -1
  31. package/dist/commands/route.js +2 -0
  32. package/dist/commands/route.js.map +1 -1
  33. package/dist/commands/server.d.ts.map +1 -1
  34. package/dist/commands/server.js +537 -21
  35. package/dist/commands/server.js.map +1 -1
  36. package/dist/commands/setClaudeKey.d.ts +8 -0
  37. package/dist/commands/setClaudeKey.d.ts.map +1 -0
  38. package/dist/commands/setClaudeKey.js +35 -0
  39. package/dist/commands/setClaudeKey.js.map +1 -0
  40. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  41. package/dist/config/ConfigDefaults.js +2 -0
  42. package/dist/config/ConfigDefaults.js.map +1 -1
  43. package/dist/core/AccountFollowMeOrchestrator.d.ts.map +1 -1
  44. package/dist/core/AccountFollowMeOrchestrator.js +4 -0
  45. package/dist/core/AccountFollowMeOrchestrator.js.map +1 -1
  46. package/dist/core/AppMediaStore.d.ts.map +1 -1
  47. package/dist/core/AppMediaStore.js +3 -0
  48. package/dist/core/AppMediaStore.js.map +1 -1
  49. package/dist/core/BackupManager.d.ts.map +1 -1
  50. package/dist/core/BackupManager.js +2 -0
  51. package/dist/core/BackupManager.js.map +1 -1
  52. package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -1
  53. package/dist/core/ClaudeCliIntelligenceProvider.js +11 -3
  54. package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -1
  55. package/dist/core/ClaudeKeyHealth.d.ts +141 -0
  56. package/dist/core/ClaudeKeyHealth.d.ts.map +1 -0
  57. package/dist/core/ClaudeKeyHealth.js +467 -0
  58. package/dist/core/ClaudeKeyHealth.js.map +1 -0
  59. package/dist/core/CodexTaskContinuationStore.d.ts.map +1 -1
  60. package/dist/core/CodexTaskContinuationStore.js +7 -0
  61. package/dist/core/CodexTaskContinuationStore.js.map +1 -1
  62. package/dist/core/CoherenceJournal.d.ts +1 -1
  63. package/dist/core/CoherenceJournal.d.ts.map +1 -1
  64. package/dist/core/CoherenceJournal.js +11 -2
  65. package/dist/core/CoherenceJournal.js.map +1 -1
  66. package/dist/core/Config.d.ts +8 -0
  67. package/dist/core/Config.d.ts.map +1 -1
  68. package/dist/core/Config.js +26 -0
  69. package/dist/core/Config.js.map +1 -1
  70. package/dist/core/CredentialSwapExecutor.d.ts.map +1 -1
  71. package/dist/core/CredentialSwapExecutor.js +10 -0
  72. package/dist/core/CredentialSwapExecutor.js.map +1 -1
  73. package/dist/core/DecisionQualityRecorderImpl.d.ts.map +1 -1
  74. package/dist/core/DecisionQualityRecorderImpl.js +6 -0
  75. package/dist/core/DecisionQualityRecorderImpl.js.map +1 -1
  76. package/dist/core/DiscoveryEvaluator.d.ts.map +1 -1
  77. package/dist/core/DiscoveryEvaluator.js +4 -0
  78. package/dist/core/DiscoveryEvaluator.js.map +1 -1
  79. package/dist/core/IdentityReannounceClaimant.d.ts.map +1 -1
  80. package/dist/core/IdentityReannounceClaimant.js +4 -0
  81. package/dist/core/IdentityReannounceClaimant.js.map +1 -1
  82. package/dist/core/IntelligenceRouter.d.ts.map +1 -1
  83. package/dist/core/IntelligenceRouter.js +9 -0
  84. package/dist/core/IntelligenceRouter.js.map +1 -1
  85. package/dist/core/JournalSyncApplier.d.ts +1 -0
  86. package/dist/core/JournalSyncApplier.d.ts.map +1 -1
  87. package/dist/core/JournalSyncApplier.js +48 -0
  88. package/dist/core/JournalSyncApplier.js.map +1 -1
  89. package/dist/core/LeaseCoordinator.d.ts +4 -0
  90. package/dist/core/LeaseCoordinator.d.ts.map +1 -1
  91. package/dist/core/LeaseCoordinator.js +64 -1
  92. package/dist/core/LeaseCoordinator.js.map +1 -1
  93. package/dist/core/MachinePoolRegistry.d.ts +8 -0
  94. package/dist/core/MachinePoolRegistry.d.ts.map +1 -1
  95. package/dist/core/MachinePoolRegistry.js +25 -2
  96. package/dist/core/MachinePoolRegistry.js.map +1 -1
  97. package/dist/core/MessagingToneGate.d.ts +11 -7
  98. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  99. package/dist/core/MessagingToneGate.js +15 -1
  100. package/dist/core/MessagingToneGate.js.map +1 -1
  101. package/dist/core/MobileDeviceKeys.d.ts +10 -0
  102. package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
  103. package/dist/core/MobileDeviceKeys.js +17 -0
  104. package/dist/core/MobileDeviceKeys.js.map +1 -1
  105. package/dist/core/MultiMachineCoordinator.d.ts +12 -0
  106. package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
  107. package/dist/core/MultiMachineCoordinator.js +115 -3
  108. package/dist/core/MultiMachineCoordinator.js.map +1 -1
  109. package/dist/core/MutualSshRuntime.d.ts +1 -0
  110. package/dist/core/MutualSshRuntime.d.ts.map +1 -1
  111. package/dist/core/MutualSshRuntime.js +17 -1
  112. package/dist/core/MutualSshRuntime.js.map +1 -1
  113. package/dist/core/ObservedEndpointTracker.d.ts +1 -0
  114. package/dist/core/ObservedEndpointTracker.d.ts.map +1 -1
  115. package/dist/core/ObservedEndpointTracker.js +17 -0
  116. package/dist/core/ObservedEndpointTracker.js.map +1 -1
  117. package/dist/core/OverloadShedPlanner.d.ts +63 -7
  118. package/dist/core/OverloadShedPlanner.d.ts.map +1 -1
  119. package/dist/core/OverloadShedPlanner.js +177 -38
  120. package/dist/core/OverloadShedPlanner.js.map +1 -1
  121. package/dist/core/OwnershipApplier.d.ts.map +1 -1
  122. package/dist/core/OwnershipApplier.js +7 -0
  123. package/dist/core/OwnershipApplier.js.map +1 -1
  124. package/dist/core/OwnershipReconciler.d.ts +11 -0
  125. package/dist/core/OwnershipReconciler.d.ts.map +1 -1
  126. package/dist/core/OwnershipReconciler.js +32 -9
  127. package/dist/core/OwnershipReconciler.js.map +1 -1
  128. package/dist/core/PostUpdateMigrator.d.ts +12 -0
  129. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  130. package/dist/core/PostUpdateMigrator.js +97 -5
  131. package/dist/core/PostUpdateMigrator.js.map +1 -1
  132. package/dist/core/PrHandLease.d.ts.map +1 -1
  133. package/dist/core/PrHandLease.js +2 -0
  134. package/dist/core/PrHandLease.js.map +1 -1
  135. package/dist/core/ProactiveSwapMonitor.d.ts.map +1 -1
  136. package/dist/core/ProactiveSwapMonitor.js +7 -0
  137. package/dist/core/ProactiveSwapMonitor.js.map +1 -1
  138. package/dist/core/ProjectRoundExecution.d.ts.map +1 -1
  139. package/dist/core/ProjectRoundExecution.js +3 -2
  140. package/dist/core/ProjectRoundExecution.js.map +1 -1
  141. package/dist/core/QueueDrainLoop.d.ts +7 -0
  142. package/dist/core/QueueDrainLoop.d.ts.map +1 -1
  143. package/dist/core/QueueDrainLoop.js +37 -1
  144. package/dist/core/QueueDrainLoop.js.map +1 -1
  145. package/dist/core/RebalancePlanner.d.ts +1 -0
  146. package/dist/core/RebalancePlanner.d.ts.map +1 -1
  147. package/dist/core/RebalancePlanner.js +1 -1
  148. package/dist/core/RebalancePlanner.js.map +1 -1
  149. package/dist/core/RemoteAckStore.d.ts.map +1 -1
  150. package/dist/core/RemoteAckStore.js +4 -0
  151. package/dist/core/RemoteAckStore.js.map +1 -1
  152. package/dist/core/ReplicatedStoreReconcilerWiring.d.ts.map +1 -1
  153. package/dist/core/ReplicatedStoreReconcilerWiring.js +1 -0
  154. package/dist/core/ReplicatedStoreReconcilerWiring.js.map +1 -1
  155. package/dist/core/SecretSync.d.ts +1 -0
  156. package/dist/core/SecretSync.d.ts.map +1 -1
  157. package/dist/core/SecretSync.js +16 -0
  158. package/dist/core/SecretSync.js.map +1 -1
  159. package/dist/core/SessionDrainRunner.d.ts +10 -1
  160. package/dist/core/SessionDrainRunner.d.ts.map +1 -1
  161. package/dist/core/SessionDrainRunner.js +60 -3
  162. package/dist/core/SessionDrainRunner.js.map +1 -1
  163. package/dist/core/SessionManager.d.ts +11 -0
  164. package/dist/core/SessionManager.d.ts.map +1 -1
  165. package/dist/core/SessionManager.js +125 -14
  166. package/dist/core/SessionManager.js.map +1 -1
  167. package/dist/core/SessionPoolFailoverRunner.d.ts.map +1 -1
  168. package/dist/core/SessionPoolFailoverRunner.js +4 -0
  169. package/dist/core/SessionPoolFailoverRunner.js.map +1 -1
  170. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  171. package/dist/core/SleepWakeDetector.js +10 -0
  172. package/dist/core/SleepWakeDetector.js.map +1 -1
  173. package/dist/core/StageAdvancer.d.ts +19 -0
  174. package/dist/core/StageAdvancer.d.ts.map +1 -1
  175. package/dist/core/StageAdvancer.js +51 -1
  176. package/dist/core/StageAdvancer.js.map +1 -1
  177. package/dist/core/SubscriptionReloginStore.d.ts.map +1 -1
  178. package/dist/core/SubscriptionReloginStore.js +10 -1
  179. package/dist/core/SubscriptionReloginStore.js.map +1 -1
  180. package/dist/core/TopicPinMutation.d.ts.map +1 -1
  181. package/dist/core/TopicPinMutation.js +5 -0
  182. package/dist/core/TopicPinMutation.js.map +1 -1
  183. package/dist/core/UnjustifiedStopGate.d.ts.map +1 -1
  184. package/dist/core/UnjustifiedStopGate.js +22 -0
  185. package/dist/core/UnjustifiedStopGate.js.map +1 -1
  186. package/dist/core/WindowRunCadenceExecutor.d.ts.map +1 -1
  187. package/dist/core/WindowRunCadenceExecutor.js +20 -0
  188. package/dist/core/WindowRunCadenceExecutor.js.map +1 -1
  189. package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
  190. package/dist/core/WriteDomainRegistry.js +12 -0
  191. package/dist/core/WriteDomainRegistry.js.map +1 -1
  192. package/dist/core/claudeChildAuth.d.ts +68 -0
  193. package/dist/core/claudeChildAuth.d.ts.map +1 -0
  194. package/dist/core/claudeChildAuth.js +173 -0
  195. package/dist/core/claudeChildAuth.js.map +1 -0
  196. package/dist/core/claudeKeyProbe.d.ts +23 -0
  197. package/dist/core/claudeKeyProbe.d.ts.map +1 -0
  198. package/dist/core/claudeKeyProbe.js +68 -0
  199. package/dist/core/claudeKeyProbe.js.map +1 -0
  200. package/dist/core/codexDeviceLimitWiring.d.ts.map +1 -1
  201. package/dist/core/codexDeviceLimitWiring.js +12 -0
  202. package/dist/core/codexDeviceLimitWiring.js.map +1 -1
  203. package/dist/core/deliverToConversation.d.ts.map +1 -1
  204. package/dist/core/deliverToConversation.js +11 -0
  205. package/dist/core/deliverToConversation.js.map +1 -1
  206. package/dist/core/leaseMediumSelection.d.ts +8 -0
  207. package/dist/core/leaseMediumSelection.d.ts.map +1 -1
  208. package/dist/core/leaseMediumSelection.js +17 -0
  209. package/dist/core/leaseMediumSelection.js.map +1 -1
  210. package/dist/core/meteredCallEntry.d.ts.map +1 -1
  211. package/dist/core/meteredCallEntry.js +21 -0
  212. package/dist/core/meteredCallEntry.js.map +1 -1
  213. package/dist/core/nobodyPollingActuator.d.ts.map +1 -1
  214. package/dist/core/nobodyPollingActuator.js +5 -0
  215. package/dist/core/nobodyPollingActuator.js.map +1 -1
  216. package/dist/core/operatorSurfaceReferral.d.ts +18 -0
  217. package/dist/core/operatorSurfaceReferral.d.ts.map +1 -0
  218. package/dist/core/operatorSurfaceReferral.js +32 -0
  219. package/dist/core/operatorSurfaceReferral.js.map +1 -0
  220. package/dist/core/ownershipFollowsLiveWork.d.ts.map +1 -1
  221. package/dist/core/ownershipFollowsLiveWork.js +10 -1
  222. package/dist/core/ownershipFollowsLiveWork.js.map +1 -1
  223. package/dist/core/poolReadiness.d.ts +67 -0
  224. package/dist/core/poolReadiness.d.ts.map +1 -0
  225. package/dist/core/poolReadiness.js +156 -0
  226. package/dist/core/poolReadiness.js.map +1 -0
  227. package/dist/core/quietTopicScanner.d.ts +39 -0
  228. package/dist/core/quietTopicScanner.d.ts.map +1 -0
  229. package/dist/core/quietTopicScanner.js +57 -0
  230. package/dist/core/quietTopicScanner.js.map +1 -0
  231. package/dist/core/rebalanceProof.d.ts +114 -0
  232. package/dist/core/rebalanceProof.d.ts.map +1 -0
  233. package/dist/core/rebalanceProof.js +192 -0
  234. package/dist/core/rebalanceProof.js.map +1 -0
  235. package/dist/core/types.d.ts +23 -1
  236. package/dist/core/types.d.ts.map +1 -1
  237. package/dist/core/types.js.map +1 -1
  238. package/dist/core/worktreeDirtyCheck.d.ts.map +1 -1
  239. package/dist/core/worktreeDirtyCheck.js +2 -0
  240. package/dist/core/worktreeDirtyCheck.js.map +1 -1
  241. package/dist/data/stageBCertifiedSet.d.ts +9 -0
  242. package/dist/data/stageBCertifiedSet.d.ts.map +1 -1
  243. package/dist/data/stageBCertifiedSet.js +12 -0
  244. package/dist/data/stageBCertifiedSet.js.map +1 -1
  245. package/dist/data/standards-guard-index.json +1 -1
  246. package/dist/data/standards-guard-index.meta.json +2 -2
  247. package/dist/data/standards-registry.meta.json +1 -1
  248. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  249. package/dist/lifeline/TelegramLifeline.js +17 -3
  250. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  251. package/dist/messaging/attentionHubPolicy.d.ts.map +1 -1
  252. package/dist/messaging/attentionHubPolicy.js +1 -0
  253. package/dist/messaging/attentionHubPolicy.js.map +1 -1
  254. package/dist/monitoring/AgentWorktreeReaper.d.ts.map +1 -1
  255. package/dist/monitoring/AgentWorktreeReaper.js +15 -0
  256. package/dist/monitoring/AgentWorktreeReaper.js.map +1 -1
  257. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.d.ts.map +1 -1
  258. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js +18 -9
  259. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js.map +1 -1
  260. package/dist/monitoring/CodexArmSessionSweeper.d.ts.map +1 -1
  261. package/dist/monitoring/CodexArmSessionSweeper.js +11 -0
  262. package/dist/monitoring/CodexArmSessionSweeper.js.map +1 -1
  263. package/dist/monitoring/CrashLoopPauser.d.ts.map +1 -1
  264. package/dist/monitoring/CrashLoopPauser.js +8 -0
  265. package/dist/monitoring/CrashLoopPauser.js.map +1 -1
  266. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  267. package/dist/monitoring/DegradationReporter.js +7 -1
  268. package/dist/monitoring/DegradationReporter.js.map +1 -1
  269. package/dist/monitoring/DegradedTmuxGuard.d.ts +2 -0
  270. package/dist/monitoring/DegradedTmuxGuard.d.ts.map +1 -1
  271. package/dist/monitoring/DegradedTmuxGuard.js +14 -0
  272. package/dist/monitoring/DegradedTmuxGuard.js.map +1 -1
  273. package/dist/monitoring/DurableOutputScrubber.d.ts.map +1 -1
  274. package/dist/monitoring/DurableOutputScrubber.js +7 -0
  275. package/dist/monitoring/DurableOutputScrubber.js.map +1 -1
  276. package/dist/monitoring/DurableVaultSession.d.ts.map +1 -1
  277. package/dist/monitoring/DurableVaultSession.js +15 -0
  278. package/dist/monitoring/DurableVaultSession.js.map +1 -1
  279. package/dist/monitoring/ExternalHogSentinel.d.ts +2 -0
  280. package/dist/monitoring/ExternalHogSentinel.d.ts.map +1 -1
  281. package/dist/monitoring/ExternalHogSentinel.js +27 -1
  282. package/dist/monitoring/ExternalHogSentinel.js.map +1 -1
  283. package/dist/monitoring/FailureLedger.d.ts.map +1 -1
  284. package/dist/monitoring/FailureLedger.js +38 -1
  285. package/dist/monitoring/FailureLedger.js.map +1 -1
  286. package/dist/monitoring/FeatureEvidenceLog.d.ts +5 -0
  287. package/dist/monitoring/FeatureEvidenceLog.d.ts.map +1 -1
  288. package/dist/monitoring/FeatureEvidenceLog.js +25 -0
  289. package/dist/monitoring/FeatureEvidenceLog.js.map +1 -1
  290. package/dist/monitoring/GeminiCapacityEscalationMonitor.d.ts.map +1 -1
  291. package/dist/monitoring/GeminiCapacityEscalationMonitor.js +20 -2
  292. package/dist/monitoring/GeminiCapacityEscalationMonitor.js.map +1 -1
  293. package/dist/monitoring/GeminiLoopRunner.d.ts.map +1 -1
  294. package/dist/monitoring/GeminiLoopRunner.js +11 -1
  295. package/dist/monitoring/GeminiLoopRunner.js.map +1 -1
  296. package/dist/monitoring/GreenPrAutoMerger.d.ts.map +1 -1
  297. package/dist/monitoring/GreenPrAutoMerger.js +11 -0
  298. package/dist/monitoring/GreenPrAutoMerger.js.map +1 -1
  299. package/dist/monitoring/GrowthDigestPublisher.d.ts.map +1 -1
  300. package/dist/monitoring/GrowthDigestPublisher.js +16 -0
  301. package/dist/monitoring/GrowthDigestPublisher.js.map +1 -1
  302. package/dist/monitoring/GrowthMilestoneAnalyst.d.ts +3 -0
  303. package/dist/monitoring/GrowthMilestoneAnalyst.d.ts.map +1 -1
  304. package/dist/monitoring/GrowthMilestoneAnalyst.js +45 -1
  305. package/dist/monitoring/GrowthMilestoneAnalyst.js.map +1 -1
  306. package/dist/monitoring/McpProcessReaper.d.ts +2 -0
  307. package/dist/monitoring/McpProcessReaper.d.ts.map +1 -1
  308. package/dist/monitoring/McpProcessReaper.js +32 -0
  309. package/dist/monitoring/McpProcessReaper.js.map +1 -1
  310. package/dist/monitoring/MissingLoginSessionDetector.d.ts +2 -1
  311. package/dist/monitoring/MissingLoginSessionDetector.d.ts.map +1 -1
  312. package/dist/monitoring/MissingLoginSessionDetector.js +23 -0
  313. package/dist/monitoring/MissingLoginSessionDetector.js.map +1 -1
  314. package/dist/monitoring/OrchestratorPoller.d.ts +1 -0
  315. package/dist/monitoring/OrchestratorPoller.d.ts.map +1 -1
  316. package/dist/monitoring/OrchestratorPoller.js +13 -0
  317. package/dist/monitoring/OrchestratorPoller.js.map +1 -1
  318. package/dist/monitoring/OrphanedWorkSentinel.d.ts.map +1 -1
  319. package/dist/monitoring/OrphanedWorkSentinel.js +7 -0
  320. package/dist/monitoring/OrphanedWorkSentinel.js.map +1 -1
  321. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  322. package/dist/monitoring/PresenceProxy.js +9 -1
  323. package/dist/monitoring/PresenceProxy.js.map +1 -1
  324. package/dist/monitoring/ProcessFootprintMonitor.d.ts.map +1 -1
  325. package/dist/monitoring/ProcessFootprintMonitor.js +20 -2
  326. package/dist/monitoring/ProcessFootprintMonitor.js.map +1 -1
  327. package/dist/monitoring/PromiseBeacon.d.ts.map +1 -1
  328. package/dist/monitoring/PromiseBeacon.js +20 -0
  329. package/dist/monitoring/PromiseBeacon.js.map +1 -1
  330. package/dist/monitoring/ReleaseReadinessSentinel.d.ts +2 -0
  331. package/dist/monitoring/ReleaseReadinessSentinel.d.ts.map +1 -1
  332. package/dist/monitoring/ReleaseReadinessSentinel.js +26 -0
  333. package/dist/monitoring/ReleaseReadinessSentinel.js.map +1 -1
  334. package/dist/monitoring/RopeHealthMonitor.d.ts.map +1 -1
  335. package/dist/monitoring/RopeHealthMonitor.js +35 -1
  336. package/dist/monitoring/RopeHealthMonitor.js.map +1 -1
  337. package/dist/monitoring/SentinelNotifier.d.ts.map +1 -1
  338. package/dist/monitoring/SentinelNotifier.js +16 -0
  339. package/dist/monitoring/SentinelNotifier.js.map +1 -1
  340. package/dist/monitoring/SessionReaper.d.ts.map +1 -1
  341. package/dist/monitoring/SessionReaper.js +11 -2
  342. package/dist/monitoring/SessionReaper.js.map +1 -1
  343. package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts +2 -0
  344. package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts.map +1 -1
  345. package/dist/monitoring/SingleMachineFailoverGapDetector.js +20 -0
  346. package/dist/monitoring/SingleMachineFailoverGapDetector.js.map +1 -1
  347. package/dist/monitoring/SpeakerElection.d.ts.map +1 -1
  348. package/dist/monitoring/SpeakerElection.js +8 -0
  349. package/dist/monitoring/SpeakerElection.js.map +1 -1
  350. package/dist/monitoring/StrandedTopicSentinel.d.ts +3 -0
  351. package/dist/monitoring/StrandedTopicSentinel.d.ts.map +1 -1
  352. package/dist/monitoring/StrandedTopicSentinel.js +33 -0
  353. package/dist/monitoring/StrandedTopicSentinel.js.map +1 -1
  354. package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
  355. package/dist/native/instar-desktop-host +0 -0
  356. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.d.ts.map +1 -1
  357. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js +5 -2
  358. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js.map +1 -1
  359. package/dist/recommended/RecommendedServicesLedger.d.ts +91 -0
  360. package/dist/recommended/RecommendedServicesLedger.d.ts.map +1 -0
  361. package/dist/recommended/RecommendedServicesLedger.js +193 -0
  362. package/dist/recommended/RecommendedServicesLedger.js.map +1 -0
  363. package/dist/recommended/RecommendedServicesReplicatedStore.d.ts +14 -0
  364. package/dist/recommended/RecommendedServicesReplicatedStore.d.ts.map +1 -0
  365. package/dist/recommended/RecommendedServicesReplicatedStore.js +34 -0
  366. package/dist/recommended/RecommendedServicesReplicatedStore.js.map +1 -0
  367. package/dist/recommended/legacyDeclines.d.ts +11 -0
  368. package/dist/recommended/legacyDeclines.d.ts.map +1 -0
  369. package/dist/recommended/legacyDeclines.js +17 -0
  370. package/dist/recommended/legacyDeclines.js.map +1 -0
  371. package/dist/recommended/serviceIds.d.ts +3 -0
  372. package/dist/recommended/serviceIds.d.ts.map +1 -0
  373. package/dist/recommended/serviceIds.js +6 -0
  374. package/dist/recommended/serviceIds.js.map +1 -0
  375. package/dist/scaffold/templates.d.ts +2 -0
  376. package/dist/scaffold/templates.d.ts.map +1 -1
  377. package/dist/scaffold/templates.js +11 -1
  378. package/dist/scaffold/templates.js.map +1 -1
  379. package/dist/scheduler/JobResultTriage.d.ts.map +1 -1
  380. package/dist/scheduler/JobResultTriage.js +10 -0
  381. package/dist/scheduler/JobResultTriage.js.map +1 -1
  382. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  383. package/dist/scheduler/JobScheduler.js +12 -0
  384. package/dist/scheduler/JobScheduler.js.map +1 -1
  385. package/dist/scheduler/MentorOnboardingRunner.d.ts +3 -0
  386. package/dist/scheduler/MentorOnboardingRunner.d.ts.map +1 -1
  387. package/dist/scheduler/MentorOnboardingRunner.js +24 -2
  388. package/dist/scheduler/MentorOnboardingRunner.js.map +1 -1
  389. package/dist/server/AgentServer.d.ts +2 -0
  390. package/dist/server/AgentServer.d.ts.map +1 -1
  391. package/dist/server/AgentServer.js +78 -15
  392. package/dist/server/AgentServer.js.map +1 -1
  393. package/dist/server/BootHealthBeacon.d.ts +3 -0
  394. package/dist/server/BootHealthBeacon.d.ts.map +1 -1
  395. package/dist/server/BootHealthBeacon.js +9 -0
  396. package/dist/server/BootHealthBeacon.js.map +1 -1
  397. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  398. package/dist/server/CapabilityIndex.js +12 -3
  399. package/dist/server/CapabilityIndex.js.map +1 -1
  400. package/dist/server/LifelineIngressGuard.d.ts.map +1 -1
  401. package/dist/server/LifelineIngressGuard.js +11 -0
  402. package/dist/server/LifelineIngressGuard.js.map +1 -1
  403. package/dist/server/PoolPollCache.d.ts +4 -0
  404. package/dist/server/PoolPollCache.d.ts.map +1 -1
  405. package/dist/server/PoolPollCache.js +33 -0
  406. package/dist/server/PoolPollCache.js.map +1 -1
  407. package/dist/server/machineRoutes.d.ts.map +1 -1
  408. package/dist/server/machineRoutes.js +6 -0
  409. package/dist/server/machineRoutes.js.map +1 -1
  410. package/dist/server/middleware.d.ts.map +1 -1
  411. package/dist/server/middleware.js +6 -0
  412. package/dist/server/middleware.js.map +1 -1
  413. package/dist/server/mobileConsoleTicket.d.ts +113 -0
  414. package/dist/server/mobileConsoleTicket.d.ts.map +1 -0
  415. package/dist/server/mobileConsoleTicket.js +405 -0
  416. package/dist/server/mobileConsoleTicket.js.map +1 -0
  417. package/dist/server/mobileConversationRoutes.d.ts.map +1 -1
  418. package/dist/server/mobileConversationRoutes.js +20 -1
  419. package/dist/server/mobileConversationRoutes.js.map +1 -1
  420. package/dist/server/mobileMediaRoutes.d.ts.map +1 -1
  421. package/dist/server/mobileMediaRoutes.js +3 -0
  422. package/dist/server/mobileMediaRoutes.js.map +1 -1
  423. package/dist/server/mobilePairingRoutes.d.ts +8 -2
  424. package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
  425. package/dist/server/mobilePairingRoutes.js +67 -6
  426. package/dist/server/mobilePairingRoutes.js.map +1 -1
  427. package/dist/server/mobileSessionTerminalRoutes.d.ts +128 -0
  428. package/dist/server/mobileSessionTerminalRoutes.d.ts.map +1 -0
  429. package/dist/server/mobileSessionTerminalRoutes.js +389 -0
  430. package/dist/server/mobileSessionTerminalRoutes.js.map +1 -0
  431. package/dist/server/recommendedServiceRoutes.d.ts +13 -0
  432. package/dist/server/recommendedServiceRoutes.d.ts.map +1 -0
  433. package/dist/server/recommendedServiceRoutes.js +49 -0
  434. package/dist/server/recommendedServiceRoutes.js.map +1 -0
  435. package/dist/server/routes.d.ts +2 -0
  436. package/dist/server/routes.d.ts.map +1 -1
  437. package/dist/server/routes.js +215 -5
  438. package/dist/server/routes.js.map +1 -1
  439. package/dist/testing/selfActionRegistry.d.ts.map +1 -1
  440. package/dist/testing/selfActionRegistry.js +44 -3
  441. package/dist/testing/selfActionRegistry.js.map +1 -1
  442. package/dist/threadline/A2ACheckInProxy.d.ts.map +1 -1
  443. package/dist/threadline/A2ACheckInProxy.js +26 -15
  444. package/dist/threadline/A2ACheckInProxy.js.map +1 -1
  445. package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
  446. package/dist/threadline/AgentTrustManager.js +3 -0
  447. package/dist/threadline/AgentTrustManager.js.map +1 -1
  448. package/dist/threadline/InboundIdLedger.d.ts.map +1 -1
  449. package/dist/threadline/InboundIdLedger.js +18 -1
  450. package/dist/threadline/InboundIdLedger.js.map +1 -1
  451. package/dist/threadline/NegotiatorGate.d.ts.map +1 -1
  452. package/dist/threadline/NegotiatorGate.js +11 -0
  453. package/dist/threadline/NegotiatorGate.js.map +1 -1
  454. package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
  455. package/dist/threadline/PipeSessionSpawner.js +8 -0
  456. package/dist/threadline/PipeSessionSpawner.js.map +1 -1
  457. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  458. package/dist/threadline/ThreadlineRouter.js +13 -0
  459. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  460. package/dist/threadline/pairingReplicationWiring.d.ts.map +1 -1
  461. package/dist/threadline/pairingReplicationWiring.js +9 -0
  462. package/dist/threadline/pairingReplicationWiring.js.map +1 -1
  463. package/dist/threadline/relayForward.d.ts.map +1 -1
  464. package/dist/threadline/relayForward.js +13 -2
  465. package/dist/threadline/relayForward.js.map +1 -1
  466. package/dist/threadline/relayUnknownSenderTrust.d.ts +0 -9
  467. package/dist/threadline/relayUnknownSenderTrust.d.ts.map +1 -1
  468. package/dist/threadline/relayUnknownSenderTrust.js +16 -0
  469. package/dist/threadline/relayUnknownSenderTrust.js.map +1 -1
  470. package/package.json +1 -1
  471. package/scripts/check-constitution-pairing.mjs +273 -0
  472. package/scripts/safe-merge.mjs +9 -0
  473. package/src/data/builtin-manifest.json +103 -103
  474. package/src/data/feature-ladders.json +113 -113
  475. package/src/data/stageBCertifiedSet.ts +12 -0
  476. package/src/data/standards-guard-index.json +1 -1
  477. package/src/data/standards-guard-index.meta.json +2 -2
  478. package/src/data/standards-registry.meta.json +1 -1
  479. package/src/data/state-coherence-registry.json +18 -0
  480. package/src/scaffold/templates.ts +12 -1
  481. package/upgrades/1.3.1650.md +105 -0
  482. package/upgrades/1.3.1651.md +30 -0
  483. package/upgrades/mobile-console-device-signin.eli16.md +5 -0
  484. package/upgrades/side-effects/cloud-key-internal-calls.md +116 -0
  485. package/upgrades/side-effects/constitution-alignment.eli16.md +11 -0
  486. package/upgrades/side-effects/constitution-alignment.md +69 -0
  487. package/upgrades/side-effects/feature-evidence-recording.eli16.md +3 -0
  488. package/upgrades/side-effects/feature-evidence-recording.md +66 -0
  489. package/upgrades/side-effects/feedback-reroute-admission-parity.md +77 -0
  490. package/upgrades/side-effects/mobile-console-device-signin.md +102 -0
  491. package/upgrades/side-effects/mobile-native-session-screen.md +88 -0
  492. package/upgrades/side-effects/operator-needs-first-screen.md +87 -0
  493. package/upgrades/side-effects/recommended-services-choices.md +50 -0
  494. package/upgrades/side-effects/rerouted-lifetime-active-process.md +63 -0
  495. package/upgrades/side-effects/session-pool-default-on.md +53 -0
  496. package/upgrades/side-effects/session-pool-rebalancing-finish.md +151 -0
  497. package/upgrades/side-effects/undated-resurfacer-e2e-wait.eli16.md +5 -0
  498. package/upgrades/side-effects/undated-resurfacer-e2e-wait.md +9 -0
@@ -7,6 +7,7 @@
7
7
  * collapse the two paths once the adapter is wired into the rest of
8
8
  * Instar's source.
9
9
  */
10
+ import { applyClaudeChildAuth, configuredClaudeOauthKey } from '../../../../core/claudeChildAuth.js';
10
11
  import { execFile } from 'node:child_process';
11
12
  import { promisify } from 'node:util';
12
13
  import { CapabilityFlag } from '../../../capabilities.js';
@@ -45,8 +46,10 @@ class AnthropicHeadlessOneShotCompletion {
45
46
  const childEnv = { ...process.env };
46
47
  delete childEnv['CLAUDECODE'];
47
48
  delete childEnv['CLAUDE_SESSION_ID'];
48
- // Inject auth credential if configured
49
- if (this.config.credential) {
49
+ // Inject auth credential if configured. The agent's configured key wins over one read from the
50
+ // server's env, matching session launch (spec cloud-key-internal-calls).
51
+ applyClaudeChildAuth(childEnv);
52
+ if (this.config.credential && !configuredClaudeOauthKey()) {
50
53
  if (this.config.credential.startsWith('sk-ant-oat')) {
51
54
  childEnv['CLAUDE_CODE_OAUTH_TOKEN'] = this.config.credential;
52
55
  delete childEnv['ANTHROPIC_API_KEY'];
@@ -1 +1 @@
1
- {"version":3,"file":"oneShotCompletion.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/anthropic-headless/transport/oneShotCompletion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oneShotCompletion.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/anthropic-headless/transport/oneShotCompletion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { type MachineKeyLookup, type MachineSigner } from '../core/AppRecordSignatures.js';
2
+ export declare const NO_REASONS: readonly ['cost', 'privacy', 'not-needed', 'have-another', 'other', 'none'];
3
+ export type NoReason = (typeof NO_REASONS)[number];
4
+ export declare const CHOICE_ORIGINS: readonly ['first-offer', 'change', 'cool-off', 'person-asked', 'owner-surface'];
5
+ export type ChoiceOrigin = (typeof CHOICE_ORIGINS)[number] | `event:${string}`;
6
+ interface RowSignature {
7
+ machineId: string;
8
+ signerKeyHash: string;
9
+ sig: string;
10
+ }
11
+ export interface ChoiceRow extends RowSignature {
12
+ type: 'choice';
13
+ eventId: string;
14
+ service: string;
15
+ choice: 'yes' | 'no';
16
+ shutdown: 'none' | 'authorized';
17
+ reason: NoReason;
18
+ origin: ChoiceOrigin;
19
+ offerTextHash: string;
20
+ supersedes: string[];
21
+ at: string;
22
+ }
23
+ export interface LegacyImportRow extends RowSignature {
24
+ type: 'legacy-import';
25
+ eventId: string;
26
+ service: string;
27
+ at: string;
28
+ }
29
+ export type LedgerRow = ChoiceRow | LegacyImportRow;
30
+ export interface EffectiveChoice {
31
+ service: string;
32
+ choice: 'unset' | 'yes' | 'no';
33
+ origin: ChoiceOrigin | null;
34
+ /** A no refuses offers. Only an authorized shutdown stops a running service. */
35
+ shutdown: 'none' | 'authorized';
36
+ reason: NoReason | null;
37
+ /** An imported legacy decline: suppresses offers, grants and stops nothing. */
38
+ legacyDeclined: boolean;
39
+ at: string | null;
40
+ }
41
+ /** Validate a row's shape, not its signature. Exact fields only. */
42
+ export declare function validateRow(raw: unknown): LedgerRow | null;
43
+ /** One effective choice per service. A pure fold, so every machine reaches the same answer. */
44
+ export declare function foldChoice(service: string, rows: readonly LedgerRow[]): EffectiveChoice;
45
+ export declare function recommendedServicesDir(stateDir: string): string;
46
+ export type IngestResult = 'added' | 'duplicate' | 'invalid' | 'bad-signature' | 'unverifiable' | 'full';
47
+ export interface RecommendedServicesLedgerOptions {
48
+ stateDir: string;
49
+ signer: MachineSigner;
50
+ keyLookup: MachineKeyLookup;
51
+ now?: () => Date;
52
+ }
53
+ export declare class RecommendedServicesLedger {
54
+ private readonly opts;
55
+ private readonly file;
56
+ private readonly rows;
57
+ private hook;
58
+ private replicating;
59
+ constructor(opts: RecommendedServicesLedgerOptions);
60
+ setReplicationHook(hook: (row: LedgerRow) => void): void;
61
+ /** Set by the server from the store's real state: its emission is on, and peers pull. */
62
+ setReplicating(on: boolean): void;
63
+ /** False when choices stay on this machine. */
64
+ isReplicating(): boolean;
65
+ all(): LedgerRow[];
66
+ effective(service: string): EffectiveChoice;
67
+ /** The person's no. Sticky until a confirmed yes names it. */
68
+ recordNo(input: {
69
+ service: string;
70
+ shutdown: 'none' | 'authorized';
71
+ reason: NoReason;
72
+ origin: ChoiceOrigin;
73
+ offerTextHash?: string;
74
+ }): ChoiceRow;
75
+ /** A confirmed yes replaces every no standing at this moment, and only those. */
76
+ recordYes(input: {
77
+ service: string;
78
+ origin: ChoiceOrigin;
79
+ offerTextHash: string;
80
+ }): ChoiceRow;
81
+ /** Idempotent per service: one import row is enough, whichever machine wrote it. */
82
+ recordLegacyImport(service: string): LegacyImportRow | null;
83
+ /** A peer's row lands only when it verifies under the pinned key of the machine it names. */
84
+ ingestReplicated(raw: unknown): IngestResult;
85
+ private appendChoice;
86
+ private signAndStore;
87
+ private store;
88
+ private at;
89
+ }
90
+ export {};
91
+ //# sourceMappingURL=RecommendedServicesLedger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendedServicesLedger.d.ts","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * The record of a person's choices about recommended outside services
3
+ * (docs/specs/recommended-services.md).
4
+ *
5
+ * Append-only and signed per row by the writing machine's identity key, because auth tokens
6
+ * differ between machines. Rows replicate as the `recommendedServices` store and fold into one
7
+ * effective choice: a no stands until a yes names it in `supersedes`, so delayed replication
8
+ * and clock skew cannot undo a refusal. Imported legacy declines only suppress offers. They
9
+ * never count in the merge and never stop a running service.
10
+ */
11
+ import crypto from 'node:crypto';
12
+ import fs from 'node:fs';
13
+ import path from 'node:path';
14
+ import { ledgerRowPayload, readJsonlLines, verifyMachineSignature, } from '../core/AppRecordSignatures.js';
15
+ export const NO_REASONS = ['cost', 'privacy', 'not-needed', 'have-another', 'other', 'none'];
16
+ export const CHOICE_ORIGINS = ['first-offer', 'change', 'cool-off', 'person-asked', 'owner-surface'];
17
+ const SERVICE_RE = /^[a-z][a-z0-9-]{0,63}$/;
18
+ const ID_RE = /^[0-9a-f]{32}$/;
19
+ const ORIGIN_RE = /^event:[a-z][a-z0-9-]{0,63}$/;
20
+ const MAX_ROWS = 10_000;
21
+ function signature(r) {
22
+ const { machineId, signerKeyHash, sig } = r;
23
+ if (typeof machineId !== 'string' || !machineId || machineId.length > 128)
24
+ return null;
25
+ if (typeof signerKeyHash !== 'string' || !signerKeyHash || signerKeyHash.length > 128)
26
+ return null;
27
+ if (typeof sig !== 'string' || !sig || sig.length > 512)
28
+ return null;
29
+ return { machineId, signerKeyHash, sig };
30
+ }
31
+ /** Validate a row's shape, not its signature. Exact fields only. */
32
+ export function validateRow(raw) {
33
+ if (!raw || typeof raw !== 'object')
34
+ return null;
35
+ const r = raw;
36
+ const s = signature(r);
37
+ if (!s)
38
+ return null;
39
+ const { eventId, service, at } = r;
40
+ if (typeof eventId !== 'string' || !ID_RE.test(eventId))
41
+ return null;
42
+ if (typeof service !== 'string' || !SERVICE_RE.test(service))
43
+ return null;
44
+ if (typeof at !== 'string' || !Number.isFinite(Date.parse(at)))
45
+ return null;
46
+ if (r.type === 'legacy-import')
47
+ return { type: 'legacy-import', eventId, service, at, ...s };
48
+ if (r.type !== 'choice')
49
+ return null;
50
+ const { choice, shutdown, reason, origin, offerTextHash, supersedes } = r;
51
+ if (choice !== 'yes' && choice !== 'no')
52
+ return null;
53
+ if (shutdown !== 'none' && shutdown !== 'authorized')
54
+ return null;
55
+ if (!NO_REASONS.includes(reason))
56
+ return null;
57
+ if (typeof origin !== 'string')
58
+ return null;
59
+ if (!CHOICE_ORIGINS.includes(origin) && !ORIGIN_RE.test(origin))
60
+ return null;
61
+ if (typeof offerTextHash !== 'string' || offerTextHash.length > 128)
62
+ return null;
63
+ if (!Array.isArray(supersedes) || supersedes.length > 256)
64
+ return null;
65
+ if (!supersedes.every((id) => typeof id === 'string' && ID_RE.test(id)))
66
+ return null;
67
+ return {
68
+ type: 'choice', eventId, service, choice, shutdown, reason: reason,
69
+ origin: origin, offerTextHash, supersedes: supersedes, at, ...s,
70
+ };
71
+ }
72
+ /** One effective choice per service. A pure fold, so every machine reaches the same answer. */
73
+ export function foldChoice(service, rows) {
74
+ const own = rows.filter((r) => r.service === service);
75
+ const choices = own.filter((r) => r.type === 'choice');
76
+ const replaced = new Set(choices.filter((c) => c.choice === 'yes').flatMap((c) => c.supersedes));
77
+ const byNewest = (a, b) => (a.at === b.at ? (a.eventId < b.eventId ? 1 : -1) : a.at < b.at ? 1 : -1);
78
+ const liveNos = choices.filter((c) => c.choice === 'no' && !replaced.has(c.eventId)).sort(byNewest);
79
+ const yeses = choices.filter((c) => c.choice === 'yes').sort(byNewest);
80
+ const legacyDeclined = own.some((r) => r.type === 'legacy-import');
81
+ const winner = liveNos[0] ?? yeses[0];
82
+ if (!winner)
83
+ return { service, choice: 'unset', origin: null, shutdown: 'none', reason: null, legacyDeclined, at: null };
84
+ const shutdown = liveNos.some((n) => n.shutdown === 'authorized') ? 'authorized' : 'none';
85
+ return {
86
+ service, choice: winner.choice, origin: winner.origin,
87
+ shutdown: winner.choice === 'no' ? shutdown : 'none',
88
+ reason: winner.choice === 'no' ? winner.reason : null, legacyDeclined, at: winner.at,
89
+ };
90
+ }
91
+ export function recommendedServicesDir(stateDir) {
92
+ return path.join(stateDir, 'state', 'recommended-services');
93
+ }
94
+ export class RecommendedServicesLedger {
95
+ opts;
96
+ file;
97
+ rows = new Map();
98
+ hook = null;
99
+ replicating = false;
100
+ constructor(opts) {
101
+ this.opts = opts;
102
+ this.file = path.join(recommendedServicesDir(opts.stateDir), 'ledger.jsonl');
103
+ for (const line of readJsonlLines(this.file)) {
104
+ try {
105
+ const row = validateRow(JSON.parse(line));
106
+ if (row)
107
+ this.rows.set(row.eventId, row);
108
+ }
109
+ catch { /* @silent-fallback-ok — one torn line; the row is re-read from peer streams at boot */ }
110
+ }
111
+ }
112
+ setReplicationHook(hook) {
113
+ this.hook = hook;
114
+ }
115
+ /** Set by the server from the store's real state: its emission is on, and peers pull. */
116
+ setReplicating(on) {
117
+ this.replicating = on;
118
+ }
119
+ /** False when choices stay on this machine. */
120
+ isReplicating() {
121
+ return this.replicating;
122
+ }
123
+ all() {
124
+ return [...this.rows.values()];
125
+ }
126
+ effective(service) {
127
+ return foldChoice(service, this.all());
128
+ }
129
+ /** The person's no. Sticky until a confirmed yes names it. */
130
+ recordNo(input) {
131
+ return this.appendChoice({ ...input, choice: 'no', supersedes: [] });
132
+ }
133
+ /** A confirmed yes replaces every no standing at this moment, and only those. */
134
+ recordYes(input) {
135
+ const replaced = new Set(this.all().flatMap((r) => (r.type === 'choice' && r.choice === 'yes' ? r.supersedes : [])));
136
+ const supersedes = this.all()
137
+ .filter((r) => r.type === 'choice' && r.service === input.service && r.choice === 'no' && !replaced.has(r.eventId))
138
+ .map((r) => r.eventId);
139
+ return this.appendChoice({ ...input, choice: 'yes', shutdown: 'none', reason: 'none', supersedes });
140
+ }
141
+ /** Idempotent per service: one import row is enough, whichever machine wrote it. */
142
+ recordLegacyImport(service) {
143
+ if (this.all().some((r) => r.type === 'legacy-import' && r.service === service))
144
+ return null;
145
+ return this.signAndStore({ type: 'legacy-import', eventId: newId(), service, at: this.at() });
146
+ }
147
+ /** A peer's row lands only when it verifies under the pinned key of the machine it names. */
148
+ ingestReplicated(raw) {
149
+ const row = validateRow(raw);
150
+ if (!row)
151
+ return 'invalid';
152
+ if (this.rows.has(row.eventId))
153
+ return 'duplicate';
154
+ if (this.rows.size >= MAX_ROWS)
155
+ return 'full';
156
+ const { sig, ...unsigned } = row;
157
+ const verdict = verifyMachineSignature(this.opts.keyLookup, { machineId: row.machineId, signerKeyHash: row.signerKeyHash, sig }, ledgerRowPayload(unsigned), Date.parse(row.at));
158
+ if (verdict === 'bad')
159
+ return 'bad-signature';
160
+ if (verdict !== 'ok')
161
+ return 'unverifiable';
162
+ this.store(row);
163
+ return 'added';
164
+ }
165
+ appendChoice(input) {
166
+ return this.signAndStore({
167
+ type: 'choice', eventId: newId(), service: input.service, choice: input.choice, shutdown: input.shutdown,
168
+ reason: input.reason, origin: input.origin, offerTextHash: input.offerTextHash ?? '', supersedes: input.supersedes, at: this.at(),
169
+ });
170
+ }
171
+ signAndStore(fields) {
172
+ const unsigned = { ...fields, machineId: this.opts.signer.machineId(), signerKeyHash: this.opts.signer.signerKeyHash() };
173
+ const { sig } = this.opts.signer.sign(ledgerRowPayload(unsigned));
174
+ const row = validateRow({ ...unsigned, sig });
175
+ if (!row)
176
+ throw new Error('recommended-services: refused to write a malformed row');
177
+ this.store(row);
178
+ this.hook?.(row);
179
+ return row;
180
+ }
181
+ store(row) {
182
+ fs.mkdirSync(path.dirname(this.file), { recursive: true });
183
+ fs.appendFileSync(this.file, `${JSON.stringify(row)}\n`);
184
+ this.rows.set(row.eventId, row);
185
+ }
186
+ at() {
187
+ return (this.opts.now?.() ?? new Date()).toISOString();
188
+ }
189
+ }
190
+ function newId() {
191
+ return crypto.randomBytes(16).toString('hex');
192
+ }
193
+ //# sourceMappingURL=RecommendedServicesLedger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendedServicesLedger.js","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { StoreFieldSchema } from '../core/ReplicatedRecordEnvelope.js';
2
+ import type { HlcTimestamp } from '../core/HybridLogicalClock.js';
3
+ import { type LedgerRow } from './RecommendedServicesLedger.js';
4
+ export declare const RECOMMENDED_SERVICE_RECORD_KIND = "recommended-service-record";
5
+ export declare const RECOMMENDED_SERVICES_STORE_KEY = "recommendedServices";
6
+ export declare function deriveRecommendedServiceRecordKey(eventId: string): string;
7
+ export declare const recommendedServiceStoreSchema: StoreFieldSchema;
8
+ export declare function buildRecommendedServiceRecordData(row: LedgerRow): (hlc: HlcTimestamp, origin: string, observed?: HlcTimestamp) => Record<string, unknown> | null;
9
+ export declare const RECOMMENDED_SERVICES_KIND_REGISTRATION: {
10
+ readonly kind: "recommended-service-record";
11
+ readonly store: "recommendedServices";
12
+ readonly schema: StoreFieldSchema;
13
+ };
14
+ //# sourceMappingURL=RecommendedServicesReplicatedStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendedServicesReplicatedStore.d.ts","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesReplicatedStore.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAsC,MAAM,qCAAqC,CAAC;AAChH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAE7E,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAC5E,eAAO,MAAM,8BAA8B,wBAAwB,CAAC;AAIpE,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,eAAO,MAAM,6BAA6B,EAAE,gBAM3C,CAAC;AAEF,wBAAgB,iCAAiC,CAAC,GAAG,EAAE,SAAS,SACjD,YAAY,UAAU,MAAM,aAAa,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMpG;AAED,eAAO,MAAM,sCAAsC;aACjD,IAAI;aACJ,KAAK;aACL,MAAM;CACE,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The `recommendedServices` replicated-store kind (docs/specs/recommended-services.md,
3
+ * Multi-machine posture). Rows are immutable and keyed by eventId, so the union has no
4
+ * conflicts. The ledger verifies each row's signature before it lands.
5
+ */
6
+ import crypto from 'node:crypto';
7
+ import { validateRow } from './RecommendedServicesLedger.js';
8
+ export const RECOMMENDED_SERVICE_RECORD_KIND = 'recommended-service-record';
9
+ export const RECOMMENDED_SERVICES_STORE_KEY = 'recommendedServices';
10
+ const KNOWN = ['row'];
11
+ export function deriveRecommendedServiceRecordKey(eventId) {
12
+ return crypto.createHash('sha256').update(`recommended-services\u0000${eventId}`).digest('hex');
13
+ }
14
+ export const recommendedServiceStoreSchema = {
15
+ knownFields: KNOWN,
16
+ validate(raw, _ctx) {
17
+ const row = validateRow(raw.row);
18
+ return row ? { row } : null;
19
+ },
20
+ };
21
+ export function buildRecommendedServiceRecordData(row) {
22
+ return (hlc, origin, observed) => ({
23
+ row,
24
+ recordKey: deriveRecommendedServiceRecordKey(row.eventId),
25
+ hlc, op: 'put', origin,
26
+ ...(observed !== undefined ? { observed } : {}),
27
+ });
28
+ }
29
+ export const RECOMMENDED_SERVICES_KIND_REGISTRATION = {
30
+ kind: RECOMMENDED_SERVICE_RECORD_KIND,
31
+ store: RECOMMENDED_SERVICES_STORE_KEY,
32
+ schema: recommendedServiceStoreSchema,
33
+ };
34
+ //# sourceMappingURL=RecommendedServicesReplicatedStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendedServicesReplicatedStore.js","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesReplicatedStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAkB,MAAM,gCAAgC,CAAC;AAE7E,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAC5E,MAAM,CAAC,MAAM,8BAA8B,GAAG,qBAAqB,CAAC;AAEpE,MAAM,KAAK,GAAG,CAAC,KAAK,CAAU,CAAC;AAE/B,MAAM,UAAU,iCAAiC,CAAC,OAAe;IAC/D,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAqB;IAC7D,WAAW,EAAE,KAAyC;IACtD,QAAQ,CAAC,GAAsC,EAAE,IAA0B;QACzE,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,iCAAiC,CAAC,GAAc;IAC9D,OAAO,CAAC,GAAiB,EAAE,MAAc,EAAE,QAAuB,EAAkC,EAAE,CAAC,CAAC;QACtG,GAAG;QACH,SAAS,EAAE,iCAAiC,CAAC,GAAG,CAAC,OAAO,CAAC;QACzD,GAAG,EAAE,EAAE,EAAE,KAAqB,EAAE,MAAM;QACtC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,IAAI,EAAE,+BAA+B;IACrC,KAAK,EAAE,8BAA8B;IACrC,MAAM,EAAE,6BAA6B;CAC7B,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Maps the two old features whose offers these services replace
3
+ * (docs/specs/recommended-services.md, Store and Offers). The old offer paths refuse these ids
4
+ * in every state, and a person's old decline carries over as an import.
5
+ */
6
+ import type { RecommendedServicesLedger } from './RecommendedServicesLedger.js';
7
+ export declare const LEGACY_FEATURE_TO_SERVICE: Readonly<Record<string, string>>;
8
+ export declare function isRetiredLegacyOffer(featureId: string): boolean;
9
+ /** Import old declines before any list is built. Safe to run at every boot. */
10
+ export declare function importLegacyDeclines(ledger: RecommendedServicesLedger, stateOf: (featureId: string) => string | null): number;
11
+ //# sourceMappingURL=legacyDeclines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacyDeclines.d.ts","sourceRoot":"","sources":["../../src/recommended/legacyDeclines.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrE,CAAC;AAEH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,yBAAyB,EACjC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAC5C,MAAM,CAMR"}
@@ -0,0 +1,17 @@
1
+ export const LEGACY_FEATURE_TO_SERVICE = Object.freeze({
2
+ 'cloudflare-tunnel': 'cloudflare-domain',
3
+ 'git-backup': 'github-state-backup',
4
+ });
5
+ export function isRetiredLegacyOffer(featureId) {
6
+ return Object.prototype.hasOwnProperty.call(LEGACY_FEATURE_TO_SERVICE, featureId);
7
+ }
8
+ /** Import old declines before any list is built. Safe to run at every boot. */
9
+ export function importLegacyDeclines(ledger, stateOf) {
10
+ let imported = 0;
11
+ for (const [featureId, service] of Object.entries(LEGACY_FEATURE_TO_SERVICE)) {
12
+ if (stateOf(featureId) === 'declined' && ledger.recordLegacyImport(service))
13
+ imported += 1;
14
+ }
15
+ return imported;
16
+ }
17
+ //# sourceMappingURL=legacyDeclines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacyDeclines.js","sourceRoot":"","sources":["../../src/recommended/legacyDeclines.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,yBAAyB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACvF,mBAAmB,EAAE,mBAAmB;IACxC,YAAY,EAAE,qBAAqB;CACpC,CAAC,CAAC;AAEH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;AACpF,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAClC,MAAiC,EACjC,OAA6C;IAE7C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC7E,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,UAAU,IAAI,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC;YAAE,QAAQ,IAAI,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The services a person can choose about (docs/specs/recommended-services.md, The catalog). */
2
+ export declare const RECOMMENDED_SERVICE_IDS: readonly string[];
3
+ //# sourceMappingURL=serviceIds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serviceIds.d.ts","sourceRoot":"","sources":["../../src/recommended/serviceIds.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAGnD,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** The services a person can choose about (docs/specs/recommended-services.md, The catalog). */
2
+ export const RECOMMENDED_SERVICE_IDS = Object.freeze([
3
+ 'tailscale', 'cloudflare-domain', 'telegram', 'jev', 'bitwarden',
4
+ 'github-state-backup', 'second-ai-door', 'voice-transcription', 'email',
5
+ ]);
6
+ //# sourceMappingURL=serviceIds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serviceIds.js","sourceRoot":"","sources":["../../src/recommended/serviceIds.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,uBAAuB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACtE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAChE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,OAAO;CACxE,CAAC,CAAC"}
@@ -118,6 +118,8 @@ export declare const REROUTED_LOGIN_EXPIRED_MARKER = "A job session stuck at an
118
118
  /** Rerouted-job expired-login awareness bullet. Shared by the generated CLAUDE.md and PostUpdateMigrator. */
119
119
  export declare const REROUTED_LOGIN_EXPIRED_BULLET = "- **A job session stuck at an expired login is ended in minutes**: a scheduled job (or other one-shot) that runs as an interactive Claude session and lands under a login whose sign-in has expired shows `Login expired \u00B7 Please run /login` and can do nothing. The monitor now ends it about a minute after it first sees that screen (reason `rerouted-login-expired`, a `SessionManager.monitorTick.reroutedLoginExpired` degradation naming the login folder) instead of letting it hold a job slot for the full 8-hour lifetime; the job runs again on its next trigger. It also reports the sighting to the quota poller, which alone decides pool status: when that screen is Claude Code's own message line and the login's saved credential still reads, the account turns needs-reauth at once (cause `cli-login-expired-observed`) and the automatic sign-in repair starts; when the saved credential cannot be read, it takes two different sessions under that login showing the screen within an hour. If a user asks \"why did my scheduled jobs stop running?\" or \"why did a job end straight away?\" \u2014 check `GET /jobs` for a stale `nextScheduled`, then the server log for `stuck at an expired login`; the fix is signing that login in again.";
120
120
  /** Content-sniff marker for the interactive expired-login bullet (CMT-1008, Migration Parity). */
121
+ export declare const CLAUDE_KEY_HEALTH_MARKER = "A rejected sign-in key is told and recovers";
122
+ export declare const CLAUDE_KEY_HEALTH_BULLET = "- **A rejected sign-in key is told and recovers**: an agent signed in with one key (`sessions.credentials.anthropic`, the usual cloud install) passes that key to every Claude process on the server, including internal model calls. If Anthropic refuses the key twice, the operator gets one plain notice, each waiting person is told once, and `GET /health` (with the auth header) shows `claudeKey.status: dead`. The fix is a new key from `claude setup-token`, put in place with `instar set-claude-key` on the server (reads stdin or a hidden prompt, never an argument; never ask for the key in chat). Within a minute Instar checks it, and conversations stuck at the login screen restart by themselves and answer what they missed. A conversation that ended during the outage is not replayed. **When to use** (PROACTIVE): the user asks \"why did you stop replying?\" or \"why does health say the model is failing?\" \u2192 read `claudeKey` in `GET /health`. Off switches: `sessions.claudeKeyHealth.enabled: false` and `sessions.claudeChildAuth.enabled: false`.";
121
123
  export declare const INTERACTIVE_LOGIN_EXPIRED_MARKER = "A conversation stuck at an expired login moves to a signed-in account";
122
124
  /** Interactive expired-login awareness bullet (CMT-1008). Shared by the generated CLAUDE.md and PostUpdateMigrator. */
123
125
  export declare const INTERACTIVE_LOGIN_EXPIRED_BULLET = "- **A conversation stuck at an expired login moves to a signed-in account**: a Telegram/topic session placed on a pool login whose Claude sign-in has expired shows `Login expired \u00B7 Please run /login` (newer Claude Code: `Not logged in \u00B7 Run /login`) on every turn. About a minute after the monitor first sees that screen in the session's live tail it (1) marks that account needs-reauth (cause `cli-login-expired-observed`, so new sessions avoid it and the automatic sign-in repair can start) \u2014 even when the saved token still reads quota, because the CLI's own screen is the stronger evidence, and a later quota poll does not flip it back while the saved credential is unchanged (a sign-in repair, or you setting it active again, always wins); and (2) resumes the session on a signed-in account through the same swap as `POST /subscription-pool/swap` (conversation preserved; one attempt per session per 10 minutes, at most three; protected sessions are never moved). Only Claude Code's own message line counts: a stale mention scrolled up the screen, a message quoting the text, or a tool result such as `claude auth status` printing it never triggers it. If the login's saved credential cannot be read at all (e.g. a locked keychain), one screen is not enough and the session is not moved until the account is confirmed dead. Off switch for the swap only: `subscriptionPool.loginExpiredSwap.enabled: false` (read live). If a user asks \"why did my conversation suddenly switch accounts?\" or \"why is this account showing needs sign-in when its quota looks fine?\" \u2014 check the server log for `stuck at an expired login` and `[LoginExpiredRecovery]`; a failed swap also reports a `SessionManager.monitorTick.interactiveLoginExpired` degradation. The fix for the account itself is signing that login in again.";
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,10 @@ import { JOB_DECLARED_FAILURE_AWARENESS } from "../scheduler/jobDeclaredFailure.
19
19
  // function call inside generateClaudeMd — no module-init cycle (PostUpdateMigrator
20
20
  // never imports templates).
21
21
  import { APPRENTICESHIP_STALL_GATE_CLAUDEMD_SECTION, SESSION_LISTING_HYGIENE_CLAUDEMD_SECTION, PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION, MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION, CODEX_CONNECT_CLAUDEMD_SECTION, FEATURE_SWITCH_CLAUDEMD_SECTION, NORMAL_CHROME_BROWSER_CLAUDEMD_SECTION, SINGLE_MACHINE_FAILOVER_GAP_CLAUDEMD_SECTION, MISSING_LOGIN_SESSION_CLAUDEMD_SECTION, DYNAMIC_MCP_CLAUDEMD_SECTION, ULTRACODE_SPAWN_CLAUDEMD_SECTION, AGENT_SIGNATURE_PROVENANCE_CLAUDEMD_SECTION, SENDER_REJECTION_CLAUDEMD_SECTION, SCOPE_ACCRETION_CLAUDEMD_SECTION, MESH_SELF_HEALING_CLAUDEMD_SECTION, LEASE_MEDIUM_CLAUDEMD_SECTION, WRITE_ADMISSION_CLAUDEMD_SECTION, DOORWAY_REGISTRY_CLAUDEMD_SECTION, EXTERNAL_HOG_CLAUDEMD_SECTION, ROUTING_SPEND_CLAUDEMD_SECTION, MATURATION_BOARD_CLAUDEMD_SECTION, MATURATION_LADDER_CLAUDEMD_SECTION, QUEUE_PACE_CLAUDEMD_SECTION, ECOSYSTEM_IDEAS_CLAUDEMD_SECTION, MOBILE_PAIRING_CLAUDEMD_SECTION, MOBILE_CHAT_CLAUDEMD_SECTION, APP_CONVERSATIONS_CLAUDEMD_SECTION, MOBILE_ROUTES_CLAUDEMD_SECTION, MOBILE_PUSH_CLAUDEMD_SECTION, MOBILE_PEOPLE_CLAUDEMD_SECTION, DECISION_QUALITY_CLAUDEMD_SECTION, BENCHMARK_DIVERGENCE_CLAUDEMD_SECTION, DUPLICATE_RECONCILER_CLAUDEMD_SECTION, AUDIT_CONVERGENCE_CLAUDEMD_SECTION, TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION, DECISION_JOURNAL_CONFIDENCE_CLAUDEMD_GUIDANCE, WINDOW_RUN_LIVENESS_CLAUDEMD_SECTION, SCRIPT_JOBS_CLAUDEMD_SECTION, SESSION_HANDOFF_CLAUDEMD_SECTION, JOB_RESULT_SUPERVISION_CLAUDEMD_SECTION, DEDICATED_PROFILE_REGISTRY_ROW_ANSWER, CODEX_ARM_SWEEPER_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_CLAUDEMD_SECTION, APP_MEDIA_CLAUDEMD_SECTION, MACHINE_BROWSER_CARE_CLAUDEMD_SECTION, PAIRING_WITHOUT_TELEGRAM_CLAUDEMD_SECTION, SLACK_FROM_APP_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_POOL_CLAUDEMD_SECTION, MACHINE_WEDGE_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
22
+ import { SURFACE_REFERRAL_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
23
+ import { RECOMMENDED_SERVICES_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
22
24
  import { MINIMUM_OPERATOR_EFFORT_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
25
+ import { POOL_READINESS_CLAUDE_MD_LINE } from '../core/PostUpdateMigrator.js';
23
26
  import { CODEX_DEVICE_LIMIT_CLAUDEMD_BULLET } from '../core/PostUpdateMigrator.js';
24
27
  import { UPDATE_APPLY_VERIFY_HOLD_CLAUDEMD_LINE } from '../core/PostUpdateMigrator.js';
25
28
  /**
@@ -417,6 +420,7 @@ ${REAPER_BACKGROUND_WORK_BULLET}
417
420
  ${STANDING_SESSIONS_BULLET}
418
421
  ${REROUTED_LOGIN_EXPIRED_BULLET}
419
422
  ${INTERACTIVE_LOGIN_EXPIRED_BULLET}
423
+ ${CLAUDE_KEY_HEALTH_BULLET}
420
424
  - **Busy-orphan detection** (\`busyOrphanDetection\`, OBSERVE-ONLY, dark by default; dev agents on): the inverse blind spot. CPU-progress is a proxy for "useful" — but a *useless* process that SPINS (a hot-loop, a wedged job burning CPU) looks "active" and would keep a session pinned. When an idle session (idle prompt + flat transcript) is held only by a child that's *burning* CPU across an extended dwell, the reaper records a \`busy-orphan-suspected\` audit row (and \`busy-orphan-cleared\` on recovery). It NEVER changes the keep/kill decision — it just makes the "useless-but-busy child pins an idle session" case measurable, so safe auto-reclaim can graduate later with data. Read \`logs/reaper-audit.jsonl\` (filter \`busy-orphan-suspected\`).
421
425
  - Why it matters: idle sessions pile up across agents until the machine starves (CPU *or* memory) and new sessions get "spawn denied" — silently breaking cross-agent messaging. This sweeps them, but only under real pressure.
422
426
  - See current state / why each session is kept or flagged: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/sessions/reaper\` (the \`pressure.inputs\` shows freePct, loadPerCore, \`cpuBusyPct\` — real sampled CPU busy %, the signal that decides \`cpuTier\` since reaper-pressure-signals; the 1-min load average is reported but no longer decisive, because it read 9.4/core at 36-44% idle (its macOS computation is poorly documented; the measured disagreement is the evidence) — plus the compressor OBSERVABLES \`compressorPct\`, \`decompressionsPerSec\` and \`kernelMemoryPressureLevel\` (reported, grading nothing: none of them separated that laptop from a healthy machine when measured) — plus \`cpuSignal\`, \`sampledAt\`, \`windowMs\` and the memTier/cpuTier breakdown. A CPU figure appears only once a full 30 s window has elapsed; shorter is \`null\` (unknown ⇒ memory-only), never a startup spike. Rollback lever: \`monitoring.sessionReaper.cpuSignal: 'load'\` restores the legacy grading exactly; the busy thresholds are \`cpuModerateBusyPct\`/\`cpuCriticalBusyPct\` (75/90), and there are no compressor thresholds because no compressor grade ships). On a machine pool, add \`?scope=pool\` to get every machine's snapshot; the local snapshot stays at the top level and \`pool.machines\` carries peers. A dark, old, unreachable, or malformed peer is a classified \`pool.failed\` row — never a 500 or a silently local-looking answer.
@@ -604,7 +608,8 @@ Two layers keep my machine-to-machine \"ropes\" (Tailscale / LAN / Cloudflare) h
604
608
  - **Idle vs broken machine (WS4.2):** the same \`pool.machines[]\` carries an explicit per-machine state so an idle machine never reads as broken. A machine with ZERO sessions gets \`pool.machines[].emptyState\` = \`online — no active sessions\` (heartbeat-fresh, just idle) / \`offline since <t>\` (known offline) / \`unreachable (last seen <t>)\` (was online, now not answering — the \`failed\` case). Honest derivation from the registry online flag + last-seen + the live fan-out — never a fabricated "looks fine". The dashboard sessions view renders these per-machine; a machine WITH sessions gets no empty-state (its tiles already name it). Single-machine install = just the lone self row.
605
609
  - **Honest machine state (trustworthy-machine-load, P1):** every \`pool.machines[]\` row now carries \`liveness\` = \`live\` / \`unreachable\` (shape \`struggling\` | \`refusing\` | \`silent\`) / \`stale\` / \`unknown\`, each with the evidence age and source, plus a ready-made \`livenessLine\` (\`<liveness>, last evidence <age> ago from <source>\`) and the freshest other-machine sighting ("Mac Mini reached it 3 min ago"). The last DIRECT contact is saved to disk, so a server restart renders \`stale, last evidence 20 min ago\` instead of "offline". **Never say a machine is "offline" without positive evidence** (a shutdown announcement or the sleep gate): quote the liveness, its age and its source — an overloaded machine looks exactly like a dead one to a plain timeout. Each row also carries a multi-signal \`loadReport\` (cores, CPU idle, available memory, native memory pressure, server event-loop lag, sessions in use) and \`loadVerdict\` = \`ok\` / \`elevated\` / \`saturated\` / \`impaired\` / \`unknown\` — a report older than 60 s reads \`unknown\`, and a peer on older code reads \`unknown\`, never \`ok\`. Reporting only: the \`online\` flag, placement and ownership keep their existing semantics in this phase.
606
610
  - **Overload admission (trustworthy-machine-load, P2):** each machine protects its own resources. When its own \`loadVerdict\` is \`saturated\` or \`impaired\` it CLOSES to new automatic work (scheduled jobs, helpers, placement of new conversations): the work waits and is retried, nothing is dropped, and existing conversations keep working. It reopens after five consecutive good samples (about 75 s). One host-wide **recovery slot** (shared by every agent on the machine) stays free so a session the operator asks for can always start and assess the machine. Placement never puts new work on a machine that is refusing it; if every machine refuses, the message stays in the durable inbound queue (\`all-machines-refusing-work\`). Registry First: \`GET /work-admission\` → \`{ enabled, dryRun, enforced, acceptingWork, lastVerdict, recoverySlot, counters }\`; each machine's \`loadReport.acceptingWork\` / \`admissionEnforced\` in \`GET /pool\`; audit \`logs/work-admission.jsonl\`. Ships dev-gated + dry-run (\`monitoring.workAdmission\`: it logs what it WOULD refuse, refuses nothing, and peers keep placing work here until \`dryRun:false\`). When the user asks "why didn't a job run / why is this machine not taking work?" → read \`GET /work-admission\` before guessing.
607
- - **Overload shed (trustworthy-machine-load, P3):** a machine that has refused new work for 3 minutes moves its EXISTING conversations off, one at a time, to a healthy machine (direct contact under 2 min, \`loadVerdict\` \`ok\`, not refusing work, at least 2 free session slots after what it has already reserved there). The move is an ordinary cooperative ownership transfer through the reconciler, like a pin move but never written as a pin. Pinned conversations, Slack conversations and conversations with a live autonomous run stay. Brakes: at most 2 moves an hour, 2 tries per conversation per overload episode, the same conversation is not moved again for 30 min, and a machine seen refusing work in the last 30 min never receives moved work. A started transfer is driven to claim or cancelled after its deadline even if the plan behind it is gone. Stale-owner notices say "struggling" or "refusing" when that is the evidence. Registry First: \`GET /overload-shed\` → \`{ enabled, dryRun, overloadedSince, isSource, liveMove, reservations, movesLastHour, counters }\`; audit \`logs/overload-shed.jsonl\`. Ships dev-gated + dry-run (\`monitoring.overloadShed\`: it logs what it WOULD move, moves nothing, and also moves nothing while overload admission is in dry-run). When the user asks "why did my conversation move machines?" or "why is this overloaded machine still holding work?" → read \`GET /overload-shed\` before guessing.
611
+ ${POOL_READINESS_CLAUDE_MD_LINE}
612
+ - **Overload shed (trustworthy-machine-load, P3):** a machine that has refused new work for 3 minutes AND is at 85% or more of its session limit moves a conversation off, one at a time, to a healthy machine (direct contact under 2 min, \`loadVerdict\` \`ok\`, not refusing work, at least 2 free session slots after what it has already reserved there). Only conversations with a running session that has sat quiet for 10 minutes move, so this frees session slots and memory, not CPU. The move goes through the same drain as a manual transfer: the session here closes and the conversation carries on there at its next message. Pinned conversations, Slack conversations and conversations with a live autonomous run stay. Brakes: at most 2 moves an hour, 2 tries per conversation per overload episode, a moved conversation stays put for 6 hours wherever it landed, and a machine seen refusing work in the last 30 min never receives moved work. Live moves need pool stage \`rebalance\`, a fresh rebalance proof on this machine, and \`dryRun: false\`; otherwise it only logs what it WOULD move. Each machine earns its proof with \`POST /session-pool/rebalance-proof\` \`{ topic, to }\` (202 with a run id; \`GET /session-pool/rebalance-proof/RUN_ID\` for the result), which really moves a topic listed in \`multiMachine.sessionPool.rebalanceProofTopics\` and passes only if the old session is gone and the target answers once. A proof lasts 30 days; without a fresh one the stage steps down to \`live-transfer\`. Stale-owner notices say "struggling" or "refusing" when that is the evidence. Registry First: \`GET /overload-shed\` → \`{ enabled, dryRun, overloadedSince, isSource, liveMove, reservations, movesLastHour, counters }\`; audit \`logs/overload-shed.jsonl\` (\`would-move\` and \`move-outcome\` rows carry the numbers behind each decision). Ships dev-gated + dry-run (\`monitoring.overloadShed\`). When the user asks "why did my conversation move machines?" or "why is this overloaded machine still holding work?" → read \`GET /overload-shed\` before guessing.
608
613
  - **Post-transfer closeout (automatic):** when a topic moves to another machine, the OLD machine's session for it is closed automatically (closed by the transfer's drain step when the current machine can drain, otherwise within ~2 reaper ticks) — no duplicate sessions doing duplicate work. The close is recorded in the reap-log with reason "topic moved to <machine>"; protected sessions are never auto-closed.
609
614
  - **Quota-aware placement (automatic):** capacity heartbeats carry each machine's LLM-account quota state, and placement avoids machines whose account is currently rate-limited/blocked (no more topics placed onto a silent machine). A hard pin still wins (flagged \`pinned-machine-quota-blocked\`); if EVERY machine is blocked, placement proceeds least-loaded with \`all-machines-quota-blocked\` flagged. \`GET /pool\` shows each machine's \`quotaState\`.
610
615
  - **Signed-out machines are skipped (automatic):** the same heartbeat also says whether the machine has any signed-in account for the framework new conversations run on (from its subscription pool). A machine where every such account needs sign-in reports \`quotaState.reason: no-signed-in-account\`, and placement sends new conversations elsewhere instead of to a session that would sit at "Not logged in". A hard pin still wins (flagged \`pinned-machine-not-signed-in\`). Unknown (no pool, or no account for that framework) never blocks. When the user asks "why did my new topic go silent / land on a machine that can't log in?" → read that machine's \`quotaState\` in \`GET /pool\`.
@@ -1021,6 +1026,7 @@ ${ROUTING_SPEND_CLAUDEMD_SECTION(port)}
1021
1026
  ${MATURATION_BOARD_CLAUDEMD_SECTION(port)}
1022
1027
  ${MATURATION_LADDER_CLAUDEMD_SECTION(port)}
1023
1028
  ${QUEUE_PACE_CLAUDEMD_SECTION(port)}
1029
+ ${RECOMMENDED_SERVICES_CLAUDEMD_SECTION(port)}
1024
1030
  ${ECOSYSTEM_IDEAS_CLAUDEMD_SECTION(port)}
1025
1031
  ${MOBILE_PAIRING_CLAUDEMD_SECTION(port)}
1026
1032
  ${MOBILE_CHAT_CLAUDEMD_SECTION(port)}
@@ -1822,6 +1828,8 @@ Record what I learn. Build infrastructure, not one-offs. Grow to meet the user's
1822
1828
  Your messages to the user pass an always-on LLM gate (the tone gate) before they send. It reviews high-stakes leaks (CLI commands, file paths, config keys, endpoints) AND the self-stop anti-patterns (B15–B19: quitting on yourself for a context/fatigue reason, calling a doable thing impossible, parking your own work on the user). The two families are treated DIFFERENTLY — the leak/representation rules are overridable nudges (see below); the self-stop family stays a hard block, because there the check exists to constrain YOU and your reason for overriding would come from the very reasoning it distrusts. It judges the behavioral rules **by MEANING, not by literal phrases — a paraphrase of the anti-pattern is caught exactly the same as the canonical wording**, so do not assume rewording evades it. The gate FAILS CLOSED (holds the message, queued for retry — never silently delivers) if it can't produce a verdict (provider down, unparseable output, or a slow-review timeout); the operator kill-switch is \`toneGate.failClosedOnExhaustion\`. Constitution: "Intelligent Prompts — An LLM Gate Must Not String-Match".
1823
1829
 
1824
1830
  ${TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION}
1831
+
1832
+ ${SURFACE_REFERRAL_CLAUDEMD_SECTION}
1825
1833
  ### Context-Aware Outbound Review (why was my message flagged / would my reply have been blocked?)
1826
1834
 
1827
1835
  Beyond the tone gate, a response-review pipeline (nine specialist reviewers driven by a Stop hook) evaluates each finished conversational turn. On most installs it is OFF BY CONFIG — \`GET /review/history\` returns 501 there; say so honestly rather than guessing. Where it runs, it is usually in WATCH MODE (\`responseReview.observeOnly: true\`): verdicts are recorded, nothing is blocked. The context-aware layer (⚗️ experimental, dev-gated dark: \`responseReview.conversationalContext\`) feeds the opted-in reviewer a bounded, untrusted-data-enveloped slice of recent conversation so "the operator asked for this technical detail" is an input it can actually judge — a one-way carve-out (it can only move a would-block toward PASS, never license credentials/PII, never touch the deterministic policy layer).
@@ -2671,6 +2679,8 @@ export const REROUTED_LOGIN_EXPIRED_MARKER = 'A job session stuck at an expired
2671
2679
  /** Rerouted-job expired-login awareness bullet. Shared by the generated CLAUDE.md and PostUpdateMigrator. */
2672
2680
  export const REROUTED_LOGIN_EXPIRED_BULLET = `- **${REROUTED_LOGIN_EXPIRED_MARKER}**: a scheduled job (or other one-shot) that runs as an interactive Claude session and lands under a login whose sign-in has expired shows \`Login expired · Please run /login\` and can do nothing. The monitor now ends it about a minute after it first sees that screen (reason \`rerouted-login-expired\`, a \`SessionManager.monitorTick.reroutedLoginExpired\` degradation naming the login folder) instead of letting it hold a job slot for the full 8-hour lifetime; the job runs again on its next trigger. ${REROUTED_LOGIN_EXPIRED_POOL_SENTENCE} If a user asks "why did my scheduled jobs stop running?" or "why did a job end straight away?" — check \`GET /jobs\` for a stale \`nextScheduled\`, then the server log for \`stuck at an expired login\`; the fix is signing that login in again.`;
2673
2681
  /** Content-sniff marker for the interactive expired-login bullet (CMT-1008, Migration Parity). */
2682
+ export const CLAUDE_KEY_HEALTH_MARKER = 'A rejected sign-in key is told and recovers';
2683
+ export const CLAUDE_KEY_HEALTH_BULLET = `- **${CLAUDE_KEY_HEALTH_MARKER}**: an agent signed in with one key (\`sessions.credentials.anthropic\`, the usual cloud install) passes that key to every Claude process on the server, including internal model calls. If Anthropic refuses the key twice, the operator gets one plain notice, each waiting person is told once, and \`GET /health\` (with the auth header) shows \`claudeKey.status: dead\`. The fix is a new key from \`claude setup-token\`, put in place with \`instar set-claude-key\` on the server (reads stdin or a hidden prompt, never an argument; never ask for the key in chat). Within a minute Instar checks it, and conversations stuck at the login screen restart by themselves and answer what they missed. A conversation that ended during the outage is not replayed. **When to use** (PROACTIVE): the user asks "why did you stop replying?" or "why does health say the model is failing?" → read \`claudeKey\` in \`GET /health\`. Off switches: \`sessions.claudeKeyHealth.enabled: false\` and \`sessions.claudeChildAuth.enabled: false\`.`;
2674
2684
  export const INTERACTIVE_LOGIN_EXPIRED_MARKER = 'A conversation stuck at an expired login moves to a signed-in account';
2675
2685
  /** Interactive expired-login awareness bullet (CMT-1008). Shared by the generated CLAUDE.md and PostUpdateMigrator. */
2676
2686
  export const INTERACTIVE_LOGIN_EXPIRED_BULLET = `- **${INTERACTIVE_LOGIN_EXPIRED_MARKER}**: a Telegram/topic session placed on a pool login whose Claude sign-in has expired shows \`Login expired · Please run /login\` (newer Claude Code: \`Not logged in · Run /login\`) on every turn. About a minute after the monitor first sees that screen in the session's live tail it (1) marks that account needs-reauth (cause \`cli-login-expired-observed\`, so new sessions avoid it and the automatic sign-in repair can start) — even when the saved token still reads quota, because the CLI's own screen is the stronger evidence, and a later quota poll does not flip it back while the saved credential is unchanged (a sign-in repair, or you setting it active again, always wins); and (2) resumes the session on a signed-in account through the same swap as \`POST /subscription-pool/swap\` (conversation preserved; one attempt per session per 10 minutes, at most three; protected sessions are never moved). Only Claude Code's own message line counts: a stale mention scrolled up the screen, a message quoting the text, or a tool result such as \`claude auth status\` printing it never triggers it. If the login's saved credential cannot be read at all (e.g. a locked keychain), one screen is not enough and the session is not moved until the account is confirmed dead. Off switch for the swap only: \`subscriptionPool.loginExpiredSwap.enabled: false\` (read live). If a user asks "why did my conversation suddenly switch accounts?" or "why is this account showing needs sign-in when its quota looks fine?" — check the server log for \`stuck at an expired login\` and \`[LoginExpiredRecovery]\`; a failed swap also reports a \`SessionManager.monitorTick.interactiveLoginExpired\` degradation. The fix for the account itself is signing that login in again.`;