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
@@ -23,6 +23,18 @@ export const STAGE_B_CERTIFIED_SET = {
23
23
  "src/core/StageBStartupReadiness.ts"
24
24
  ],
25
25
  "excluded": [
26
+ {
27
+ "file": "src/core/claudeChildAuth.ts",
28
+ "reason": "Claude-only helper that passes the sign-in key to claude children; a Codex launch never reads it, so it cannot change the behaviour the Stage-B evidence certifies."
29
+ },
30
+ {
31
+ "file": "src/monitoring/FeatureEvidenceLog.ts",
32
+ "reason": "Write-only evidence log reached through DegradationReporter; its calls never throw, return nothing the caller reads, and do not alter the certified Codex Stage-B delivery path."
33
+ },
34
+ {
35
+ "file": "src/utils/jsonl-rotation.ts",
36
+ "reason": "Size-based log rotation used only by the evidence log in this closure; it never throws and does not alter the certified Codex Stage-B delivery path."
37
+ },
26
38
  {
27
39
  "file": "src/scheduler/jobScriptProtocol.ts",
28
40
  "reason": "Shared deterministic script-job output parser reached through scheduler imports; it does not alter the certified Codex Stage-B delivery path and has separate script protocol unit and lifecycle coverage"
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "generatedFrom": "source-tree",
4
4
  "registrySha256": "e9eb5bb7f56ce6f81c5f80210c1ec7999d4b8c7d2ff1ab5cfd97a269172ce2ac",
5
- "packageVersion": "1.3.1649",
5
+ "packageVersion": "1.3.1650",
6
6
  "guards": [
7
7
  {
8
8
  "ref": "docs/audits/phase-b/f10-triage.md",
@@ -1,5 +1,5 @@
1
1
  {
2
- "sha256": "925a6e27d3abc6b957a8e865a9623c9a4a607cc43ddbf9bbe70cc8193b2f0e0e",
2
+ "sha256": "a88c8170fba3168f43e10fed54a788521b7b476fb4af8ba0dea8ab7ae70260c9",
3
3
  "registrySha256": "e9eb5bb7f56ce6f81c5f80210c1ec7999d4b8c7d2ff1ab5cfd97a269172ce2ac",
4
- "packageVersion": "1.3.1649"
4
+ "packageVersion": "1.3.1650"
5
5
  }
@@ -2,5 +2,5 @@
2
2
  "sha256": "e9eb5bb7f56ce6f81c5f80210c1ec7999d4b8c7d2ff1ab5cfd97a269172ce2ac",
3
3
  "articleCount": 93,
4
4
  "generatedFrom": "docs/STANDARDS-REGISTRY.md",
5
- "packageVersion": "1.3.1649"
5
+ "packageVersion": "1.3.1650"
6
6
  }
@@ -2155,6 +2155,24 @@
2155
2155
  "note": "Never pruned by design: a message signed by a key must stay checkable after the key is revoked. One activation and at most one revocation row per paired phone key per writing machine, so it grows only with pairings."
2156
2156
  }
2157
2157
  },
2158
+ {
2159
+ "category": "recommended-services",
2160
+ "description": "A person's yes and no choices about recommended outside services (docs/specs/recommended-services.md): an append-only signed ledger that replicates as the recommendedServices store.",
2161
+ "scope": "must-be-coherent",
2162
+ "freshness": "eventual",
2163
+ "conflictShape": "append-only",
2164
+ "transport": "peer-http",
2165
+ "paths": [
2166
+ "state/recommended-services/"
2167
+ ],
2168
+ "grandfathered": false,
2169
+ "retention": {
2170
+ "class": "C",
2171
+ "access": "jsonl",
2172
+ "complianceHold": true,
2173
+ "note": "Never pruned by design: dropping a row could undo a person's no. Volume is tiny: at most a few rows per service per person."
2174
+ }
2175
+ },
2158
2176
  {
2159
2177
  "category": "ecosystem-ideas",
2160
2178
  "description": "The ecosystem idea pipeline (docs/specs/ecosystem-idea-pipeline.md): an append-only event ledger that replicates as the ecosystemIdeas store, a per-machine framework admission record and notice dedupe. Source mirrors and index.db in the same directory are a rebuildable cache.",
@@ -21,6 +21,8 @@ import { JOB_DECLARED_FAILURE_AWARENESS } from "../scheduler/jobDeclaredFailure.
21
21
  // function call inside generateClaudeMd — no module-init cycle (PostUpdateMigrator
22
22
  // never imports templates).
23
23
  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';
24
+ import { SURFACE_REFERRAL_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
25
+ import { RECOMMENDED_SERVICES_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
24
26
  import { MINIMUM_OPERATOR_EFFORT_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
25
27
  import { CODEX_DEVICE_LIMIT_CLAUDEMD_BULLET } from '../core/PostUpdateMigrator.js';
26
28
  import { UPDATE_APPLY_VERIFY_HOLD_CLAUDEMD_LINE } from '../core/PostUpdateMigrator.js';
@@ -439,6 +441,7 @@ ${REAPER_BACKGROUND_WORK_BULLET}
439
441
  ${STANDING_SESSIONS_BULLET}
440
442
  ${REROUTED_LOGIN_EXPIRED_BULLET}
441
443
  ${INTERACTIVE_LOGIN_EXPIRED_BULLET}
444
+ ${CLAUDE_KEY_HEALTH_BULLET}
442
445
  - **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\`).
443
446
  - 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.
444
447
  - 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.
@@ -1043,6 +1046,7 @@ ${ROUTING_SPEND_CLAUDEMD_SECTION(port)}
1043
1046
  ${MATURATION_BOARD_CLAUDEMD_SECTION(port)}
1044
1047
  ${MATURATION_LADDER_CLAUDEMD_SECTION(port)}
1045
1048
  ${QUEUE_PACE_CLAUDEMD_SECTION(port)}
1049
+ ${RECOMMENDED_SERVICES_CLAUDEMD_SECTION(port)}
1046
1050
  ${ECOSYSTEM_IDEAS_CLAUDEMD_SECTION(port)}
1047
1051
  ${MOBILE_PAIRING_CLAUDEMD_SECTION(port)}
1048
1052
  ${MOBILE_CHAT_CLAUDEMD_SECTION(port)}
@@ -1844,6 +1848,8 @@ Record what I learn. Build infrastructure, not one-offs. Grow to meet the user's
1844
1848
  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".
1845
1849
 
1846
1850
  ${TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION}
1851
+
1852
+ ${SURFACE_REFERRAL_CLAUDEMD_SECTION}
1847
1853
  ### Context-Aware Outbound Review (why was my message flagged / would my reply have been blocked?)
1848
1854
 
1849
1855
  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).
@@ -2733,6 +2739,9 @@ export const REROUTED_LOGIN_EXPIRED_MARKER = 'A job session stuck at an expired
2733
2739
  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.`;
2734
2740
 
2735
2741
  /** Content-sniff marker for the interactive expired-login bullet (CMT-1008, Migration Parity). */
2742
+ export const CLAUDE_KEY_HEALTH_MARKER = 'A rejected sign-in key is told and recovers';
2743
+ 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\`.`;
2744
+
2736
2745
  export const INTERACTIVE_LOGIN_EXPIRED_MARKER = 'A conversation stuck at an expired login moves to a signed-in account';
2737
2746
 
2738
2747
  /** Interactive expired-login awareness bullet (CMT-1008). Shared by the generated CLAUDE.md and PostUpdateMigrator. */
@@ -0,0 +1,105 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ An agent signed in with one key (`sessions.credentials.anthropic`, every headless cloud install) passed it to sessions only. `ClaudeCliIntelligenceProvider` ran `claude -p` with the server's own env, so every internal model call answered "Not logged in". Every server-side `claude` child now gets the same key: the provider's default and hardened paths, project rounds, the headless one-shot, Threadline pipe sessions, the lifeline doctor and triage. Direct children take it through their env; shell and tmux launches source a private file that is deleted before `claude` starts, so the key stays out of argv.
9
+
10
+ New `ClaudeKeyHealth`, active only with an oauth-token configured. A failed call or a session at the login screen asks for a direct probe. Only Anthropic's 401, seen twice, makes a key dead; "Not logged in" is reported as an Instar fault. The operator gets one notice, each waiting person is told once, and authenticated `/health` shows `claudeKey`. `instar set-claude-key` puts a new key in place, a running server finds it within a minute with no restart, and once a probe proves it, conversations at the login screen restart and answer what they missed. `SessionManager.setAnthropicKey` carries the key into its config copy.
11
+
12
+ Instar's own merge tool now refuses a pull request that changes the constitution registry unless its body names its counterpart in the other rule book, or says why it has none (`scripts/check-constitution-pairing.mjs`, used by `scripts/safe-merge.mjs`). The green-PR watcher treats that refusal as waiting on a body edit. Adds the map of differences between the two books and corrects the direction-guard document. Does nothing outside the two instar repositories.
13
+
14
+ 113 switched-off features now record what they do: when each fires, holds back or fails, with the reason and a few small facts. Rows go to the evidence log on development agents, so the maturation ladder can judge each feature by its own behaviour. No feature's behaviour changes. Decisions taken per message are limited to one row per window, and that row says how many it stood for.
15
+
16
+ The feedback executor's early capacity check now uses the same limits as its actual confined canary and build spawns. It treats the final rerouted slot and the global overflow slot as reserved for scheduler-proven jobs. A full lane defers the feedback attempt before it claims an item, creates a workspace, or spends a start.
17
+
18
+ An owner's paired phone (Instar iPhone app) can open the agent's dashboard console without typing the dashboard PIN. After the owner's Face ID or passcode, the app signs a one-time server challenge with a second Secure Enclave key that only signs after that check, receives a one-minute single-use ticket bound to that phone and address, and the console trades it once at `POST /dashboard/console-ticket` for the same token a PIN unlock returns. It never returns the operator session, so actions that need the PIN still ask for it. New device routes: `POST /mobile/device/presence-key`, `POST /mobile/console-ticket/challenge`, `POST /mobile/console-ticket` (owner phones only, TLS or loopback only). Audit: `.instar/state/mobile-console-tickets.jsonl` (metadata only). Off switch: `mobilePairing.consoleTicket.enabled: false`. MSP phones, phones without a passcode, and older app builds keep the PIN box.
19
+
20
+ The Instar iPhone app can now show a session natively. A paired owner phone may read a session's screen with `GET /sessions/<name>/output` and type plain text into it with `POST /sessions/<name>/input`, both signed by the phone's device key. Two new entries in the device allowlist carry a new `ownerOnly` flag (MSP, unassigned, pending, revoked and unsigned requests are refused) and their own rate buckets. A device-only router mounted before the main routes handles them; Bearer requests to the same paths reach the existing handlers unchanged.
21
+
22
+ The device path only reaches sessions running on this machine, matched exactly (tmux name, then id, then name). It refuses control characters, so the phone cannot press keys. It redacts this agent's token, the dashboard PIN and view signatures from the screen text. It keeps a durable 3-minute record of accepted inputs, so a captured request can never be typed twice, even across a restart. It logs each typed message (without its text) in `logs/mobile-session-input.jsonl`. A session on another machine is answered with a plain reason naming that machine; nothing is proxied. Typing is limited to 12 a minute per phone and 12 a minute across all phones.
23
+
24
+ Everything that needs the operator now has one list, `dashboard/console/needs-model.js`, built from each page's own model: merging stopped, pull requests waiting for approval, feedback decisions, sign-ins, agents waiting, permission approvals, plans waiting on them, passwords requested, and spending limits that are on but not enforcing. Home's "What needs you" count and headline include all of it, and say "Nothing needs you that I can see" rather than a confident all-clear when one of those reads failed. Each page leads with its need and the control to act on it. Costs gets a new lead card, Development gets a button that opens Shipping when a pull request waits for approval, and the Agents pairing switch moves above the lists. Page wording no longer says "below". A warning that an invite leaked now offers "Make a new invite".
25
+
26
+ A new advisory outbound rule, `B22_SURFACE_REFERRAL`, nudges an agent whose message sends the operator to a page without a direct link, the exact on-screen words, or having loaded the page at the operator's screen size first. It is a nudge with a recorded override, never a wall. After loading the page, the agent resends with `--tone-complied B22_SURFACE_REFERRAL`.
27
+
28
+ Instar now keeps a signed, append-only record of a person's yes or no for each recommended outside service, and it replicates across the agent's machines where machine sync is on: the coherence journal is live, this store is on, and journal replication is enabled. The route's `replicating` field says whether it is. Rows written while it was off go out at the next boot once it's on. A no stands until the person confirms a yes that names it, so clock skew and delayed sync can't undo a refusal. A no needs the dashboard PIN. Old declines of Cloudflare and Git backup carry over as offer suppression only. The old suggestion paths no longer offer those two features. No offers go out yet.
29
+
30
+ A rerouted one-shot that passes its configured hard lifetime can now finish its timeout cleanup even when the interactive process still appears active. The session manager checks the saved lane and deadline again before relaxing only process-activity vetoes. All other session protections remain. It now logs “Killed” only after termination succeeds.
31
+
32
+ An end-to-end test now waits for the first resurfacer run instead of checking after a fixed 30 ms.
33
+
34
+ ## What to Tell Your User
35
+
36
+ If your agent runs on a cloud server with a sign-in key, its background checks now work. Those checks review outgoing messages and sort incoming ones, and until now they failed quietly on these installs. If the key ever stops working, your agent tells you plainly and says how to fix it. Once a new key is in place, open conversations pick up by themselves. A conversation that ended during the outage is not replayed.
37
+
38
+ Nothing changes for you. This only affects how Instar's own rule book is maintained.
39
+
40
+ Nothing changes for you. Features still switched off now keep a record of what they did and why, so it's clear when each is ready to turn on.
41
+
42
+ When background session capacity is full, feedback work waits cleanly for room instead of starting preparation and then failing at its safety check.
43
+
44
+ Opening the dashboard from the Instar app on your phone no longer asks for the PIN after Face ID. Anything that changes something important still asks for the PIN. If the app ever says to pair the phone again, that restores PIN-free opening.
45
+
46
+ The session button in a chat now opens the session right in the app: you see what the session is doing, live, and can type to it, with no browser and no PIN. There is also a Sessions list on the agent's page. Only your own phone can do this, and it can only type plain text, not special keys. If the agent hasn't been updated yet, the app offers the dashboard instead.
47
+
48
+ Anything that needs you now shows on your home page and at the top of its own page, with the button right there. When I send you to a page, my message comes with a direct link and the exact words to look for, and I check the page first.
49
+
50
+ Your choices about outside services like Tailscale or Bitwarden are now saved in one place. On agents with machine sync switched on, they follow you across your machines. I won't start offering these yet. That comes once setup for each one is proven.
51
+
52
+ A worker that runs past its time limit no longer holds a subscription slot forever just because its process is still present. Its work is recorded as timed out and can follow the existing retry path. Recent user activity and the other session safety checks still protect live conversations.
53
+
54
+ Nothing changes for you; this only makes a test reliable on busy machines.
55
+
56
+ ## Summary of New Capabilities
57
+
58
+ - `instar set-claude-key` puts a new Claude sign-in key in place, from stdin or a hidden prompt.
59
+ - Authenticated `GET /health` shows `claudeKey` on agents signed in with a key.
60
+ - Off switches: `sessions.claudeKeyHealth.enabled: false` and `sessions.claudeChildAuth.enabled: false`.
61
+
62
+ None for agents outside the Instar repositories. For maintainers: a pairing check for changes to the two rule books.
63
+
64
+ - 113 more features can be judged from real records instead of reading "no data".
65
+
66
+ Owner phones open the console signed in, using a single-use ticket backed by a Face ID-gated key the agent verifies itself.
67
+
68
+ - Watch a session's screen live in the app, refreshed every second and a half.
69
+ - Type to a session from the app (plain text, owner's phone only, logged without the text).
70
+ - A native list of the agent's sessions, with machine and how long each has run.
71
+ - Plain answers when a session has ended or runs on another of your machines.
72
+
73
+ - One registry of what needs the operator, feeding Home's count and headline.
74
+ - A test that fails the build when a page buries a need, offers no action for it, or points at a place in its wording.
75
+ - `B22_SURFACE_REFERRAL`: an outbound nudge for sending the operator to a page.
76
+
77
+ - `GET /recommended-services` shows the saved choice for each service.
78
+ - `POST /recommended-services/:id/no` records a no, with the dashboard PIN and an optional reason category.
79
+
80
+ None. This repairs the rerouted-session lifetime path.
81
+
82
+ None.
83
+
84
+ ## Evidence
85
+
86
+ Found on nimbus by the customer proof (fb-03ec0234-b5b, fb-1dc4a0ca-260): PromptGate 463/463 errors, `llmReliability` failing. Real CLI failure output was captured on Claude Code 2.1.316 and is pinned in `tests/unit/ClaudeKeyHealth.test.ts`. `tests/unit/claude-spawn-auth-class.test.ts` fails if a new `claude` launch site neither takes the key nor says why not.
87
+
88
+ Unit and integration tests cover each outcome, including a failed read refusing as unknown. Run against real history since #2323, the checker reported drift on #2682, #2380, #2194, #2323 and instar-2 #182, none of which has a declaration line.
89
+
90
+ Reproduction of the gap: 115 of 172 ladder entries read "no data" with nothing recording. After this, 2 remain, and neither can record from inside the server: one is a CI script, one has no decision point. Unit tests of every changed module pass, and the full run is the merge gate. Text is scrubbed and bounded; message text, prompts and credentials are not recorded.
91
+
92
+ The production session manager's focused tests passed 65/65, covering the boundary where one rerouted slot remains reserved, the global session limit, actual refusal of a feedback canary, and continued admission of a scheduler-proven job. Build passed. Full unit, integration, end-to-end, and live post-deployment checks remain pending.
93
+
94
+ Unit, integration and end-to-end tests cover single use, expiry, Host binding, revocation between mint and redeem, MSP refusal, replay after restart, the off switch, the throttle and the audit. A real-browser run against a throwaway agent opened the real console signed in with a valid ticket and showed the PIN box for a used, unknown or revoked one; its first run found and fixed a Host-comparison defect for phones paired on an IP address. The app's 158 unit tests pass. The no-second-prompt path on a real Secure Enclave runs first on the operator's phone and falls back to the PIN box if it fails.
95
+
96
+ - Spec docs/specs/mobile-native-session-screen.md converged at the 6-round cap with GPT-6 Astra and the clean-door reader; review found and fixed control characters acting as keys, replay across a restart (twice), credential text in pane output, wrong-session targeting and event-loop blocking.
97
+ - Unit: allowlist shape, owner-only flag, named buckets, text filter, exact resolution, miss classification, replay record (including after a restart), redaction, audit rotation, CLAUDE.md migration.
98
+ - Integration: both sides of the allowlist through the production authenticator (owner allowed; MSP, unassigned, pending, revoked, notify token, unsigned and credential-less refused; Bearer passes through), session and machine binding, peer lookups, replay, buckets.
99
+ - E2E: production AgentServer, a phone paired through redeem and confirm, reading and typing into a real session record.
100
+
101
+ Each of the nine states was put on its real page through a proxy that refuses all writes, in a real browser at 1280x728 and 390x844: all 18 runs show the action on the first screen with no scrolling and no sideways scroll, and screenshots were read. Home named "Automatic merging is stopped" with a link to it when that state was on. `tests/unit/console-needs-first-screen.test.ts` renders the shipped pages and carries negative controls. A dashboard opened on another machine sees merging, approvals and password requests only for that machine, as those pages do today.
102
+
103
+ `tests/unit/recommended-services-ledger.test.ts`, `tests/unit/recommended-services-wiring.test.ts`, `tests/integration/recommended-services-routes.test.ts` and `tests/e2e/recommended-services-alive.test.ts`. The e2e proves a real AgentServer answers 200, enforces the real PIN check, and keeps a no across a restart. Replication between two real machines has not been run live yet.
104
+
105
+ On Echo, `dashboard-console-default` crossed 480 minutes. The server printed repeated kill attempts, while the durable reap log recorded `skipped:active-process` and the feedback executor stayed blocked at 6/6. A focused test now uses the real `ReapGuard` with active child and main-process signals and verifies the expired reroute ends; another verifies recent user activity still vetoes. The production-shape E2E test also checks the timeout through the HTTP session listing. Focused unit tests, build, lint, and independent review passed. Full three-tier verification remains before merge.
@@ -0,0 +1,5 @@
1
+ # Dashboard without the PIN on your phone — plain English
2
+
3
+ When you open the dashboard from the Instar iPhone app, the app has already checked your Face ID, but the dashboard still asked for its PIN. Now the phone proves it is you instead. It holds a second key in its secure chip that only works right after Face ID or your passcode. The app uses it to get a pass from the agent that works once, only for one minute, and only at the address it was issued for. The dashboard trades that pass for exactly what the PIN would have given it, and nothing more: approving or changing something important still asks for the PIN.
4
+
5
+ A phone you have removed gets no pass, and a pass it got just before removal is refused. A copied request is useless because every pass needs a fresh challenge that the agent forgets after one use or a restart. The pass never appears in a web address, and the dashboard on the phone now keeps nothing on disk, which also clears an old sign-in an earlier PIN left there. Helpers' phones and phones without a passcode still see the PIN box, and whenever anything fails the dashboard simply shows the PIN box as before.
@@ -0,0 +1,116 @@
1
+ # Side-Effects Review — cloud agents: sign-in key for internal calls, dead-key handling
2
+
3
+ **Version / slug:** `cloud-key-internal-calls`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent general-purpose reviewer agent`
7
+
8
+ ## Summary of the change
9
+
10
+ Every server-side `claude` child now gets the configured oauth key through one helper (`claudeChildAuth`), reading the value PR #2632 already resolves. New `ClaudeKeyHealth` confirms a dead key with a direct probe, tells the operator and waiting people with fixed text, and restarts sessions stuck at the login screen once a working key is proven. New `instar set-claude-key`.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - Is the key dead — add — two 401s from Anthropic on direct probes.
15
+ - Notify operator — add — after the self-heal re-read and confirmation.
16
+ - Refresh a session — add — at the login screen, bounded per episode, through the ordinary work gate where it is on.
17
+ - Skip the pool swap on a key agent — add — an env key overrides any pool account.
18
+ - Tone gate, sentinel, external gate — pass-through — failure directions untouched.
19
+
20
+ ---
21
+
22
+ ## 1. Over-block
23
+
24
+ The new code blocks nothing inbound or outbound. `set-claude-key` refuses a value that doesn't look like a `claude setup-token` key; a valid key of a future shape would be refused until `looksLikeClaudeToken` is updated. The pool swap is skipped on key agents, which is correct because an env key overrides any pool account.
25
+
26
+ ---
27
+
28
+ ## 2. Under-block
29
+
30
+ A session that ended during an outage has its messages not replayed. A key-only agent with `subscriptionPath` set keeps today's behaviour on the opt-in tmux adapters. An API-key-only agent's internal calls stay failed, by the subscription-by-default rule. The three session lanes still pass the key in tmux `-e` argv.
31
+
32
+ ---
33
+
34
+ ## 3. Level-of-abstraction fit
35
+
36
+ The key travels through one small module beside the config, not a parameter on eight provider callers, so a new caller can't forget it. A structural test holds that. Recovery reuses `SessionRefresh` and the login-screen classifier, and adds no second restart path.
37
+
38
+ ---
39
+
40
+ ## 4. Signal vs authority compliance
41
+
42
+ Signals: internal call failures and the login screen. They only request a probe. Authority: Anthropic's own 401 on a real call, twice. A deterministic check is right here, because it reads a status code and judges no meaning. The refresh is further limited. Outside a recovery sweep, a matching launch key never refreshes. During the sweep after a proven outage, screen text is enough, once per session per key. The work gate applies where it is on, which is development agents. Elsewhere login text printed by a working session during that sweep can cost it one restart. That normally resumes the conversation; with no resume entry it starts fresh, and a failure mid-restart leaves no session until the next message. The worst case is one lost in-flight turn.
43
+
44
+ ---
45
+
46
+ ## 4b. Judgment-point check (Judgment Within Floors standard)
47
+
48
+ All points are invariant: each reads a status code, a hash comparison or a counter. None weighs meaning.
49
+
50
+ ---
51
+
52
+ ## 5. Interactions
53
+
54
+ - Circuit breaker: the probe bypasses it on purpose; the spawn cap still applies.
55
+ - Pool swap: skipped on key agents through `prependInteractiveLoginExpiredSink`; unchanged elsewhere.
56
+ - Triage lane: previously had no key and hardcoded `credentialSource: 'store'`. It now reports `env` when a key is passed.
57
+ - Tone gate, sentinel and external gate start getting real answers on key agents, so messages that passed the fixed leak floor may now be held by a model verdict. That is the intended behaviour and a visible change for those agents.
58
+ - Agents with a key and a stored login: internal calls move to the key, matching their sessions.
59
+ - Stage-B release evidence: `claudeChildAuth.ts` is reached by import from the certified set, so it is listed as excluded with a reason. A Codex launch never reads it, and no certified file changed.
60
+
61
+ ---
62
+
63
+ ## 6. External surfaces
64
+
65
+ New CLI command. Authenticated `/health` gains `claudeKey`, and public `/health` may read degraded while dead. Fixed text goes to the Telegram hub, the Slack attention channel and session channels. The probe makes one small authenticated call, and in `ok` state at most one per 5 minutes when signals arrive.
66
+
67
+ ---
68
+
69
+ ## 6b. Operator-surface quality (Operator-Surface Quality standard)
70
+
71
+ The notice says what happened, what it means and the exact steps, in plain words. Restoring needs a computer, because `claude setup-token` has no phone form. This is stated in the spec's limits.
72
+
73
+ ---
74
+
75
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
76
+
77
+ Machine-local, a stated limit. The key lives in each machine's `config.json`, and sessions are local processes. Each machine notices and reports its own key and the operator restores each. `state/claude-key-health.json` is not replicated. Key-only installs today are single-machine.
78
+
79
+ ---
80
+
81
+ ## 8. Rollback cost
82
+
83
+ Revert the PR, or set either off switch; both are read live. Config is not migrated. Leftovers are an unused state file and a CLAUDE.md note.
84
+
85
+ ---
86
+
87
+ ## Conclusion
88
+
89
+ Safe to ship. The behaviour change for key agents is the fix itself. The live proof on nimbus is still required before calling it done.
90
+
91
+ ---
92
+
93
+ ## Second-pass review (if required)
94
+
95
+ **Reviewer:** independent general-purpose reviewer agent, four passes over the code diff
96
+ **Concurred:** yes, after the fixes listed below
97
+
98
+ Independent reviewer, on the code diff. Found no credential leak and nine defects: a replaced key could be paged about, a restored key could go unprobed after a long outage, the refresh loop was not re-entrant, the confirm delay could be bypassed, a removed key was ignored, the off switch and base URL missed three entry points, env files stayed after a failed launch, late-bound Telegram topics were missed, and background promises had no catch. All nine fixed with tests. A second read found three more: the stated restart bound was inaccurate, recovery could still act after the key was removed, and the lifeline read its off switch from a frozen copy. All three fixed. A third read found the Slack respawner renames a session, so the once-per-key record missed it; fixed. The fourth read concurred. After that, the full unit lane found four catches over the no-silent-fallbacks ratchet: a failed session listing now files a degradation report, and three send failures carry an exemption because `delivered` drives the retry and its capped report. That small change was not re-read by the reviewer.
99
+
100
+ ---
101
+
102
+ ## Evidence pointers
103
+
104
+ `tests/unit/ClaudeKeyHealth.test.ts`, `tests/unit/claudeChildAuth.test.ts`, `tests/unit/ClaudeCliIntelligenceProvider-key.test.ts`, `tests/unit/claude-spawn-auth-class.test.ts`, `tests/integration/claude-key-health-route.test.ts`, `tests/e2e/claude-key-alive.test.ts`.
105
+
106
+ ---
107
+
108
+ ## Class-Closure Declaration (display-only mirror)
109
+
110
+ - **`defectClass`**: `unbounded-self-action`
111
+ - **`closure`**: `guard`
112
+ - **Citation**: `tests/unit/self-action-convergence.test.ts` (controller `claude-key-session-refresh`)
113
+ - **Enforcement**: `ratchet`
114
+ - **How caught**: `decideKeyRefresh` caps a session at 3 attempts, then it leaves the pending list and is reported. Nothing re-adds it within the episode, and a session already moved onto this key is skipped, so the count settles. Dead-key probes back off to a 1-hour ceiling and stop after 24 hours.
115
+
116
+ The separate class this change closes, a server-side child that needs a credential but inherits only the server's own env, is held by `tests/unit/claude-spawn-auth-class.test.ts`.
@@ -0,0 +1,11 @@
1
+ # Pairing check for the two rule books, in plain words
2
+
3
+ Instar 1.x and 2.0 each have a written copy of the rules, and changes to one often never reached the other. This adds the first working part of the requirement Justin asked for.
4
+
5
+ Any pull request that changes the 1.x rule book now has to carry one line: which matching change it pairs with in 2.0, or why it has none. My merge tool checks that the line is there and that the named change really exists and really touches the other book. If not, it refuses and says exactly what to add. Adding the line doesn't cancel an approval.
6
+
7
+ It only checks that a pair exists. Whether the two say the same thing, or whether "no pair needed" is honest, stays with the independent review.
8
+
9
+ Nothing here changes the rule books themselves. Those wordings still need Justin's own approval, and come separately. This also adds a map of how the two books differ today, and corrects one document that wrongly said no rule change could land at all.
10
+
11
+ Other agents are unaffected: the check does nothing outside these two repositories. To undo it, revert this change. No data needs fixing.
@@ -0,0 +1,69 @@
1
+ # Side-Effects Review — constitution pairing check and merge-tool wiring
2
+
3
+ **Version / slug:** `constitution-alignment`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent subagent, appended below`
7
+
8
+ ## Summary of the change
9
+
10
+ Step 1 of `docs/specs/constitution-alignment.md`. Adds `scripts/check-constitution-pairing.mjs`: every PR touching a constitution book must name its counterpart in the other repository, or say why it has none. `scripts/safe-merge.mjs` refuses a registry PR that doesn't. `GreenPrAutoMerger` treats that refusal as waiting on a body edit. Also adds the map of existing differences and corrects `docs/STANDARDS-DIRECTION-GUARD.md`. No constitution text changes here. Tier 2; 5 spec review rounds of a cap of 6; about 6 files and 450 lines, most of it tests.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - safe-merge refusal on a missing or unreal declaration: **add**, invariant. Existence only.
15
+ - `none:` honesty and same-obligation: judgment-candidate, held by the independent review of each change. No code here decides it.
16
+
17
+ ## 1. Over-block
18
+
19
+ A PR touching the registry with no line is refused until one line is added. That includes a typo fix; the requirement says all updates. Clearing it takes one body edit and dismisses no approval. A failed read of a named counterpart refuses a registry PR with state `unknown`. A failed read of the PR's own file list refuses *any* PR on this repository with state `unread`, because whether it touches a book isn't known; its message says to retry and the watcher re-reads in 15 minutes. safe-merge already stops on any failed `gh` read a moment earlier or later, so this adds no new class of outage, only one more read that can hit it.
20
+
21
+ ## 2. Under-block
22
+
23
+ - A dishonest `none:`, or a pair that changes something else in the other book. Not visible to a script. The independent review and the operator's review hold it.
24
+ - A merge not going through safe-merge, and every merge in instar-2. Caught by the daily run, within a day.
25
+ - A PR body edited after merge can mislead the daily read. Accepted.
26
+
27
+ ## 3. Level-of-abstraction fit
28
+
29
+ The merge funnel is the right layer in instar: the base-branch refusal lives at the same point. A GitHub required status check would be stronger but needs the operator's admin action on two repositories, and the daily run backs it up.
30
+
31
+ ## 4. Signal vs authority
32
+
33
+ Compliant, per `docs/signal-vs-authority.md`: the blocking authority covers a closed existence question, in the shape of the Maturation Path plan gate, over inputs no model is needed to read. All judgment of meaning stays with a mind. The refusal is cheap to clear and says exactly how.
34
+
35
+ ## 5. Interactions
36
+
37
+ - Sits immediately after `nonMainBaseRefusal`, before every floor. Base refusal still wins for a stacked PR.
38
+ - `GreenPrAutoMerger`: new branch, no ladder attempt, re-read every 15 minutes, since the fix moves no head. Without it, the default ladder would give up. A body edit therefore takes up to 15 minutes to be seen. An approved registry PR with no line waits on audit only, with no attention item: the author is me, and the reader of that item would be the operator, who can't fix it.
39
+ - Adds two `gh` reads per safe-merge run on `JKHeadley/instar`. A registry PR adds a read of the counterpart. Negligible.
40
+ - `scripts/safe-merge.mjs` now imports a sibling file, the same way it imports its existing siblings.
41
+
42
+ ## 6. External surfaces
43
+
44
+ Instar's own PR process only. `scripts/` ships to the fleet, where this is inert: any repository but the two named no-ops. No user-facing change, no message, no route.
45
+
46
+ ## 7. Multi-machine posture
47
+
48
+ Unified. No local state: GitHub is the only record. The same script behaves identically on every machine.
49
+
50
+ ## 8. Rollback
51
+
52
+ Revert. Removes the refusal and the watcher branch. No data migration. The daily job, added at landing on Echo, is disabled in one edit.
53
+
54
+ ## Evidence
55
+
56
+ - Unit: `tests/unit/check-constitution-pairing.test.ts`. Integration: `tests/integration/safe-merge-constitution-counterpart.test.ts` runs the real script with a fake `gh`, including the refusal path, the unreadable-counterpart path, and a PR touching no book.
57
+ - Live positive control, against real history since #2323: `paired=0 declared-none=0 waiting=0 overdue=0 drift=5 no-pr=0`, naming #2682, #2380, #2194, #2323 and instar-2 #182. All five lack a line, so this proves the no-line class only; fixtures cover the rest. A real TLS failure on an earlier run printed `unknown` and did not read as clean.
58
+
59
+ ## Ladder line
60
+
61
+ This spec has no flag, so its plan says `ladder: not applicable: no flag.` The ladder's coverage test now accepts that form, with a reason, and still refuses a name that matches no entry.
62
+
63
+ ## Second-pass review
64
+
65
+ **Reviewer:** independent general-purpose subagent, on claude-opus-5-5
66
+
67
+ Independent subagent, 2026-11-03. Concern raised: a failed first read refused every PR on the repository, labelled as a constitution change. Verified live with a 404. Resolved: a separate `unread` state with its own message, this artifact and the spec corrected, tests added. It also found that a line naming a nonexistent PR made the whole daily run `unknown`; now one row of drift, tested. Everything else it checked held: standalone run from a temp directory, real page shapes, state mapping, `nextEligibleAt`. Recorded after fixing; the concern is resolved by these changes rather than concurred with as first written.
68
+
69
+ **Second-pass re-check of the fix:** Concur with the review.
@@ -0,0 +1,3 @@
1
+ # Recording what switched-off features do, in plain words
2
+
3
+ To judge a switched-off feature, you need a record of what it actually did. Most of them kept none, so the maturation ladder could only say "no data". This adds one line at the point where each of 113 features makes its decision: it fired, it held back, or it failed, with the reason and a few small facts. It changes nothing about what the feature does, and a failure to record can never break the feature. It never records message text, prompts or credentials. It's off on the fleet for now, like the ladder itself. Two features can't record this way, because they don't run inside the server, and they stay marked as needing it.
@@ -0,0 +1,66 @@
1
+ # Side-Effects Review — Evidence recording in switched-off features
2
+
3
+ **Version / slug:** `feature-evidence-recording`
4
+ **Date:** `2026-11-03`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `independent subagent, appended below`
7
+
8
+ ## Summary of the change
9
+
10
+ Adds `featureEvidence.record` (and `recordAtMostEvery` for per-message paths) at the decision points of 113 features across 85 files, and marks them measured in the registry. Spec: `docs/specs/feature-maturation-ladder.md` §4 and §13. Tier 2 by spread; each call is additive and cannot change behaviour.
11
+
12
+ ## Decision-point inventory
13
+
14
+ No decision point is added or changed. Each call observes a decision that already happened.
15
+
16
+ ---
17
+
18
+ ## 1. Over-block
19
+
20
+ No block/allow surface — over-block not applicable.
21
+
22
+ ## 2. Under-block
23
+
24
+ No block/allow surface. Recording misses what a feature cannot see about itself: a wrong decision reads like a right one until graded. Agents flagged double replies, wrongly refused holders and spurious reaps as undetectable from inside; the review's grading covers those.
25
+
26
+ ## 3. Level-of-abstraction fit
27
+
28
+ One thin call at each feature's decision point, through one log. Hook scripts and CI scripts cannot call it and are listed as not covered.
29
+
30
+ ## 4. Signal vs authority compliance
31
+
32
+ Signals only; no call's result is read. Reference: `docs/signal-vs-authority.md`.
33
+
34
+ ## 5. Interactions
35
+
36
+ The call appends synchronously, so it stays off per-tick paths; per-message paths use `recordAtMostEvery`. `catch` blocks that gained a recording call stay non-throwing. The log is wired only when the ladder is on, so on the fleet every call is a no-op, and rows from before the log is wired at boot are lost. A source-order test on `/messages/relay-agent` used a 30 KB window that the added lines outgrew; widened to 40 KB.
37
+
38
+ ## 6. External surfaces
39
+
40
+ None. Rows stay on the machine; only numbers leave. `context` holds reason codes, counts and non-secret ids, and text passes `scrubForStore`.
41
+
42
+ ## 7. Multi-machine posture
43
+
44
+ Per-machine facts read through each machine's route and the board, as the spec states.
45
+
46
+ ## 8. Rollback cost
47
+
48
+ Revert, or set `maturation.ladder.enabled` false, which makes every call a no-op.
49
+
50
+ ## Evidence
51
+
52
+ `tsc` clean; unit tests of each changed module; `tests/unit/FeatureEvidenceLog.test.ts`; the full run is the merge gate.
53
+
54
+ ## Second-pass review
55
+
56
+ **Reviewer:** independent general-purpose subagent, on claude-opus-5-5
57
+
58
+ Independent subagent, first read: "Concern raised". `allPeersPresumedGone()` in a record's arguments could throw on a corrupt registry just before the lease self-suspend, so the self-fence would be skipped; three per-message or per-request paths recorded without the limiter; one `.message.slice` could throw on a non-Error. All fixed: those facts came out of the lease context, the three paths use `recordAtMostEvery`, and the error read is guarded. A wider grep of added arguments found no other call that can throw on a load-bearing path. It found no message text or credentials in the sampled context, and every feature id in the registry. It sampled by risk, not all 85 files. Concur after fixes.
59
+
60
+ ## Class-Closure Declaration
61
+
62
+ `unbounded-self-action`: closure `n/a`. These calls observe decisions other code already made; none triggers an action or a retry. Row volume is bounded by rotation and, on per-message paths, by `recordAtMostEvery`.
63
+
64
+ ## Stage-B certified set
65
+
66
+ `src/monitoring/DegradationReporter.ts` sits in the certified Codex delivery closure and gained a recording call, so the evidence log and its rotation helper entered the closure. Both are listed as excluded, with reasons: write-only, never throwing, and off the delivery path. The certified fingerprint is unchanged.
@@ -0,0 +1,77 @@
1
+ # Side-Effects Review — feedback reroute admission parity
2
+
3
+ **Version / slug:** `feedback-reroute-admission-parity`
4
+ **Date:** 2026-11-04
5
+ **Author:** Echo
6
+ **Second-pass reviewer:** independent reroute-lifetime reviewer
7
+
8
+ ## Summary of the change
9
+
10
+ The feedback executor asks `SessionManager.confinedRerouteCapacity()` before claiming a ranked item. Its canary and worker sessions are not scheduler-proven, but the precheck counted a slot reserved for scheduled jobs. At five of six rerouted sessions, a live tick claimed a priority-95 retry and prepared a workspace; the canary was then refused at its actual `5/5` limit. `src/core/SessionManager.ts` now applies the same non-scheduler global cap and shared reroute admission cap at the precheck and spawn gate. Two unit test files cover both sides of the reservation. No new slot is granted.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - `confinedRerouteCapacity()` — modified — returns saturation before the feedback executor claims work.
15
+ - `evaluateRerouteGate()` — modified to share the cap helper; its existing spawn authority and scheduled-job exception remain.
16
+ - Feedback executor ranked selection and independent review — passed through without change.
17
+
18
+ ## 1. Over-block
19
+
20
+ At five of six rerouted sessions, a feedback worker now waits even if the sixth slot is idle. That is intended: the sixth slot is reserved for a scheduler-proven job, and the feedback worker's canary would otherwise be refused. A one-slot host retains its full single slot, so it is not blocked by a reservation it cannot spare.
21
+
22
+ ## 2. Under-block
23
+
24
+ The precheck is a snapshot. Another session can take the last available place before the canary starts; the spawn gate still refuses it. Memory pressure can also change between the two checks. This patch does not add a reservation or a worker queue and cannot guarantee an immediate start.
25
+
26
+ ## 3. Level-of-abstraction fit
27
+
28
+ The precheck is an early resource-capacity signal for the executor, while the spawn gate remains the final authority. Both use the same `SessionManager` counters and cap helper. A separate executor-side copy of the limits would drift again.
29
+
30
+ ## 4. Signal vs authority compliance
31
+
32
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
33
+
34
+ This is a deterministic resource safety invariant: the non-scheduler worker cannot spend the scheduler's reserved slot. The early check feeds the executor's admission decision; the existing spawn gate continues to enforce the hard limit. No judgment about a report's meaning, priority, or user intent is added.
35
+
36
+ ## 4b. Judgment-point check
37
+
38
+ No new static heuristic at a competing-signals decision point. The available slot count and scheduler provenance are enumerable resource facts defined by the approved confined-spawn spec. Triage ranking remains the model-governed decision point.
39
+
40
+ ## 5. Interactions
41
+
42
+ - **Shadowing:** the precheck runs before the canary and prevents a known futile claim; the canary still runs when the precheck says available.
43
+ - **Double-fire:** no new action fires; both checks read the same session state.
44
+ - **Races:** a concurrent spawn can still take the slot between checks; the spawn gate refuses safely.
45
+ - **Feedback loops:** repeated capacity ticks can stay idle until a slot frees. No retry budget or ranking changes.
46
+
47
+ ## 6. External surfaces
48
+
49
+ The executor may claim fewer feedback items during capacity pressure and records `admission:reroute-capacity` instead of claiming then stopping at canary. No API shape, secret handling, Telegram delivery, or durable schema changes. A deployed agent receives the code through the ordinary Instar update path. The fix queue continues to grow while all worker slots are occupied.
50
+
51
+ ## 7. Multi-machine behavior
52
+
53
+ **Machine-local by design:** session slots and memory pressure are facts about the machine that would run the canary; each host must read its own counters. The drain owner still controls the single executor writer. This change emits no new user-facing notice, stores no new state, and generates no URL.
54
+
55
+ ## 8. Rollback cost
56
+
57
+ Revert this code change and ship a patch. No migration or state cleanup is needed. During rollback, the old false admission can recur under the reserved-slot boundary; the spawn gate still refuses the unsafe start.
58
+
59
+ ## Conclusion
60
+
61
+ The change aligns the early feedback admission with the final spawn guard and preserves the scheduler reservation. Build, full unit suite, focused real-manager tests, and exact-head three-tier verification at `39400fb38` passed. The live receipt after deployment remains required. The original commit lacked a decision-audit record; this review and a new gated commit will repair that evidence gap before merge.
62
+
63
+ ## Second-pass review
64
+
65
+ **Reviewer:** independent reroute-lifetime reviewer
66
+ **Independent read of the artifact:** concur. The reviewer checked the 1-slot and 2-slot boundaries, the scheduler exception, the global overflow test, and the residual race. The existing spawn gate remains authoritative. The reviewer noted that the older precheck already returned `saturated` at the global max before checking mode; this patch preserves that order and aligns it with the final global gate.
67
+
68
+ ## Evidence pointers
69
+
70
+ - Approved spec: `docs/specs/confined-spawn-subscription-reroute.md`.
71
+ - Focused real-SessionManager tests: 65 passed; executor capacity tests: 7 passed.
72
+ - Exact-head local verification at `39400fb38` against main `7840c5ff`: unit 3,121 files / 57,051 tests, integration 675 / 5,507, E2E 499 / 3,746; zero failures.
73
+ - Live pre-fix refusal: feedback canary at `5/5`, with no worker session launched.
74
+
75
+ ## Class-Closure Declaration (display-only mirror)
76
+
77
+ No agent-authored-artifact defect. This changes an early capacity query and a shared cap calculation; it does not add or modify a self-triggered controller's action, cadence, or retry edge. The existing executor tick remains bounded by its previous limits.