instar 1.3.1649 → 1.3.1650

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 (451) 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/reflect.d.ts.map +1 -1
  24. package/dist/commands/reflect.js +2 -0
  25. package/dist/commands/reflect.js.map +1 -1
  26. package/dist/commands/route.d.ts.map +1 -1
  27. package/dist/commands/route.js +2 -0
  28. package/dist/commands/route.js.map +1 -1
  29. package/dist/commands/server.d.ts.map +1 -1
  30. package/dist/commands/server.js +315 -14
  31. package/dist/commands/server.js.map +1 -1
  32. package/dist/commands/setClaudeKey.d.ts +8 -0
  33. package/dist/commands/setClaudeKey.d.ts.map +1 -0
  34. package/dist/commands/setClaudeKey.js +35 -0
  35. package/dist/commands/setClaudeKey.js.map +1 -0
  36. package/dist/core/AccountFollowMeOrchestrator.d.ts.map +1 -1
  37. package/dist/core/AccountFollowMeOrchestrator.js +4 -0
  38. package/dist/core/AccountFollowMeOrchestrator.js.map +1 -1
  39. package/dist/core/AppMediaStore.d.ts.map +1 -1
  40. package/dist/core/AppMediaStore.js +3 -0
  41. package/dist/core/AppMediaStore.js.map +1 -1
  42. package/dist/core/BackupManager.d.ts.map +1 -1
  43. package/dist/core/BackupManager.js +2 -0
  44. package/dist/core/BackupManager.js.map +1 -1
  45. package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -1
  46. package/dist/core/ClaudeCliIntelligenceProvider.js +11 -3
  47. package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -1
  48. package/dist/core/ClaudeKeyHealth.d.ts +141 -0
  49. package/dist/core/ClaudeKeyHealth.d.ts.map +1 -0
  50. package/dist/core/ClaudeKeyHealth.js +467 -0
  51. package/dist/core/ClaudeKeyHealth.js.map +1 -0
  52. package/dist/core/CodexTaskContinuationStore.d.ts.map +1 -1
  53. package/dist/core/CodexTaskContinuationStore.js +7 -0
  54. package/dist/core/CodexTaskContinuationStore.js.map +1 -1
  55. package/dist/core/CoherenceJournal.d.ts +1 -1
  56. package/dist/core/CoherenceJournal.d.ts.map +1 -1
  57. package/dist/core/CoherenceJournal.js +11 -2
  58. package/dist/core/CoherenceJournal.js.map +1 -1
  59. package/dist/core/Config.d.ts +8 -0
  60. package/dist/core/Config.d.ts.map +1 -1
  61. package/dist/core/Config.js +26 -0
  62. package/dist/core/Config.js.map +1 -1
  63. package/dist/core/CredentialSwapExecutor.d.ts.map +1 -1
  64. package/dist/core/CredentialSwapExecutor.js +10 -0
  65. package/dist/core/CredentialSwapExecutor.js.map +1 -1
  66. package/dist/core/DecisionQualityRecorderImpl.d.ts.map +1 -1
  67. package/dist/core/DecisionQualityRecorderImpl.js +6 -0
  68. package/dist/core/DecisionQualityRecorderImpl.js.map +1 -1
  69. package/dist/core/DiscoveryEvaluator.d.ts.map +1 -1
  70. package/dist/core/DiscoveryEvaluator.js +4 -0
  71. package/dist/core/DiscoveryEvaluator.js.map +1 -1
  72. package/dist/core/IdentityReannounceClaimant.d.ts.map +1 -1
  73. package/dist/core/IdentityReannounceClaimant.js +4 -0
  74. package/dist/core/IdentityReannounceClaimant.js.map +1 -1
  75. package/dist/core/IntelligenceRouter.d.ts.map +1 -1
  76. package/dist/core/IntelligenceRouter.js +9 -0
  77. package/dist/core/IntelligenceRouter.js.map +1 -1
  78. package/dist/core/JournalSyncApplier.d.ts +1 -0
  79. package/dist/core/JournalSyncApplier.d.ts.map +1 -1
  80. package/dist/core/JournalSyncApplier.js +48 -0
  81. package/dist/core/JournalSyncApplier.js.map +1 -1
  82. package/dist/core/LeaseCoordinator.d.ts +4 -0
  83. package/dist/core/LeaseCoordinator.d.ts.map +1 -1
  84. package/dist/core/LeaseCoordinator.js +64 -1
  85. package/dist/core/LeaseCoordinator.js.map +1 -1
  86. package/dist/core/MessagingToneGate.d.ts +11 -7
  87. package/dist/core/MessagingToneGate.d.ts.map +1 -1
  88. package/dist/core/MessagingToneGate.js +15 -1
  89. package/dist/core/MessagingToneGate.js.map +1 -1
  90. package/dist/core/MobileDeviceKeys.d.ts +10 -0
  91. package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
  92. package/dist/core/MobileDeviceKeys.js +17 -0
  93. package/dist/core/MobileDeviceKeys.js.map +1 -1
  94. package/dist/core/MultiMachineCoordinator.d.ts +12 -0
  95. package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
  96. package/dist/core/MultiMachineCoordinator.js +115 -3
  97. package/dist/core/MultiMachineCoordinator.js.map +1 -1
  98. package/dist/core/MutualSshRuntime.d.ts +1 -0
  99. package/dist/core/MutualSshRuntime.d.ts.map +1 -1
  100. package/dist/core/MutualSshRuntime.js +17 -1
  101. package/dist/core/MutualSshRuntime.js.map +1 -1
  102. package/dist/core/ObservedEndpointTracker.d.ts +1 -0
  103. package/dist/core/ObservedEndpointTracker.d.ts.map +1 -1
  104. package/dist/core/ObservedEndpointTracker.js +17 -0
  105. package/dist/core/ObservedEndpointTracker.js.map +1 -1
  106. package/dist/core/OverloadShedPlanner.d.ts.map +1 -1
  107. package/dist/core/OverloadShedPlanner.js +9 -0
  108. package/dist/core/OverloadShedPlanner.js.map +1 -1
  109. package/dist/core/OwnershipApplier.d.ts.map +1 -1
  110. package/dist/core/OwnershipApplier.js +7 -0
  111. package/dist/core/OwnershipApplier.js.map +1 -1
  112. package/dist/core/OwnershipReconciler.d.ts.map +1 -1
  113. package/dist/core/OwnershipReconciler.js +5 -0
  114. package/dist/core/OwnershipReconciler.js.map +1 -1
  115. package/dist/core/PostUpdateMigrator.d.ts +8 -0
  116. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  117. package/dist/core/PostUpdateMigrator.js +76 -2
  118. package/dist/core/PostUpdateMigrator.js.map +1 -1
  119. package/dist/core/PrHandLease.d.ts.map +1 -1
  120. package/dist/core/PrHandLease.js +2 -0
  121. package/dist/core/PrHandLease.js.map +1 -1
  122. package/dist/core/ProactiveSwapMonitor.d.ts.map +1 -1
  123. package/dist/core/ProactiveSwapMonitor.js +7 -0
  124. package/dist/core/ProactiveSwapMonitor.js.map +1 -1
  125. package/dist/core/ProjectRoundExecution.d.ts.map +1 -1
  126. package/dist/core/ProjectRoundExecution.js +3 -2
  127. package/dist/core/ProjectRoundExecution.js.map +1 -1
  128. package/dist/core/QueueDrainLoop.d.ts +7 -0
  129. package/dist/core/QueueDrainLoop.d.ts.map +1 -1
  130. package/dist/core/QueueDrainLoop.js +37 -1
  131. package/dist/core/QueueDrainLoop.js.map +1 -1
  132. package/dist/core/RemoteAckStore.d.ts.map +1 -1
  133. package/dist/core/RemoteAckStore.js +4 -0
  134. package/dist/core/RemoteAckStore.js.map +1 -1
  135. package/dist/core/ReplicatedStoreReconcilerWiring.d.ts.map +1 -1
  136. package/dist/core/ReplicatedStoreReconcilerWiring.js +1 -0
  137. package/dist/core/ReplicatedStoreReconcilerWiring.js.map +1 -1
  138. package/dist/core/SecretSync.d.ts +1 -0
  139. package/dist/core/SecretSync.d.ts.map +1 -1
  140. package/dist/core/SecretSync.js +16 -0
  141. package/dist/core/SecretSync.js.map +1 -1
  142. package/dist/core/SessionManager.d.ts +11 -0
  143. package/dist/core/SessionManager.d.ts.map +1 -1
  144. package/dist/core/SessionManager.js +125 -14
  145. package/dist/core/SessionManager.js.map +1 -1
  146. package/dist/core/SessionPoolFailoverRunner.d.ts.map +1 -1
  147. package/dist/core/SessionPoolFailoverRunner.js +4 -0
  148. package/dist/core/SessionPoolFailoverRunner.js.map +1 -1
  149. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  150. package/dist/core/SleepWakeDetector.js +10 -0
  151. package/dist/core/SleepWakeDetector.js.map +1 -1
  152. package/dist/core/SubscriptionReloginStore.d.ts.map +1 -1
  153. package/dist/core/SubscriptionReloginStore.js +10 -1
  154. package/dist/core/SubscriptionReloginStore.js.map +1 -1
  155. package/dist/core/TopicPinMutation.d.ts.map +1 -1
  156. package/dist/core/TopicPinMutation.js +5 -0
  157. package/dist/core/TopicPinMutation.js.map +1 -1
  158. package/dist/core/UnjustifiedStopGate.d.ts.map +1 -1
  159. package/dist/core/UnjustifiedStopGate.js +22 -0
  160. package/dist/core/UnjustifiedStopGate.js.map +1 -1
  161. package/dist/core/WindowRunCadenceExecutor.d.ts.map +1 -1
  162. package/dist/core/WindowRunCadenceExecutor.js +20 -0
  163. package/dist/core/WindowRunCadenceExecutor.js.map +1 -1
  164. package/dist/core/claudeChildAuth.d.ts +68 -0
  165. package/dist/core/claudeChildAuth.d.ts.map +1 -0
  166. package/dist/core/claudeChildAuth.js +173 -0
  167. package/dist/core/claudeChildAuth.js.map +1 -0
  168. package/dist/core/claudeKeyProbe.d.ts +23 -0
  169. package/dist/core/claudeKeyProbe.d.ts.map +1 -0
  170. package/dist/core/claudeKeyProbe.js +68 -0
  171. package/dist/core/claudeKeyProbe.js.map +1 -0
  172. package/dist/core/codexDeviceLimitWiring.d.ts.map +1 -1
  173. package/dist/core/codexDeviceLimitWiring.js +12 -0
  174. package/dist/core/codexDeviceLimitWiring.js.map +1 -1
  175. package/dist/core/deliverToConversation.d.ts.map +1 -1
  176. package/dist/core/deliverToConversation.js +11 -0
  177. package/dist/core/deliverToConversation.js.map +1 -1
  178. package/dist/core/meteredCallEntry.d.ts.map +1 -1
  179. package/dist/core/meteredCallEntry.js +21 -0
  180. package/dist/core/meteredCallEntry.js.map +1 -1
  181. package/dist/core/nobodyPollingActuator.d.ts.map +1 -1
  182. package/dist/core/nobodyPollingActuator.js +5 -0
  183. package/dist/core/nobodyPollingActuator.js.map +1 -1
  184. package/dist/core/operatorSurfaceReferral.d.ts +18 -0
  185. package/dist/core/operatorSurfaceReferral.d.ts.map +1 -0
  186. package/dist/core/operatorSurfaceReferral.js +32 -0
  187. package/dist/core/operatorSurfaceReferral.js.map +1 -0
  188. package/dist/core/ownershipFollowsLiveWork.d.ts.map +1 -1
  189. package/dist/core/ownershipFollowsLiveWork.js +10 -1
  190. package/dist/core/ownershipFollowsLiveWork.js.map +1 -1
  191. package/dist/core/types.d.ts +15 -0
  192. package/dist/core/types.d.ts.map +1 -1
  193. package/dist/core/types.js.map +1 -1
  194. package/dist/core/worktreeDirtyCheck.d.ts.map +1 -1
  195. package/dist/core/worktreeDirtyCheck.js +2 -0
  196. package/dist/core/worktreeDirtyCheck.js.map +1 -1
  197. package/dist/data/stageBCertifiedSet.d.ts +9 -0
  198. package/dist/data/stageBCertifiedSet.d.ts.map +1 -1
  199. package/dist/data/stageBCertifiedSet.js +12 -0
  200. package/dist/data/stageBCertifiedSet.js.map +1 -1
  201. package/dist/data/standards-guard-index.json +1 -1
  202. package/dist/data/standards-guard-index.meta.json +2 -2
  203. package/dist/data/standards-registry.meta.json +1 -1
  204. package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
  205. package/dist/lifeline/TelegramLifeline.js +17 -3
  206. package/dist/lifeline/TelegramLifeline.js.map +1 -1
  207. package/dist/messaging/attentionHubPolicy.d.ts.map +1 -1
  208. package/dist/messaging/attentionHubPolicy.js +1 -0
  209. package/dist/messaging/attentionHubPolicy.js.map +1 -1
  210. package/dist/monitoring/AgentWorktreeReaper.d.ts.map +1 -1
  211. package/dist/monitoring/AgentWorktreeReaper.js +15 -0
  212. package/dist/monitoring/AgentWorktreeReaper.js.map +1 -1
  213. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.d.ts.map +1 -1
  214. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js +18 -9
  215. package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js.map +1 -1
  216. package/dist/monitoring/CodexArmSessionSweeper.d.ts.map +1 -1
  217. package/dist/monitoring/CodexArmSessionSweeper.js +11 -0
  218. package/dist/monitoring/CodexArmSessionSweeper.js.map +1 -1
  219. package/dist/monitoring/CrashLoopPauser.d.ts.map +1 -1
  220. package/dist/monitoring/CrashLoopPauser.js +8 -0
  221. package/dist/monitoring/CrashLoopPauser.js.map +1 -1
  222. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  223. package/dist/monitoring/DegradationReporter.js +7 -1
  224. package/dist/monitoring/DegradationReporter.js.map +1 -1
  225. package/dist/monitoring/DegradedTmuxGuard.d.ts +2 -0
  226. package/dist/monitoring/DegradedTmuxGuard.d.ts.map +1 -1
  227. package/dist/monitoring/DegradedTmuxGuard.js +14 -0
  228. package/dist/monitoring/DegradedTmuxGuard.js.map +1 -1
  229. package/dist/monitoring/DurableOutputScrubber.d.ts.map +1 -1
  230. package/dist/monitoring/DurableOutputScrubber.js +7 -0
  231. package/dist/monitoring/DurableOutputScrubber.js.map +1 -1
  232. package/dist/monitoring/DurableVaultSession.d.ts.map +1 -1
  233. package/dist/monitoring/DurableVaultSession.js +15 -0
  234. package/dist/monitoring/DurableVaultSession.js.map +1 -1
  235. package/dist/monitoring/ExternalHogSentinel.d.ts +2 -0
  236. package/dist/monitoring/ExternalHogSentinel.d.ts.map +1 -1
  237. package/dist/monitoring/ExternalHogSentinel.js +27 -1
  238. package/dist/monitoring/ExternalHogSentinel.js.map +1 -1
  239. package/dist/monitoring/FailureLedger.d.ts.map +1 -1
  240. package/dist/monitoring/FailureLedger.js +38 -1
  241. package/dist/monitoring/FailureLedger.js.map +1 -1
  242. package/dist/monitoring/FeatureEvidenceLog.d.ts +5 -0
  243. package/dist/monitoring/FeatureEvidenceLog.d.ts.map +1 -1
  244. package/dist/monitoring/FeatureEvidenceLog.js +25 -0
  245. package/dist/monitoring/FeatureEvidenceLog.js.map +1 -1
  246. package/dist/monitoring/GeminiCapacityEscalationMonitor.d.ts.map +1 -1
  247. package/dist/monitoring/GeminiCapacityEscalationMonitor.js +20 -2
  248. package/dist/monitoring/GeminiCapacityEscalationMonitor.js.map +1 -1
  249. package/dist/monitoring/GeminiLoopRunner.d.ts.map +1 -1
  250. package/dist/monitoring/GeminiLoopRunner.js +11 -1
  251. package/dist/monitoring/GeminiLoopRunner.js.map +1 -1
  252. package/dist/monitoring/GreenPrAutoMerger.d.ts.map +1 -1
  253. package/dist/monitoring/GreenPrAutoMerger.js +11 -0
  254. package/dist/monitoring/GreenPrAutoMerger.js.map +1 -1
  255. package/dist/monitoring/GrowthDigestPublisher.d.ts.map +1 -1
  256. package/dist/monitoring/GrowthDigestPublisher.js +16 -0
  257. package/dist/monitoring/GrowthDigestPublisher.js.map +1 -1
  258. package/dist/monitoring/GrowthMilestoneAnalyst.d.ts +3 -0
  259. package/dist/monitoring/GrowthMilestoneAnalyst.d.ts.map +1 -1
  260. package/dist/monitoring/GrowthMilestoneAnalyst.js +45 -1
  261. package/dist/monitoring/GrowthMilestoneAnalyst.js.map +1 -1
  262. package/dist/monitoring/McpProcessReaper.d.ts +2 -0
  263. package/dist/monitoring/McpProcessReaper.d.ts.map +1 -1
  264. package/dist/monitoring/McpProcessReaper.js +32 -0
  265. package/dist/monitoring/McpProcessReaper.js.map +1 -1
  266. package/dist/monitoring/MissingLoginSessionDetector.d.ts +2 -1
  267. package/dist/monitoring/MissingLoginSessionDetector.d.ts.map +1 -1
  268. package/dist/monitoring/MissingLoginSessionDetector.js +23 -0
  269. package/dist/monitoring/MissingLoginSessionDetector.js.map +1 -1
  270. package/dist/monitoring/OrchestratorPoller.d.ts +1 -0
  271. package/dist/monitoring/OrchestratorPoller.d.ts.map +1 -1
  272. package/dist/monitoring/OrchestratorPoller.js +13 -0
  273. package/dist/monitoring/OrchestratorPoller.js.map +1 -1
  274. package/dist/monitoring/OrphanedWorkSentinel.d.ts.map +1 -1
  275. package/dist/monitoring/OrphanedWorkSentinel.js +7 -0
  276. package/dist/monitoring/OrphanedWorkSentinel.js.map +1 -1
  277. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  278. package/dist/monitoring/PresenceProxy.js +9 -1
  279. package/dist/monitoring/PresenceProxy.js.map +1 -1
  280. package/dist/monitoring/ProcessFootprintMonitor.d.ts.map +1 -1
  281. package/dist/monitoring/ProcessFootprintMonitor.js +20 -2
  282. package/dist/monitoring/ProcessFootprintMonitor.js.map +1 -1
  283. package/dist/monitoring/PromiseBeacon.d.ts.map +1 -1
  284. package/dist/monitoring/PromiseBeacon.js +20 -0
  285. package/dist/monitoring/PromiseBeacon.js.map +1 -1
  286. package/dist/monitoring/ReleaseReadinessSentinel.d.ts +2 -0
  287. package/dist/monitoring/ReleaseReadinessSentinel.d.ts.map +1 -1
  288. package/dist/monitoring/ReleaseReadinessSentinel.js +26 -0
  289. package/dist/monitoring/ReleaseReadinessSentinel.js.map +1 -1
  290. package/dist/monitoring/RopeHealthMonitor.d.ts.map +1 -1
  291. package/dist/monitoring/RopeHealthMonitor.js +35 -1
  292. package/dist/monitoring/RopeHealthMonitor.js.map +1 -1
  293. package/dist/monitoring/SentinelNotifier.d.ts.map +1 -1
  294. package/dist/monitoring/SentinelNotifier.js +16 -0
  295. package/dist/monitoring/SentinelNotifier.js.map +1 -1
  296. package/dist/monitoring/SessionReaper.d.ts.map +1 -1
  297. package/dist/monitoring/SessionReaper.js +11 -2
  298. package/dist/monitoring/SessionReaper.js.map +1 -1
  299. package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts +2 -0
  300. package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts.map +1 -1
  301. package/dist/monitoring/SingleMachineFailoverGapDetector.js +20 -0
  302. package/dist/monitoring/SingleMachineFailoverGapDetector.js.map +1 -1
  303. package/dist/monitoring/SpeakerElection.d.ts.map +1 -1
  304. package/dist/monitoring/SpeakerElection.js +8 -0
  305. package/dist/monitoring/SpeakerElection.js.map +1 -1
  306. package/dist/monitoring/StrandedTopicSentinel.d.ts +3 -0
  307. package/dist/monitoring/StrandedTopicSentinel.d.ts.map +1 -1
  308. package/dist/monitoring/StrandedTopicSentinel.js +33 -0
  309. package/dist/monitoring/StrandedTopicSentinel.js.map +1 -1
  310. package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
  311. package/dist/native/instar-desktop-host +0 -0
  312. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.d.ts.map +1 -1
  313. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js +5 -2
  314. package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js.map +1 -1
  315. package/dist/recommended/RecommendedServicesLedger.d.ts +91 -0
  316. package/dist/recommended/RecommendedServicesLedger.d.ts.map +1 -0
  317. package/dist/recommended/RecommendedServicesLedger.js +193 -0
  318. package/dist/recommended/RecommendedServicesLedger.js.map +1 -0
  319. package/dist/recommended/RecommendedServicesReplicatedStore.d.ts +14 -0
  320. package/dist/recommended/RecommendedServicesReplicatedStore.d.ts.map +1 -0
  321. package/dist/recommended/RecommendedServicesReplicatedStore.js +34 -0
  322. package/dist/recommended/RecommendedServicesReplicatedStore.js.map +1 -0
  323. package/dist/recommended/legacyDeclines.d.ts +11 -0
  324. package/dist/recommended/legacyDeclines.d.ts.map +1 -0
  325. package/dist/recommended/legacyDeclines.js +17 -0
  326. package/dist/recommended/legacyDeclines.js.map +1 -0
  327. package/dist/recommended/serviceIds.d.ts +3 -0
  328. package/dist/recommended/serviceIds.d.ts.map +1 -0
  329. package/dist/recommended/serviceIds.js +6 -0
  330. package/dist/recommended/serviceIds.js.map +1 -0
  331. package/dist/scaffold/templates.d.ts +2 -0
  332. package/dist/scaffold/templates.d.ts.map +1 -1
  333. package/dist/scaffold/templates.js +8 -0
  334. package/dist/scaffold/templates.js.map +1 -1
  335. package/dist/scheduler/JobResultTriage.d.ts.map +1 -1
  336. package/dist/scheduler/JobResultTriage.js +10 -0
  337. package/dist/scheduler/JobResultTriage.js.map +1 -1
  338. package/dist/scheduler/JobScheduler.d.ts.map +1 -1
  339. package/dist/scheduler/JobScheduler.js +12 -0
  340. package/dist/scheduler/JobScheduler.js.map +1 -1
  341. package/dist/scheduler/MentorOnboardingRunner.d.ts +3 -0
  342. package/dist/scheduler/MentorOnboardingRunner.d.ts.map +1 -1
  343. package/dist/scheduler/MentorOnboardingRunner.js +24 -2
  344. package/dist/scheduler/MentorOnboardingRunner.js.map +1 -1
  345. package/dist/server/AgentServer.d.ts +2 -0
  346. package/dist/server/AgentServer.d.ts.map +1 -1
  347. package/dist/server/AgentServer.js +76 -15
  348. package/dist/server/AgentServer.js.map +1 -1
  349. package/dist/server/BootHealthBeacon.d.ts +3 -0
  350. package/dist/server/BootHealthBeacon.d.ts.map +1 -1
  351. package/dist/server/BootHealthBeacon.js +9 -0
  352. package/dist/server/BootHealthBeacon.js.map +1 -1
  353. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  354. package/dist/server/CapabilityIndex.js +10 -1
  355. package/dist/server/CapabilityIndex.js.map +1 -1
  356. package/dist/server/LifelineIngressGuard.d.ts.map +1 -1
  357. package/dist/server/LifelineIngressGuard.js +11 -0
  358. package/dist/server/LifelineIngressGuard.js.map +1 -1
  359. package/dist/server/PoolPollCache.d.ts +4 -0
  360. package/dist/server/PoolPollCache.d.ts.map +1 -1
  361. package/dist/server/PoolPollCache.js +33 -0
  362. package/dist/server/PoolPollCache.js.map +1 -1
  363. package/dist/server/machineRoutes.d.ts.map +1 -1
  364. package/dist/server/machineRoutes.js +6 -0
  365. package/dist/server/machineRoutes.js.map +1 -1
  366. package/dist/server/middleware.d.ts.map +1 -1
  367. package/dist/server/middleware.js +6 -0
  368. package/dist/server/middleware.js.map +1 -1
  369. package/dist/server/mobileConsoleTicket.d.ts +113 -0
  370. package/dist/server/mobileConsoleTicket.d.ts.map +1 -0
  371. package/dist/server/mobileConsoleTicket.js +405 -0
  372. package/dist/server/mobileConsoleTicket.js.map +1 -0
  373. package/dist/server/mobileConversationRoutes.d.ts.map +1 -1
  374. package/dist/server/mobileConversationRoutes.js +20 -1
  375. package/dist/server/mobileConversationRoutes.js.map +1 -1
  376. package/dist/server/mobileMediaRoutes.d.ts.map +1 -1
  377. package/dist/server/mobileMediaRoutes.js +3 -0
  378. package/dist/server/mobileMediaRoutes.js.map +1 -1
  379. package/dist/server/mobilePairingRoutes.d.ts +8 -2
  380. package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
  381. package/dist/server/mobilePairingRoutes.js +67 -6
  382. package/dist/server/mobilePairingRoutes.js.map +1 -1
  383. package/dist/server/mobileSessionTerminalRoutes.d.ts +128 -0
  384. package/dist/server/mobileSessionTerminalRoutes.d.ts.map +1 -0
  385. package/dist/server/mobileSessionTerminalRoutes.js +389 -0
  386. package/dist/server/mobileSessionTerminalRoutes.js.map +1 -0
  387. package/dist/server/recommendedServiceRoutes.d.ts +13 -0
  388. package/dist/server/recommendedServiceRoutes.d.ts.map +1 -0
  389. package/dist/server/recommendedServiceRoutes.js +49 -0
  390. package/dist/server/recommendedServiceRoutes.js.map +1 -0
  391. package/dist/server/routes.d.ts +2 -0
  392. package/dist/server/routes.d.ts.map +1 -1
  393. package/dist/server/routes.js +170 -4
  394. package/dist/server/routes.js.map +1 -1
  395. package/dist/testing/selfActionRegistry.d.ts.map +1 -1
  396. package/dist/testing/selfActionRegistry.js +36 -0
  397. package/dist/testing/selfActionRegistry.js.map +1 -1
  398. package/dist/threadline/A2ACheckInProxy.d.ts.map +1 -1
  399. package/dist/threadline/A2ACheckInProxy.js +26 -15
  400. package/dist/threadline/A2ACheckInProxy.js.map +1 -1
  401. package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
  402. package/dist/threadline/AgentTrustManager.js +3 -0
  403. package/dist/threadline/AgentTrustManager.js.map +1 -1
  404. package/dist/threadline/InboundIdLedger.d.ts.map +1 -1
  405. package/dist/threadline/InboundIdLedger.js +18 -1
  406. package/dist/threadline/InboundIdLedger.js.map +1 -1
  407. package/dist/threadline/NegotiatorGate.d.ts.map +1 -1
  408. package/dist/threadline/NegotiatorGate.js +11 -0
  409. package/dist/threadline/NegotiatorGate.js.map +1 -1
  410. package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
  411. package/dist/threadline/PipeSessionSpawner.js +8 -0
  412. package/dist/threadline/PipeSessionSpawner.js.map +1 -1
  413. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  414. package/dist/threadline/ThreadlineRouter.js +13 -0
  415. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  416. package/dist/threadline/pairingReplicationWiring.d.ts.map +1 -1
  417. package/dist/threadline/pairingReplicationWiring.js +9 -0
  418. package/dist/threadline/pairingReplicationWiring.js.map +1 -1
  419. package/dist/threadline/relayForward.d.ts.map +1 -1
  420. package/dist/threadline/relayForward.js +13 -2
  421. package/dist/threadline/relayForward.js.map +1 -1
  422. package/dist/threadline/relayUnknownSenderTrust.d.ts +0 -9
  423. package/dist/threadline/relayUnknownSenderTrust.d.ts.map +1 -1
  424. package/dist/threadline/relayUnknownSenderTrust.js +16 -0
  425. package/dist/threadline/relayUnknownSenderTrust.js.map +1 -1
  426. package/package.json +1 -1
  427. package/scripts/check-constitution-pairing.mjs +273 -0
  428. package/scripts/safe-merge.mjs +9 -0
  429. package/src/data/builtin-manifest.json +103 -103
  430. package/src/data/feature-ladders.json +113 -113
  431. package/src/data/stageBCertifiedSet.ts +12 -0
  432. package/src/data/standards-guard-index.json +1 -1
  433. package/src/data/standards-guard-index.meta.json +2 -2
  434. package/src/data/standards-registry.meta.json +1 -1
  435. package/src/data/state-coherence-registry.json +18 -0
  436. package/src/scaffold/templates.ts +9 -0
  437. package/upgrades/1.3.1650.md +105 -0
  438. package/upgrades/mobile-console-device-signin.eli16.md +5 -0
  439. package/upgrades/side-effects/cloud-key-internal-calls.md +116 -0
  440. package/upgrades/side-effects/constitution-alignment.eli16.md +11 -0
  441. package/upgrades/side-effects/constitution-alignment.md +69 -0
  442. package/upgrades/side-effects/feature-evidence-recording.eli16.md +3 -0
  443. package/upgrades/side-effects/feature-evidence-recording.md +66 -0
  444. package/upgrades/side-effects/feedback-reroute-admission-parity.md +77 -0
  445. package/upgrades/side-effects/mobile-console-device-signin.md +102 -0
  446. package/upgrades/side-effects/mobile-native-session-screen.md +88 -0
  447. package/upgrades/side-effects/operator-needs-first-screen.md +87 -0
  448. package/upgrades/side-effects/recommended-services-choices.md +50 -0
  449. package/upgrades/side-effects/rerouted-lifetime-active-process.md +63 -0
  450. package/upgrades/side-effects/undated-resurfacer-e2e-wait.eli16.md +5 -0
  451. package/upgrades/side-effects/undated-resurfacer-e2e-wait.md +9 -0
@@ -0,0 +1,102 @@
1
+ # Side-Effects Review — Owner phone opens the console without the dashboard PIN
2
+
3
+ **Version / slug:** `mobile-console-device-signin`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent subagent (see below)`
7
+
8
+ ## Summary of the change
9
+
10
+ Tier 2 (touches sign-in and credentials). An owner's paired iPhone can open the agent console without typing the dashboard PIN. The app enrols a second Secure Enclave key (the presence key, which signs only after Face ID / Touch ID / the passcode) with a proof of possession, asks for a single-use server challenge, signs it with that key, and receives a 60-second single-use ticket bound to the device and the signed Host. The console page redeems the ticket once at a public route for exactly the token `/dashboard/unlock` returns (never the operator session). New: `src/server/mobileConsoleTicket.ts`, three allowlisted device routes, `POST /dashboard/console-ticket` (exact-path bearer exemption), `DeviceRecord.presenceKey` + `setPresenceKey`, config switch `mobilePairing.consoleTicket.enabled` (default on), `dashboard/console/ticket-model.js` and a boot step in `console.js`, a CLAUDE.md line rewrite + migration, an amendment note in `mobile-device-keys.md`. App: `PresenceKey.swift`, `ConsoleSignIn.swift`, `ConsoleView.swift` rewrite (non-persistent store for device-key agents, origin-guarded injection, one-shot script, one-time purge), `AppLock` keeps its authenticated `LAContext`. Size: about 15 files, ~900 LOC including tests. Effort: 5 spec review rounds (cap 6), one commit attempt planned.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - Presence-key enrollment: device, owner, local TLS, switch, valid key format, proof of possession, set once — **add**, invariant.
15
+ - Challenge / mint: device, owner, local TLS, switch, challenge single-use and bound to device+Host, presence signature — **add**, invariant.
16
+ - Redeem: local TLS, switch, ticket single-use + Host-bound, device still active owner (registry + ledger + person), throughput limit on unknown tickets only — **add**, invariant.
17
+ - App plan (token / ticket / PIN) — **add**, invariant; every failure falls back to today's PIN box.
18
+ - Bearer-gate exemption for `POST /dashboard/console-ticket` — **add**, exact method + path.
19
+
20
+ ---
21
+
22
+ ## 1. Over-block
23
+
24
+ - A legitimate owner whose phone has no passcode, or whose presence key was deleted by removing the passcode, gets the PIN box (409 → "pair again" note). Intended.
25
+ - A lease move of a shared tunnel hostname between mint and redeem (within 60 s) answers 401 → PIN box. Rare and safe.
26
+ - A Host rewrite by a front (`httpHostHeader`) would make every redeem 401 → PIN box. Instar's fronts pass the Host through (pairing and multi-route already depend on it).
27
+ - Behind the tunnel all remote callers share the loopback address, so the 10/min per-address limit on unknown tickets is effectively global; a known ticket is judged before the limit, so the operator is never blocked by it.
28
+
29
+ ## 2. Under-block
30
+
31
+ - The token handed to the console outlives a revocation that happens while the console is open, until the screen closes or the API token is rotated (same as a PIN-unlocked tab). Tracked as feedback `fb-d588d77a-cf8` (device-bound console session).
32
+ - The server cannot verify the presence key's Secure Enclave origin or `.userPresence` policy (no App Attest); an attacker controlling the app process before first enrollment could enrol a software key. Same attacker could read a typed PIN.
33
+ - The phone passcode stands in for the PIN (`.userPresence` accepts it). Stated in the spec.
34
+ - A third-party local proxy that accepts plain HTTP and forwards over loopback passes `arrivedOverLocalTls`; the app only ever posts to `https`, and this is the same limit device signatures already accept.
35
+
36
+ ## 3. Level-of-abstraction fit
37
+
38
+ Reuses the PIN unlock's console credential and storage path (the console stores the token exactly as after a PIN unlock), the device authenticator for the signed requests, `arrivedOverLocalTls` for transport, the device registry + key ledger + person resolution for revocation. A device-bound session would be the deeper fix and sits at the bearer-gate layer; it is out of this change's scope by the brief and tracked as feedback.
39
+
40
+ ## 4. Signal vs authority compliance
41
+
42
+ Every gate is a cryptographic or exact check (signature, single-use secret, registry status, transport), the hard-invariant class `docs/signal-vs-authority.md` exempts from the judgment requirement. The audit log is a record, never a gate; a failed write is reported through DegradationReporter and does not affect the answer.
43
+
44
+ ## 4b. Judgment-point check (Judgment Within Floors standard)
45
+
46
+ No judgment points. All decision points are invariants (spec "Decision points touched" table), each with a deterministic fallback to today's PIN box.
47
+
48
+ ## 5. Interactions
49
+
50
+ - `authMiddleware`: one new exact-path exemption placed beside `/dashboard/unlock`; the route is also registered before the gate, so the gate never sees it. GET on the path still needs a bearer (tested).
51
+ - `deviceAuthenticator`: three new allowlist rows (JSON bodies, `active` only); the shared per-device rate limit and replay set apply as for every device route. Mint replay safety does not depend on the replay set (single-use challenges).
52
+ - `/dashboard/unlock` and its PIN budget: untouched. The console still falls back to it.
53
+ - Device revocation: the redeem re-reads registry + ledger, so revocation wins without a hook in the revoke route.
54
+ - PostUpdateMigrator: the new line rewrite composes with the earlier Tailscale and word-code rewrites (different match conditions; tested with the word-code fresh text).
55
+
56
+ ## 6. External surfaces
57
+
58
+ - New public HTTP route `POST /dashboard/console-ticket` (input: a 256-bit single-use secret; output: the API token).
59
+ - Three new device routes visible to paired phones.
60
+ - A new audit file `.instar/state/mobile-console-tickets.jsonl` (metadata only, rotated at 1 MB).
61
+ - The iPhone app's console web view for device-key agents becomes non-persistent and purges a stale stored token once; on an older server the operator types the PIN on every console open.
62
+ - CLAUDE.md wording for the mobile pairing section changes on update.
63
+
64
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
65
+
66
+ 1. **Leads with the primary action?** Yes: the console opens signed in; when it cannot, the PIN box is the first and only thing shown, as today.
67
+ 2. **Zero raw internals as primary content?** Yes: no ticket, challenge or key is ever rendered; the only new text is the app's plain note "Sign-in without the PIN needs this phone paired again (remove it, then pair)."
68
+ 3. **Destructive actions de-emphasized?** No destructive action added.
69
+ 4. **Plain language + phone width?** The change is the removal of a step on the phone; the console's existing phone layout is unchanged.
70
+
71
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
72
+
73
+ Machine-local by design, with markers in the spec's posture section: challenges and tickets live in one process's memory and redeem for that machine's own API token (hardware-bound-resource); the presence key sits on the device record of the machine the phone paired with, which is the only machine that can verify that phone (physical-credential-locality, consistent with `mobile-device-keys.md`); the audit log sits beside the per-machine registry. No user-facing notices. Durable state: only the presence key on the device record (follows the device record). Generated URL: `redeemOrigin` is the Host the phone itself signed for; a ticket redeemed elsewhere fails to the PIN box.
74
+
75
+ ## 8. Rollback cost
76
+
77
+ Revert the server PR and ship a patch: routes vanish, apps fall back to the PIN box, memory-only tickets expire in 60 s, the `presenceKey` field becomes inert, the audit file is inert. The CLAUDE.md line on already-updated installs would overstate the feature until a later update; no data migration. The app ships separately (Echo, TestFlight); an app already on phones keeps the non-persistent store (which the device-keys spec required anyway).
78
+
79
+ ---
80
+
81
+ ## Conclusion
82
+
83
+ The review and five spec rounds changed the design materially: a server-verifiable presence key replaced an app-side "owner verified" flag; single-use server challenges replaced a clock-based restart check; the redeem became Host-bound, TLS/loopback-only, switch-checked, and throttles only unknown tickets; enrollment gained proof of possession; the device-keys spec exception was made explicit and a device-bound session was filed as feedback. Clear to ship pending the second-pass concurrence below.
84
+
85
+ ---
86
+
87
+ ## Second-pass review (if required)
88
+
89
+ **Reviewer:** independent second-pass subagent (claude-opus-5-5), 2026-11-03
90
+ **Independent read of the artifact: concur**
91
+
92
+ Concur with the review. Verified against the code: the redeem answers only `{ token }`; single-use deletes happen before any other check for challenges and tickets; the redeem re-reads registry, key ledger and owner role; transport is checked first; the bearer exemption is exact method + path; the app injection is a JSON literal guarded by `location.origin`, main frame only, removed after first navigation. One non-blocking gap raised and fixed before commit: after a passcode is removed and set again, iOS replaces the presence key while the app still believed it was enrolled, so every open silently fell back to the PIN box; the app now clears its enrolled flag on a `401` from the mint (other than an expired challenge), so the next open re-enrols, gets `409`, and shows the "pair again" note.
93
+
94
+ ---
95
+
96
+ ## Evidence pointers
97
+
98
+ - **User-role live proof (real Chromium, real console page, throwaway agent on a real port, phone stand-in signing as the app does):** valid ticket on an owner phone → signed in, no PIN box, ticket gone from session storage; same ticket again → PIN box; unknown ticket → PIN box; no ticket → PIN box; ticket minted then phone revoked → PIN box; MSP phone → mint refused `403 owner-phone-required`. Result: PASS. The first run FAILED on the valid-ticket row and found a real defect: a phone paired on an address the device authenticator's strict host parser rejects (an IP with a port) could never redeem, because the redeem compared a null normalized Host. Fixed with one shared `normalHost` used on both sides, and pinned by a unit test. Limits: the proof ran over plain HTTP on loopback (which the redeem accepts as loopback), not through a TLS front; the iOS Secure Enclave paths (context reuse without a second prompt, invalidated context, passcode removal) run first on the operator's phone and each fails safe to the PIN box.
99
+ - **App:** `xcodebuild test` on the iPhone 17 Pro simulator: 158 tests, 0 failures, including 10 new `ConsoleSignInTests`.
100
+
101
+ - Spec: `docs/specs/mobile-console-device-signin.md`; convergence report `docs/specs/reports/mobile-console-device-signin-convergence.md`.
102
+ - Tests: `tests/unit/mobile-console-ticket.test.ts`, `tests/unit/dashboard-console-ticket-model.test.ts`, `tests/unit/mobile-console-ticket-awareness.test.ts`, `tests/integration/mobile-console-ticket-routes.test.ts`, `tests/e2e/mobile-console-ticket-lifecycle.test.ts`; app `apps/instar-ios/Tests/InstarAppTests/ConsoleSignInTests.swift` (agent-home repo).
@@ -0,0 +1,88 @@
1
+ # Side-Effects Review — Native session screen (device-key session output and input)
2
+
3
+ **Version / slug:** `mobile-native-session-screen`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `Echo`
6
+ **Second-pass reviewer:** `independent subagent (see the end of this file)`
7
+
8
+ ## Summary of the change
9
+
10
+ Operator request (Justin, Telegram topic 134088, 2026-11-03 22:01 and 22:55 PST): the chat's session button opens a native session screen in the app. Spec: `docs/specs/mobile-native-session-screen.md` (converged, approved).
11
+
12
+ - `src/server/mobilePairingRoutes.ts`: two `DEVICE_ALLOWLIST` entries (`GET /sessions/<name>/output`, `POST /sessions/<name>/input`), active devices, `ownerOnly: true`, own buckets `session-output` (90/min) and `session-input` (12/min). New rule flags `ownerOnly` (403 `owner-phone-required` for a non-owner person) and `bucket` (named bucket). `deviceBucketOk` keys by device and bucket name (the media rule keeps its old key) and drops emptied windows once the map holds more than 64 keys.
13
+ - `src/server/mobileSessionTerminalRoutes.ts` (new): a device-only router. Non-device requests call `next()` untouched. For an owner device: exact session resolution on this machine, `sid`/`machine` binding, async pane capture, credential redaction, plain-text filter, durable replay record, machine-wide input window, audit log, and a bounded pool lookup to name the machine of a session that is not here.
14
+ - `src/server/AgentServer.ts`: mounts the router before the main routes when mobile pairing exists; wires state, capture, send, peer lookup, nicknames, secrets.
15
+ - `src/core/PostUpdateMigrator.ts` + template: one CLAUDE.md bullet (sniff "native session screen") after the "Open session" bullet. `src/server/CapabilityIndex.ts`: one sentence.
16
+ - Tests: unit, integration, e2e.
17
+
18
+ Tier 2 (security-sensitive: new device access to session routes). Size: 1 new module (~290 lines), ~45 lines wiring/allowlist, ~25 lines migration/index, 3 test files (~520 lines). Effort: 6 spec rounds (the Tier-2 cap; later rounds each found real security gaps), 1 commit attempt so far.
19
+
20
+ ## Decision-point inventory
21
+
22
+ - Device allowlist membership for the two routes — add — exact method/path/status rules.
23
+ - `ownerOnly` — add — refuses non-owner persons in the authenticator; the router re-checks.
24
+ - Named buckets, machine-wide input window — add — fixed counts, 429.
25
+ - Plain-text filter, exact resolution, `sid`/`machine` binding, replay record — add — each can only refuse.
26
+ - Credential redaction — add — changes only what a device sees.
27
+ - "Where is this session" lookup — add — a signal shown to the operator; never grants access.
28
+
29
+ ## 1. Over-block
30
+
31
+ A phone whose clock is far off is already refused by the existing ±60 s window. A session record that is `starting` is reachable; a tmux session Instar does not track is not (the dashboard can reach it; the phone cannot, deliberately). Typing more than 12 messages a minute across all phones gets 429. Text with control characters (pasted escape codes) is refused rather than cleaned server-side; the app strips them before sending. A session whose name was reused after the phone opened it answers 409 and must be reopened.
32
+
33
+ ## 2. Under-block
34
+
35
+ Redaction is exact-match: a token split by a wrap or encoded differently can reach the owner's phone. Accepted: the owner's PIN unlock already returns the API token itself to the same phone. With multi-route off, a replay to another machine that holds the same device record and has taken over the paired host within 60 s is not caught by the per-machine replay record (accepted; requires a captured TLS request signed by the owner's Secure Enclave key, and the effect is the owner's own text typed once more). Other secrets a session prints are shown, as on the PIN dashboard.
36
+
37
+ ## 3. Level-of-abstraction fit
38
+
39
+ Access control stays in the existing device authenticator (one new generic flag). Route behaviour sits in a dedicated router in front of the Bearer handlers, so the Bearer path is not touched. Pane capture and injection go through the existing SessionManager surfaces (`captureOutputAsync`, `sendInput`). The machine lookup reuses `poolPeerFetch` and `resolvePeerUrls`, as `GET /sessions?scope=pool` does.
40
+
41
+ ## 4. Signal vs authority compliance
42
+
43
+ Every refusal is a deterministic boundary check (identity, role, exact id/name match, character class, exact digest, fixed counts), the structural-validation class `docs/signal-vs-authority.md` exempts. No heuristic gains blocking power. The machine lookup only words an answer; it never allows or refuses access.
44
+
45
+ ## 4b. Judgment-point check
46
+
47
+ No competing-signals decision point is added; all points are classified `invariant` in the spec with reasons.
48
+
49
+ ## 5. Interactions
50
+
51
+ - Mounted before `this.app.use(routes)`, after `authMiddleware`; Bearer requests fall through to the same handlers (integration and e2e tests prove it).
52
+ - `deviceBucketOk` keeps the media rule's exact key (`deviceId`), so media chunk limits are unchanged.
53
+ - `sendInput` for Codex sessions with Stage B on journals and may queue; `ok` is reported as "accepted", and the app says "Sent. It appears in the output when the session takes it."
54
+ - The other mobile builder's console ticket may add allowlist rows nearby; rows are independent entries.
55
+ - The coverage test that counts `conversationRef` rules is unaffected (the new rules are not conversation routes); the new unit test pins the two `ownerOnly` rules.
56
+
57
+ ## 6. External surfaces
58
+
59
+ The iPhone app gains two device routes; answers are new and additive. Bearer callers see no change. Peers receive at most one `GET /sessions` per missing name per 3 s (15 s once found) and at most 8 names per phone per minute. New files: `logs/mobile-session-input.jsonl` (rotated at 2 MB), `state/mobile-session-input-replay.json` (3-minute entries).
60
+
61
+ ## 6b. Operator-surface quality
62
+
63
+ No dashboard or approval-page file is touched. The operator surface is the iPhone app (separate repo, commit e112dac): plain-language errors, no raw codes, the session text first, the dashboard link only for an old server.
64
+
65
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
66
+
67
+ Machine-local by design (`hardware-bound-resource`): a session's pane exists on one host. A request bound to another machine, or a session found on another machine, gets a plain reason naming it from this machine's registry; nothing is proxied. The audit log and replay record are machine-local for the same reason. The sessions list uses the existing pool read. No notices, no generated URLs.
68
+
69
+ ## 8. Rollback cost
70
+
71
+ Revert the PR. Phones then get 403 `device-not-allowed` and the app offers the dashboard. The audit log and replay file stay behind, harmless. The CLAUDE.md bullet stays true on an older server (it names the 403 fallback). No config or data migration.
72
+
73
+ ## Conclusion
74
+
75
+ The change gives the owner's phone the session reading and typing the PIN dashboard already offers, with tighter limits than the dashboard (plain text only, rate windows, replay record, audit). Remaining exposure is within what the PIN unlock grants. Clear to ship after the second-pass review.
76
+
77
+ ## Second-pass review (if required)
78
+
79
+ **Reviewer:** independent general-purpose subagent (Claude Opus 5.5), read-only, given the artifact and the diff.
80
+ **Independent read of the artifact: concur**
81
+
82
+ No way was found for a non-owner, revoked, unsigned or credential-less request to read or type: device requests must match an allowlist row, pass the signature and ledger-revocation check, and are refused as non-owners in the authenticator and again in the router. Non-device requests fall through `next()` to the unchanged Bearer handlers. Typed text is filtered for control characters, and the durable replay record (keyed on the canonical signed string) is written before typing and fails closed. All refusals are structural. One loose claim (emptied bucket windows are dropped only past 64 keys) was corrected above.
83
+
84
+ ## Evidence pointers
85
+
86
+ - Spec and report: `docs/specs/mobile-native-session-screen.md`, `docs/specs/reports/mobile-native-session-screen-convergence.md`.
87
+ - Tests: `tests/unit/mobile-session-terminal.test.ts`, `tests/integration/mobile-session-terminal.test.ts`, `tests/e2e/mobile-session-terminal-alive.test.ts`.
88
+ - Feedback filed: fb-8e2a2b9c-99c (Bearer input raw name), fb-7b984fff-335 (async injection).
@@ -0,0 +1,87 @@
1
+ # Side-Effects Review — Anything that needs the operator is on the first screen, counted, and linked
2
+
3
+ **Version / slug:** `operator-needs-first-screen`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `Echo`
6
+ **Second-pass reviewer:** `independent subagent, see below`
7
+
8
+ ## Summary of the change
9
+
10
+ Tier 2, because it adds a rule to the outbound gate. Spec converged in two rounds. New: `dashboard/console/needs-model.js`, `src/core/operatorSurfaceReferral.ts`, two test files. Changed: Home's `combineNeeds` and `headline`, `loadHome`, seven pages (lead marker, Costs card, Development approval button, Agents switch position, alarm action), page copy, the tone gate's rule tables and prompt, the outbound route's signals, and the CLAUDE.md template plus its migration.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - `B22_SURFACE_REFERRAL` — add — advisory tone-gate rule, LLM-judged, anchored by a signal.
15
+ - `combineNeeds` / `headline` — modify — display only, more rows counted; "Checking in" until sources answer.
16
+ - `getOnce(…, soft403)` — add — a 403 on a Home source does not sign the operator out.
17
+
18
+ ---
19
+
20
+ ## 1. Over-block
21
+
22
+ The rule can nudge a message that merely mentions a page. It only applies when the detector fires, the prompt lists carve-outs and favours false negatives, and a nudge can be overridden with a reason. The cost of a true nudge is one round trip. An agent with no browser overrides with a stated reason. Automated senders and sentinel redrives never see it: the signal is only raised for a sender that can react.
23
+
24
+ ## 2. Under-block
25
+
26
+ A referral phrased outside the detector's words gets no signal, so no nudge. Rendering confirmation is a self-report, recorded as one; the gate cannot see a browser. The floor catches its vocabulary and the registered states; a new need phrased differently relies on the side-effects question. A console on another machine does not see `merging`, `approvals` or `secrets` for the machine that holds them, filed to feedback.
27
+
28
+ ## 3. Level-of-abstraction fit
29
+
30
+ The list is one pure module beside the page models and reuses their builders. The gate rule feeds the existing authority rather than running beside it. The first version put a receipt store and browser tool next to the gate; review cut them as more machinery than the problem earned.
31
+
32
+ ## 4. Signal vs authority compliance
33
+
34
+ Reference: `docs/signal-vs-authority.md`. The detector is a pure signal with no I/O and is deliberately not in `GateSignalDetectors`, whose hits count as leaks on the outage path; a test pins that. The tone gate is the one authority and the rule's disposition is advisory.
35
+
36
+ ## 4b. Judgment-point check (Judgment Within Floors standard)
37
+
38
+ B22 is a judgment point within a floor: a detector anchors it and the LLM decides by meaning whether this is a real referral. No static heuristic decides anything.
39
+
40
+ ## 5. Interactions
41
+
42
+ - B21 covers multi-step procedures and carves out a single link tap. B22 covers a referral missing its link or words. The two do not compete: a one-tap ask with link and words passes both.
43
+ - A nudge plus the existing pending-advisory correlation means a revised resend is credited automatically. Render confirmation specifically needs the complied flag.
44
+ - Home's new reads add load every 30 seconds: about ten small reads, with the four feedback reads every fourth tick and only where the merge watcher answers. Each source has one in-flight read.
45
+ - The refresh place-keeping from the previous PR covers Home's page repaints unchanged.
46
+ - `surfacedNeeds` keeps last good rows for two minutes when a read fails.
47
+ - Live count: Home's count on this agent rises because real needs now count. That is the intended effect and could feel like a jump on first look.
48
+
49
+ ## 6. External surfaces
50
+
51
+ Operator-visible: the Home count and rows, page leads, wording. Agent-visible: one new nudge and a CLAUDE.md section. No route shape changes, no new stored state.
52
+
53
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
54
+
55
+ 1. **Leads with the primary action?** Yes, and now enforced: 18 of 18 browser runs show the action on the first screen with no scrolling.
56
+ 2. **Zero raw internals as primary content?** Rows use page wording, with no identifiers. Secret rows carry the label only, never the drop token, pinned by a test.
57
+ 3. **Destructive actions de-emphasized?** No destructive action added. The spending card links out, and the alarm card's action is constructive.
58
+ 4. **Plain language + phone width?** Screenshots read at 390x844, no sideways scroll on any page in the run.
59
+
60
+ ## 6c. Agent Proposes, Operator Approves
61
+
62
+ `dashboard/console/mandates.js` only gains a lead marker on its existing approvals block, and Home gains a row that links to it. (1) The operator still approves a pre-filled request and constructs nothing. (2) The authority text is unchanged, authored by the server from structured data. No approval flow, field or wording changed.
63
+
64
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
65
+
66
+ Mixed, stated source by source in the spec. `accounts` is proxied-on-read through `scope=pool`. `merging`, `approvals` and `secrets` are machine-local today, the same reach as their pages. The gate is stateless per message. One-voice and topic transfer are unaffected.
67
+
68
+ ## 8. Rollback cost
69
+
70
+ Revert and release. No migration to undo beyond a CLAUDE.md paragraph, which is harmless if left.
71
+
72
+ ## Conclusion
73
+
74
+ Clear to ship after the second pass. The registry wording ships separately on the operator's answer.
75
+
76
+ ## Second-pass review (if required)
77
+
78
+ Concern raised, then resolved. Independent reviewer: a queued reply redriven by the delivery sentinel could be held by B22, and the recovery policy treats any 422 as final, so it would never deliver. Resolved: a send whose delivery id matches a real queue row gets no B22 signal, pinned by an integration test both ways (a made-up id buys nothing). Precision items also fixed: the quote check was quadratic on long text (now linear and bounded), apostrophes no longer count as quotes, a 200 with the wrong shape counts as failed rather than "nothing waiting", and the conditional feedback source no longer holds the headline at "Checking in". Clean on the reviewer's other checks: the complied flag reaches the signal before the authority runs, a failed source never reads as "All quiet", secret rows carry no token. Concur after these fixes.
79
+
80
+ ## Evidence pointers
81
+
82
+ Real judge (Haiku tier via the Claude CLI), five sample messages: a bare referral and a link-and-words message without confirmation get the nudge, the same message with confirmation passes, a report of the agent's own work passes. "Check the page if you like" was nudged, a borderline call the agent can override. The rule's text is added only for a flagged message, so the benchmarked prompt template and its saved benchmark are unchanged, pinned by the existing mirror test. `tests/unit/console-needs-first-screen.test.ts`, `tests/unit/operator-surface-referral.test.ts`, `docs/specs/reports/operator-needs-first-screen-convergence.md`. Browser proof ran through a proxy that refused all writes; the stop latch was not touched, no enable or rollback route was called, and the dashboard PIN was never read or used.
83
+
84
+ ## Class-Closure Declaration (display-only mirror)
85
+
86
+ - **`defectClass`** — the agent-authored rule "Operator-Surface Quality rule 1" was enforced only by a written attestation. Not a prompt defect; the fix is enforcement added beside it.
87
+ - **`closure`** — `guard`: `tests/unit/console-needs-first-screen.test.ts`.
@@ -0,0 +1,50 @@
1
+ # Side-Effects Review — recommended services, step 1: saved choices
2
+
3
+ **Tier 2.** Spec: `docs/specs/recommended-services.md`, approved by the operator on 2026-11-03. About 25 files. Spec review used all 6 rounds and did not converge by the round rule. The operator chose to proceed, with the last fixes reviewed during the build. The second-pass reviewer below covers that for this step.
4
+
5
+ ## Summary
6
+
7
+ Adds the signed choice ledger, its replicated store, read and no routes, legacy decline import, and retirement of the two old offers. Sends no offers. This is part of rollout step 1, not all of it. Still to come in step 1: the ACT-115 owner-check fix, the migration-complete flag, moving door and Tailscale steps out of the CLI, and the delivered-first-result trigger. The yes route, catalog, recipes and offers follow in later steps. All are tracked by commitment CMT-031.
8
+
9
+ ## 1. Over-block
10
+
11
+ The evaluator and `/features/:id/surface` now refuse `cloudflare-tunnel` and `git-backup`. Until offers go live, nothing suggests those two features. Both are default on, so few agents ever saw these suggestions. A no without the PIN is refused, which leaves an owner with no PIN configured unable to record one; `checkMandatePin` answers 503 there.
12
+
13
+ ## 2. Under-block
14
+
15
+ The agent can read the PIN, so a deliberately hostile agent could record a no. The operator accepted this limit until owner proof ships. A local file edit could also alter the ledger; signatures are checked only for peer rows.
16
+
17
+ ## 3. Level-of-abstraction fit
18
+
19
+ A separate ledger, for reasons in the spec: `FeatureRegistry` state is local, erasable, and overwritten by bootstrap. It reuses the established replicated-store shape and machine signatures.
20
+
21
+ ## 4. Signal vs authority
22
+
23
+ No brittle check gains blocking authority over messages or actions. The fold decides nothing yet except what the route reports. Refusing retired offers is an exact id match. See `docs/signal-vs-authority.md`.
24
+
25
+ ## 5. Interactions
26
+
27
+ The store is enabled only where the coherence journal is live, so it never advertises a capability with no applier, and an explicit `enabled: false` is honoured. Old peers don't register the kind and ignore it.
28
+
29
+ ## 6. External surfaces
30
+
31
+ Two new routes. A new CLAUDE.md section via template and migration. No outbound messages. No operator-facing action is added beyond the PIN route, which has no dashboard surface until step 2; no flow sends anyone to it before then.
32
+
33
+ ## 7. Multi-machine posture
34
+
35
+ Replicated through the `recommendedServices` store, registered in the coherence registry, `rotateKeep: 0`. **It depends on the coherence journal, which is dev-gated, so on the fleet today choices stay on one machine.** Journal replication must also be enabled, which is explicit-only. `GET /recommended-services` reports `replicating` from those real states, not from a hook being attached. Own rows are re-sent at boot, so nothing written while it was off is lost. Offers must not go live on a multi-machine agent while this is false; the spec's rollout now states that. Rows verify under the writing machine's identity key. An unverifiable row is not accepted now and is re-read at next boot. Single machine: in backup `includeFiles`.
36
+
37
+ ## 8. Rollback cost
38
+
39
+ Revert the release. The ledger file and journal rows stay inert, and return to use on re-upgrade. Older code offers the two legacy features again through their triggers, as the spec states.
40
+
41
+ ## Second-pass review
42
+
43
+ **Concern raised, then fixed.** The independent reviewer found that replication wouldn't work on the fleet while the text claimed it would, that a failed legacy import could stop boot, that the store overrode an explicit off switch, and that this artifact understated what step 1 still needs. All four are addressed above. A re-check found `replicating` could read true with nothing replicating; it now reads the store and replication switches. The reviewer checked wiring order, signing, the merge fold, backup paths and journal kind lists and found them clean. Live replication between two real machines has not been run.
44
+
45
+ ## Test corrections from the first CI run
46
+
47
+ Test files only, no runtime change, so this commit did not go back to the second-pass reviewer.
48
+
49
+ - `tests/unit/capabilities-discoverability.test.ts`: the new route file is added to the list the check scans. Without it the capability entry read as a dead entry.
50
+ - `tests/e2e/discovery-evaluator.test.ts`: this test never enabled the feature. Its consent record had an empty `dataImplications`, the registry refused it, and the refusal went unchecked. The feature stayed `interested`, and the test passed only because that lower priority pushed it past the 10-feature cap. Retiring two offers freed room and exposed this. The record is now valid and the test asserts that the transition succeeded.
@@ -0,0 +1,63 @@
1
+ # Side-Effects Review — expired rerouted sessions release capacity
2
+
3
+ ## Summary of the change
4
+
5
+ Tier 2 session lifecycle repair under the approved `docs/specs/june15-headless-spawn-reroute.md`. The configured hard lifetime is supposed to end a rerouted one-shot and record a timeout. On the operated host, `dashboard-console-default` passed its 480-minute limit while the session manager repeatedly printed “Killing”; durable `logs/reap-log.jsonl` instead recorded `skipped:active-process`, leaving the session running and the subscription lane at 6/6. This patch gives only the rerouted-session monitor a private capability to pass process-activity KEEP checks after it rechecks the saved lane and elapsed lifetime at the termination boundary. Other KEEP reasons still apply. The log now says “Killed” only after termination succeeds.
6
+
7
+ ## Decision-point inventory
8
+
9
+ The existing decision is whether a rerouted interactive one-shot has passed its saved hard deadline. The monitor and termination boundary both check that fact. A new private capability affects only `active-process`, `main-process-active`, and `process-uninspectable` reasons; it cannot be supplied through the public `terminateSession` method. Normal sessions, unexpired reroutes, and other termination reasons use the previous guard path.
10
+
11
+ ## 1. Over-block
12
+
13
+ An expired rerouted one-shot with an active tmux child was previously always retained, defeating the lifetime and leaving capacity occupied. A real `ReapGuard` unit test covers the active child and active main-process signals and now expects `killed/rerouted-lifetime`. The existing hard-lifetime test had no installed guard, which is why it missed the production failure.
14
+
15
+ ## 2. Under-block
16
+
17
+ The patch intentionally allows an active process to be stopped at its explicit hard deadline. It does not bypass protected sessions, standing sessions, recovery, pending injection, relay lease, recent user interaction, open commitment, active subagent, or structural long work. A second real-guard test verifies a recent user message still blocks termination. The private symbol, literal reason, lane, completion mode, positive finite lifetime, valid start time, and elapsed-time check all must agree before the process-activity bypass applies.
18
+
19
+ ## 3. Level-of-abstraction fit
20
+
21
+ The session manager already owns the hard-lifetime monitor and termination guard. The fix stays there, rather than changing the global ReapGuard or raising the host-wide session cap. It uses the same private termination entry point and durable session state as other lifecycle authorities.
22
+
23
+ ## 4. Signal vs authority compliance
24
+
25
+ The printed “Killing” line was a misleading signal: it preceded the guarded termination result. The durable reap log showed the actual `skipped:active-process` decision. The patch moves the message after success and keeps the termination guard authoritative. The new capability is not inferred from a log; it is minted by the monitor and independently checked against the saved session and clock.
26
+
27
+ ## 4b. Judgment-point check
28
+
29
+ No model or operator decision is replaced. The configured 480-minute limit is an existing deterministic policy. Timeout still produces the existing degradation report and job retry semantics only after termination succeeds.
30
+
31
+ ## 5. Interactions
32
+
33
+ A rerouted one-shot that reaches its hard limit may be stopped even if its process tree is still active. That frees one subscription slot for queued work, including the feedback executor. The job scheduler sees `killed` and records a timeout. If another KEEP reason applies, the session stays running and `reapBlocked` remains durably logged; the timeout line no longer claims it was killed.
34
+
35
+ ## 6. External surfaces
36
+
37
+ `GET /sessions` reflects the real terminal state after a successful kill. The reap log remains the audit surface for a skipped termination. No API shape, Telegram format, GitHub permission, or credential access changes.
38
+
39
+ ## 6b. Operator-surface quality
40
+
41
+ The operator can distinguish a completed hard-timeout kill from a blocked attempt. This addresses the observed repeated false “Killing” message and the feedback executor’s unexplained 6/6 admission refusal.
42
+
43
+ ## 7. Multi-machine posture
44
+
45
+ A rerouted tmux session is machine-local. The existing lease-holder and local session state checks still run before termination. The private capability cannot be sent over the API or another machine. A peer observing the session after owner transfer remains subject to the same lease gate.
46
+
47
+ ## 8. Rollback cost
48
+
49
+ Revert this small source and test change in a patch release. No stored schema, config, or migration changes. A session already killed at its hard deadline cannot be resumed automatically, which is the pre-existing specified timeout consequence.
50
+
51
+ ## Conclusion
52
+
53
+ The live 6/6 cap is caused by a hard-lifetime attempt blocked by `active-process`; it is not a phantom counter. Focused real-guard unit tests (49 in file), build, and lint are the current local evidence. Full three-tier verification and CI remain required before shipping.
54
+
55
+ ## Second-pass review
56
+
57
+ **Reviewer:** rerouted_lifetime_review
58
+
59
+ Concur with the review. The module-private capability is accepted only for the literal timeout reason, saved rerouted lane and pattern mode, a finite positive limit, and an elapsed deadline. It bypasses three process-activity reasons; lease ownership and the other ReapGuard protections still apply. The real-guard expiry test fails on the old code, and the recent-message test checks a surviving higher-priority veto. The reviewer did not edit files or run broad tests.
60
+
61
+ ## Verification update — 2026-11-04
62
+
63
+ The first exact-head merge-tree run at `552c8c492` passed all unit tests (57,053) and integration tests (5,507), but one general lifecycle E2E test failed among 3,747 E2E tests. The verifier correctly refused an isolation rerun because that test imports the changed session manager. A direct run of the same lifecycle file on this branch then passed all 10 tests. A separate PR's full verifier also failed that file at 09:00Z, so the first failure cannot yet be attributed to this patch. The full E2E suite is being rerun under the shared test limit; shipping still requires a green exact-head result and a live timeout receipt. This update changes no source or test behavior.
@@ -0,0 +1,5 @@
1
+ # Plain overview: a test that checked too early now waits
2
+
3
+ Instar has an automatic helper that brings forgotten to-do items back to attention. One end-to-end test starts a test server and then checks, after just three hundredths of a second, that the helper has already done its first pass. On a busy computer running many tests at once, the first pass sometimes comes a little later, so the test failed even though nothing was broken. That failure blocked an unrelated change, the new native session screen for the phone app, from merging.
4
+
5
+ The test now waits for the first pass, checking every tenth of a second for up to ten seconds, and then makes exactly the same checks as before. Nothing in Instar itself changes. If the helper ever truly failed to run, the test still fails, just after ten seconds instead of at once.
@@ -0,0 +1,9 @@
1
+ # Side effects: resurfacer e2e waits for its first run
2
+
3
+ Test-only. tests/e2e/undated-action-resurfacer-lifecycle.test.ts waited a fixed 30 ms after boot and then required the first resurfacer run to have happened. On a loaded peer verifier (2026-11-04, PR 2707) the run came later, so the test failed with totalRuns 0; it passed when rerun on the Studio. The test now polls the status route every 100 ms, up to 10 s, until the first run is recorded, then makes the same assertions. No product code changes.
4
+
5
+ 1-8: no runtime surface; rollback is a revert.
6
+
7
+ ## Class-Closure Declaration
8
+
9
+ - `unbounded-self-action`: closure `n/a`, test-only, with a bounded wait.