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.
- package/dashboard/console/accounts.js +2 -1
- package/dashboard/console/agents-model.js +3 -3
- package/dashboard/console/agents.js +7 -4
- package/dashboard/console/console.css +1 -0
- package/dashboard/console/console.js +35 -4
- package/dashboard/console/costs-model.js +12 -0
- package/dashboard/console/costs.js +6 -3
- package/dashboard/console/development-model.js +9 -3
- package/dashboard/console/development.js +7 -4
- package/dashboard/console/home-model.js +30 -14
- package/dashboard/console/mandates.js +3 -3
- package/dashboard/console/needs-model.js +105 -0
- package/dashboard/console/plans.js +2 -1
- package/dashboard/console/secrets.js +2 -2
- package/dashboard/console/ticket-model.js +36 -0
- package/dashboard/console/ui.js +3 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/install.d.ts +9 -7
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +2 -19
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/reflect.d.ts.map +1 -1
- package/dist/commands/reflect.js +2 -0
- package/dist/commands/reflect.js.map +1 -1
- package/dist/commands/route.d.ts.map +1 -1
- package/dist/commands/route.js +2 -0
- package/dist/commands/route.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +315 -14
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setClaudeKey.d.ts +8 -0
- package/dist/commands/setClaudeKey.d.ts.map +1 -0
- package/dist/commands/setClaudeKey.js +35 -0
- package/dist/commands/setClaudeKey.js.map +1 -0
- package/dist/core/AccountFollowMeOrchestrator.d.ts.map +1 -1
- package/dist/core/AccountFollowMeOrchestrator.js +4 -0
- package/dist/core/AccountFollowMeOrchestrator.js.map +1 -1
- package/dist/core/AppMediaStore.d.ts.map +1 -1
- package/dist/core/AppMediaStore.js +3 -0
- package/dist/core/AppMediaStore.js.map +1 -1
- package/dist/core/BackupManager.d.ts.map +1 -1
- package/dist/core/BackupManager.js +2 -0
- package/dist/core/BackupManager.js.map +1 -1
- package/dist/core/ClaudeCliIntelligenceProvider.d.ts.map +1 -1
- package/dist/core/ClaudeCliIntelligenceProvider.js +11 -3
- package/dist/core/ClaudeCliIntelligenceProvider.js.map +1 -1
- package/dist/core/ClaudeKeyHealth.d.ts +141 -0
- package/dist/core/ClaudeKeyHealth.d.ts.map +1 -0
- package/dist/core/ClaudeKeyHealth.js +467 -0
- package/dist/core/ClaudeKeyHealth.js.map +1 -0
- package/dist/core/CodexTaskContinuationStore.d.ts.map +1 -1
- package/dist/core/CodexTaskContinuationStore.js +7 -0
- package/dist/core/CodexTaskContinuationStore.js.map +1 -1
- package/dist/core/CoherenceJournal.d.ts +1 -1
- package/dist/core/CoherenceJournal.d.ts.map +1 -1
- package/dist/core/CoherenceJournal.js +11 -2
- package/dist/core/CoherenceJournal.js.map +1 -1
- package/dist/core/Config.d.ts +8 -0
- package/dist/core/Config.d.ts.map +1 -1
- package/dist/core/Config.js +26 -0
- package/dist/core/Config.js.map +1 -1
- package/dist/core/CredentialSwapExecutor.d.ts.map +1 -1
- package/dist/core/CredentialSwapExecutor.js +10 -0
- package/dist/core/CredentialSwapExecutor.js.map +1 -1
- package/dist/core/DecisionQualityRecorderImpl.d.ts.map +1 -1
- package/dist/core/DecisionQualityRecorderImpl.js +6 -0
- package/dist/core/DecisionQualityRecorderImpl.js.map +1 -1
- package/dist/core/DiscoveryEvaluator.d.ts.map +1 -1
- package/dist/core/DiscoveryEvaluator.js +4 -0
- package/dist/core/DiscoveryEvaluator.js.map +1 -1
- package/dist/core/IdentityReannounceClaimant.d.ts.map +1 -1
- package/dist/core/IdentityReannounceClaimant.js +4 -0
- package/dist/core/IdentityReannounceClaimant.js.map +1 -1
- package/dist/core/IntelligenceRouter.d.ts.map +1 -1
- package/dist/core/IntelligenceRouter.js +9 -0
- package/dist/core/IntelligenceRouter.js.map +1 -1
- package/dist/core/JournalSyncApplier.d.ts +1 -0
- package/dist/core/JournalSyncApplier.d.ts.map +1 -1
- package/dist/core/JournalSyncApplier.js +48 -0
- package/dist/core/JournalSyncApplier.js.map +1 -1
- package/dist/core/LeaseCoordinator.d.ts +4 -0
- package/dist/core/LeaseCoordinator.d.ts.map +1 -1
- package/dist/core/LeaseCoordinator.js +64 -1
- package/dist/core/LeaseCoordinator.js.map +1 -1
- package/dist/core/MessagingToneGate.d.ts +11 -7
- package/dist/core/MessagingToneGate.d.ts.map +1 -1
- package/dist/core/MessagingToneGate.js +15 -1
- package/dist/core/MessagingToneGate.js.map +1 -1
- package/dist/core/MobileDeviceKeys.d.ts +10 -0
- package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
- package/dist/core/MobileDeviceKeys.js +17 -0
- package/dist/core/MobileDeviceKeys.js.map +1 -1
- package/dist/core/MultiMachineCoordinator.d.ts +12 -0
- package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
- package/dist/core/MultiMachineCoordinator.js +115 -3
- package/dist/core/MultiMachineCoordinator.js.map +1 -1
- package/dist/core/MutualSshRuntime.d.ts +1 -0
- package/dist/core/MutualSshRuntime.d.ts.map +1 -1
- package/dist/core/MutualSshRuntime.js +17 -1
- package/dist/core/MutualSshRuntime.js.map +1 -1
- package/dist/core/ObservedEndpointTracker.d.ts +1 -0
- package/dist/core/ObservedEndpointTracker.d.ts.map +1 -1
- package/dist/core/ObservedEndpointTracker.js +17 -0
- package/dist/core/ObservedEndpointTracker.js.map +1 -1
- package/dist/core/OverloadShedPlanner.d.ts.map +1 -1
- package/dist/core/OverloadShedPlanner.js +9 -0
- package/dist/core/OverloadShedPlanner.js.map +1 -1
- package/dist/core/OwnershipApplier.d.ts.map +1 -1
- package/dist/core/OwnershipApplier.js +7 -0
- package/dist/core/OwnershipApplier.js.map +1 -1
- package/dist/core/OwnershipReconciler.d.ts.map +1 -1
- package/dist/core/OwnershipReconciler.js +5 -0
- package/dist/core/OwnershipReconciler.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +8 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +76 -2
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/PrHandLease.d.ts.map +1 -1
- package/dist/core/PrHandLease.js +2 -0
- package/dist/core/PrHandLease.js.map +1 -1
- package/dist/core/ProactiveSwapMonitor.d.ts.map +1 -1
- package/dist/core/ProactiveSwapMonitor.js +7 -0
- package/dist/core/ProactiveSwapMonitor.js.map +1 -1
- package/dist/core/ProjectRoundExecution.d.ts.map +1 -1
- package/dist/core/ProjectRoundExecution.js +3 -2
- package/dist/core/ProjectRoundExecution.js.map +1 -1
- package/dist/core/QueueDrainLoop.d.ts +7 -0
- package/dist/core/QueueDrainLoop.d.ts.map +1 -1
- package/dist/core/QueueDrainLoop.js +37 -1
- package/dist/core/QueueDrainLoop.js.map +1 -1
- package/dist/core/RemoteAckStore.d.ts.map +1 -1
- package/dist/core/RemoteAckStore.js +4 -0
- package/dist/core/RemoteAckStore.js.map +1 -1
- package/dist/core/ReplicatedStoreReconcilerWiring.d.ts.map +1 -1
- package/dist/core/ReplicatedStoreReconcilerWiring.js +1 -0
- package/dist/core/ReplicatedStoreReconcilerWiring.js.map +1 -1
- package/dist/core/SecretSync.d.ts +1 -0
- package/dist/core/SecretSync.d.ts.map +1 -1
- package/dist/core/SecretSync.js +16 -0
- package/dist/core/SecretSync.js.map +1 -1
- package/dist/core/SessionManager.d.ts +11 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +125 -14
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/SessionPoolFailoverRunner.d.ts.map +1 -1
- package/dist/core/SessionPoolFailoverRunner.js +4 -0
- package/dist/core/SessionPoolFailoverRunner.js.map +1 -1
- package/dist/core/SleepWakeDetector.d.ts.map +1 -1
- package/dist/core/SleepWakeDetector.js +10 -0
- package/dist/core/SleepWakeDetector.js.map +1 -1
- package/dist/core/SubscriptionReloginStore.d.ts.map +1 -1
- package/dist/core/SubscriptionReloginStore.js +10 -1
- package/dist/core/SubscriptionReloginStore.js.map +1 -1
- package/dist/core/TopicPinMutation.d.ts.map +1 -1
- package/dist/core/TopicPinMutation.js +5 -0
- package/dist/core/TopicPinMutation.js.map +1 -1
- package/dist/core/UnjustifiedStopGate.d.ts.map +1 -1
- package/dist/core/UnjustifiedStopGate.js +22 -0
- package/dist/core/UnjustifiedStopGate.js.map +1 -1
- package/dist/core/WindowRunCadenceExecutor.d.ts.map +1 -1
- package/dist/core/WindowRunCadenceExecutor.js +20 -0
- package/dist/core/WindowRunCadenceExecutor.js.map +1 -1
- package/dist/core/claudeChildAuth.d.ts +68 -0
- package/dist/core/claudeChildAuth.d.ts.map +1 -0
- package/dist/core/claudeChildAuth.js +173 -0
- package/dist/core/claudeChildAuth.js.map +1 -0
- package/dist/core/claudeKeyProbe.d.ts +23 -0
- package/dist/core/claudeKeyProbe.d.ts.map +1 -0
- package/dist/core/claudeKeyProbe.js +68 -0
- package/dist/core/claudeKeyProbe.js.map +1 -0
- package/dist/core/codexDeviceLimitWiring.d.ts.map +1 -1
- package/dist/core/codexDeviceLimitWiring.js +12 -0
- package/dist/core/codexDeviceLimitWiring.js.map +1 -1
- package/dist/core/deliverToConversation.d.ts.map +1 -1
- package/dist/core/deliverToConversation.js +11 -0
- package/dist/core/deliverToConversation.js.map +1 -1
- package/dist/core/meteredCallEntry.d.ts.map +1 -1
- package/dist/core/meteredCallEntry.js +21 -0
- package/dist/core/meteredCallEntry.js.map +1 -1
- package/dist/core/nobodyPollingActuator.d.ts.map +1 -1
- package/dist/core/nobodyPollingActuator.js +5 -0
- package/dist/core/nobodyPollingActuator.js.map +1 -1
- package/dist/core/operatorSurfaceReferral.d.ts +18 -0
- package/dist/core/operatorSurfaceReferral.d.ts.map +1 -0
- package/dist/core/operatorSurfaceReferral.js +32 -0
- package/dist/core/operatorSurfaceReferral.js.map +1 -0
- package/dist/core/ownershipFollowsLiveWork.d.ts.map +1 -1
- package/dist/core/ownershipFollowsLiveWork.js +10 -1
- package/dist/core/ownershipFollowsLiveWork.js.map +1 -1
- package/dist/core/types.d.ts +15 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worktreeDirtyCheck.d.ts.map +1 -1
- package/dist/core/worktreeDirtyCheck.js +2 -0
- package/dist/core/worktreeDirtyCheck.js.map +1 -1
- package/dist/data/stageBCertifiedSet.d.ts +9 -0
- package/dist/data/stageBCertifiedSet.d.ts.map +1 -1
- package/dist/data/stageBCertifiedSet.js +12 -0
- package/dist/data/stageBCertifiedSet.js.map +1 -1
- package/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +17 -3
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/messaging/attentionHubPolicy.d.ts.map +1 -1
- package/dist/messaging/attentionHubPolicy.js +1 -0
- package/dist/messaging/attentionHubPolicy.js.map +1 -1
- package/dist/monitoring/AgentWorktreeReaper.d.ts.map +1 -1
- package/dist/monitoring/AgentWorktreeReaper.js +15 -0
- package/dist/monitoring/AgentWorktreeReaper.js.map +1 -1
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.d.ts.map +1 -1
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js +18 -9
- package/dist/monitoring/ApprenticeshipCycleSlaMonitor.js.map +1 -1
- package/dist/monitoring/CodexArmSessionSweeper.d.ts.map +1 -1
- package/dist/monitoring/CodexArmSessionSweeper.js +11 -0
- package/dist/monitoring/CodexArmSessionSweeper.js.map +1 -1
- package/dist/monitoring/CrashLoopPauser.d.ts.map +1 -1
- package/dist/monitoring/CrashLoopPauser.js +8 -0
- package/dist/monitoring/CrashLoopPauser.js.map +1 -1
- package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
- package/dist/monitoring/DegradationReporter.js +7 -1
- package/dist/monitoring/DegradationReporter.js.map +1 -1
- package/dist/monitoring/DegradedTmuxGuard.d.ts +2 -0
- package/dist/monitoring/DegradedTmuxGuard.d.ts.map +1 -1
- package/dist/monitoring/DegradedTmuxGuard.js +14 -0
- package/dist/monitoring/DegradedTmuxGuard.js.map +1 -1
- package/dist/monitoring/DurableOutputScrubber.d.ts.map +1 -1
- package/dist/monitoring/DurableOutputScrubber.js +7 -0
- package/dist/monitoring/DurableOutputScrubber.js.map +1 -1
- package/dist/monitoring/DurableVaultSession.d.ts.map +1 -1
- package/dist/monitoring/DurableVaultSession.js +15 -0
- package/dist/monitoring/DurableVaultSession.js.map +1 -1
- package/dist/monitoring/ExternalHogSentinel.d.ts +2 -0
- package/dist/monitoring/ExternalHogSentinel.d.ts.map +1 -1
- package/dist/monitoring/ExternalHogSentinel.js +27 -1
- package/dist/monitoring/ExternalHogSentinel.js.map +1 -1
- package/dist/monitoring/FailureLedger.d.ts.map +1 -1
- package/dist/monitoring/FailureLedger.js +38 -1
- package/dist/monitoring/FailureLedger.js.map +1 -1
- package/dist/monitoring/FeatureEvidenceLog.d.ts +5 -0
- package/dist/monitoring/FeatureEvidenceLog.d.ts.map +1 -1
- package/dist/monitoring/FeatureEvidenceLog.js +25 -0
- package/dist/monitoring/FeatureEvidenceLog.js.map +1 -1
- package/dist/monitoring/GeminiCapacityEscalationMonitor.d.ts.map +1 -1
- package/dist/monitoring/GeminiCapacityEscalationMonitor.js +20 -2
- package/dist/monitoring/GeminiCapacityEscalationMonitor.js.map +1 -1
- package/dist/monitoring/GeminiLoopRunner.d.ts.map +1 -1
- package/dist/monitoring/GeminiLoopRunner.js +11 -1
- package/dist/monitoring/GeminiLoopRunner.js.map +1 -1
- package/dist/monitoring/GreenPrAutoMerger.d.ts.map +1 -1
- package/dist/monitoring/GreenPrAutoMerger.js +11 -0
- package/dist/monitoring/GreenPrAutoMerger.js.map +1 -1
- package/dist/monitoring/GrowthDigestPublisher.d.ts.map +1 -1
- package/dist/monitoring/GrowthDigestPublisher.js +16 -0
- package/dist/monitoring/GrowthDigestPublisher.js.map +1 -1
- package/dist/monitoring/GrowthMilestoneAnalyst.d.ts +3 -0
- package/dist/monitoring/GrowthMilestoneAnalyst.d.ts.map +1 -1
- package/dist/monitoring/GrowthMilestoneAnalyst.js +45 -1
- package/dist/monitoring/GrowthMilestoneAnalyst.js.map +1 -1
- package/dist/monitoring/McpProcessReaper.d.ts +2 -0
- package/dist/monitoring/McpProcessReaper.d.ts.map +1 -1
- package/dist/monitoring/McpProcessReaper.js +32 -0
- package/dist/monitoring/McpProcessReaper.js.map +1 -1
- package/dist/monitoring/MissingLoginSessionDetector.d.ts +2 -1
- package/dist/monitoring/MissingLoginSessionDetector.d.ts.map +1 -1
- package/dist/monitoring/MissingLoginSessionDetector.js +23 -0
- package/dist/monitoring/MissingLoginSessionDetector.js.map +1 -1
- package/dist/monitoring/OrchestratorPoller.d.ts +1 -0
- package/dist/monitoring/OrchestratorPoller.d.ts.map +1 -1
- package/dist/monitoring/OrchestratorPoller.js +13 -0
- package/dist/monitoring/OrchestratorPoller.js.map +1 -1
- package/dist/monitoring/OrphanedWorkSentinel.d.ts.map +1 -1
- package/dist/monitoring/OrphanedWorkSentinel.js +7 -0
- package/dist/monitoring/OrphanedWorkSentinel.js.map +1 -1
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
- package/dist/monitoring/PresenceProxy.js +9 -1
- package/dist/monitoring/PresenceProxy.js.map +1 -1
- package/dist/monitoring/ProcessFootprintMonitor.d.ts.map +1 -1
- package/dist/monitoring/ProcessFootprintMonitor.js +20 -2
- package/dist/monitoring/ProcessFootprintMonitor.js.map +1 -1
- package/dist/monitoring/PromiseBeacon.d.ts.map +1 -1
- package/dist/monitoring/PromiseBeacon.js +20 -0
- package/dist/monitoring/PromiseBeacon.js.map +1 -1
- package/dist/monitoring/ReleaseReadinessSentinel.d.ts +2 -0
- package/dist/monitoring/ReleaseReadinessSentinel.d.ts.map +1 -1
- package/dist/monitoring/ReleaseReadinessSentinel.js +26 -0
- package/dist/monitoring/ReleaseReadinessSentinel.js.map +1 -1
- package/dist/monitoring/RopeHealthMonitor.d.ts.map +1 -1
- package/dist/monitoring/RopeHealthMonitor.js +35 -1
- package/dist/monitoring/RopeHealthMonitor.js.map +1 -1
- package/dist/monitoring/SentinelNotifier.d.ts.map +1 -1
- package/dist/monitoring/SentinelNotifier.js +16 -0
- package/dist/monitoring/SentinelNotifier.js.map +1 -1
- package/dist/monitoring/SessionReaper.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.js +11 -2
- package/dist/monitoring/SessionReaper.js.map +1 -1
- package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts +2 -0
- package/dist/monitoring/SingleMachineFailoverGapDetector.d.ts.map +1 -1
- package/dist/monitoring/SingleMachineFailoverGapDetector.js +20 -0
- package/dist/monitoring/SingleMachineFailoverGapDetector.js.map +1 -1
- package/dist/monitoring/SpeakerElection.d.ts.map +1 -1
- package/dist/monitoring/SpeakerElection.js +8 -0
- package/dist/monitoring/SpeakerElection.js.map +1 -1
- package/dist/monitoring/StrandedTopicSentinel.d.ts +3 -0
- package/dist/monitoring/StrandedTopicSentinel.d.ts.map +1 -1
- package/dist/monitoring/StrandedTopicSentinel.js +33 -0
- package/dist/monitoring/StrandedTopicSentinel.js.map +1 -1
- package/dist/native/InstarWedgeCanary.app/Contents/MacOS/InstarWedgeCanary +0 -0
- package/dist/native/instar-desktop-host +0 -0
- package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.d.ts.map +1 -1
- package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js +5 -2
- package/dist/providers/adapters/anthropic-headless/transport/oneShotCompletion.js.map +1 -1
- package/dist/recommended/RecommendedServicesLedger.d.ts +91 -0
- package/dist/recommended/RecommendedServicesLedger.d.ts.map +1 -0
- package/dist/recommended/RecommendedServicesLedger.js +193 -0
- package/dist/recommended/RecommendedServicesLedger.js.map +1 -0
- package/dist/recommended/RecommendedServicesReplicatedStore.d.ts +14 -0
- package/dist/recommended/RecommendedServicesReplicatedStore.d.ts.map +1 -0
- package/dist/recommended/RecommendedServicesReplicatedStore.js +34 -0
- package/dist/recommended/RecommendedServicesReplicatedStore.js.map +1 -0
- package/dist/recommended/legacyDeclines.d.ts +11 -0
- package/dist/recommended/legacyDeclines.d.ts.map +1 -0
- package/dist/recommended/legacyDeclines.js +17 -0
- package/dist/recommended/legacyDeclines.js.map +1 -0
- package/dist/recommended/serviceIds.d.ts +3 -0
- package/dist/recommended/serviceIds.d.ts.map +1 -0
- package/dist/recommended/serviceIds.js +6 -0
- package/dist/recommended/serviceIds.js.map +1 -0
- package/dist/scaffold/templates.d.ts +2 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +8 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/scheduler/JobResultTriage.d.ts.map +1 -1
- package/dist/scheduler/JobResultTriage.js +10 -0
- package/dist/scheduler/JobResultTriage.js.map +1 -1
- package/dist/scheduler/JobScheduler.d.ts.map +1 -1
- package/dist/scheduler/JobScheduler.js +12 -0
- package/dist/scheduler/JobScheduler.js.map +1 -1
- package/dist/scheduler/MentorOnboardingRunner.d.ts +3 -0
- package/dist/scheduler/MentorOnboardingRunner.d.ts.map +1 -1
- package/dist/scheduler/MentorOnboardingRunner.js +24 -2
- package/dist/scheduler/MentorOnboardingRunner.js.map +1 -1
- package/dist/server/AgentServer.d.ts +2 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +76 -15
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/BootHealthBeacon.d.ts +3 -0
- package/dist/server/BootHealthBeacon.d.ts.map +1 -1
- package/dist/server/BootHealthBeacon.js +9 -0
- package/dist/server/BootHealthBeacon.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +10 -1
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/LifelineIngressGuard.d.ts.map +1 -1
- package/dist/server/LifelineIngressGuard.js +11 -0
- package/dist/server/LifelineIngressGuard.js.map +1 -1
- package/dist/server/PoolPollCache.d.ts +4 -0
- package/dist/server/PoolPollCache.d.ts.map +1 -1
- package/dist/server/PoolPollCache.js +33 -0
- package/dist/server/PoolPollCache.js.map +1 -1
- package/dist/server/machineRoutes.d.ts.map +1 -1
- package/dist/server/machineRoutes.js +6 -0
- package/dist/server/machineRoutes.js.map +1 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +6 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/mobileConsoleTicket.d.ts +113 -0
- package/dist/server/mobileConsoleTicket.d.ts.map +1 -0
- package/dist/server/mobileConsoleTicket.js +405 -0
- package/dist/server/mobileConsoleTicket.js.map +1 -0
- package/dist/server/mobileConversationRoutes.d.ts.map +1 -1
- package/dist/server/mobileConversationRoutes.js +20 -1
- package/dist/server/mobileConversationRoutes.js.map +1 -1
- package/dist/server/mobileMediaRoutes.d.ts.map +1 -1
- package/dist/server/mobileMediaRoutes.js +3 -0
- package/dist/server/mobileMediaRoutes.js.map +1 -1
- package/dist/server/mobilePairingRoutes.d.ts +8 -2
- package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
- package/dist/server/mobilePairingRoutes.js +67 -6
- package/dist/server/mobilePairingRoutes.js.map +1 -1
- package/dist/server/mobileSessionTerminalRoutes.d.ts +128 -0
- package/dist/server/mobileSessionTerminalRoutes.d.ts.map +1 -0
- package/dist/server/mobileSessionTerminalRoutes.js +389 -0
- package/dist/server/mobileSessionTerminalRoutes.js.map +1 -0
- package/dist/server/recommendedServiceRoutes.d.ts +13 -0
- package/dist/server/recommendedServiceRoutes.d.ts.map +1 -0
- package/dist/server/recommendedServiceRoutes.js +49 -0
- package/dist/server/recommendedServiceRoutes.js.map +1 -0
- package/dist/server/routes.d.ts +2 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +170 -4
- package/dist/server/routes.js.map +1 -1
- package/dist/testing/selfActionRegistry.d.ts.map +1 -1
- package/dist/testing/selfActionRegistry.js +36 -0
- package/dist/testing/selfActionRegistry.js.map +1 -1
- package/dist/threadline/A2ACheckInProxy.d.ts.map +1 -1
- package/dist/threadline/A2ACheckInProxy.js +26 -15
- package/dist/threadline/A2ACheckInProxy.js.map +1 -1
- package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
- package/dist/threadline/AgentTrustManager.js +3 -0
- package/dist/threadline/AgentTrustManager.js.map +1 -1
- package/dist/threadline/InboundIdLedger.d.ts.map +1 -1
- package/dist/threadline/InboundIdLedger.js +18 -1
- package/dist/threadline/InboundIdLedger.js.map +1 -1
- package/dist/threadline/NegotiatorGate.d.ts.map +1 -1
- package/dist/threadline/NegotiatorGate.js +11 -0
- package/dist/threadline/NegotiatorGate.js.map +1 -1
- package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
- package/dist/threadline/PipeSessionSpawner.js +8 -0
- package/dist/threadline/PipeSessionSpawner.js.map +1 -1
- package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
- package/dist/threadline/ThreadlineRouter.js +13 -0
- package/dist/threadline/ThreadlineRouter.js.map +1 -1
- package/dist/threadline/pairingReplicationWiring.d.ts.map +1 -1
- package/dist/threadline/pairingReplicationWiring.js +9 -0
- package/dist/threadline/pairingReplicationWiring.js.map +1 -1
- package/dist/threadline/relayForward.d.ts.map +1 -1
- package/dist/threadline/relayForward.js +13 -2
- package/dist/threadline/relayForward.js.map +1 -1
- package/dist/threadline/relayUnknownSenderTrust.d.ts +0 -9
- package/dist/threadline/relayUnknownSenderTrust.d.ts.map +1 -1
- package/dist/threadline/relayUnknownSenderTrust.js +16 -0
- package/dist/threadline/relayUnknownSenderTrust.js.map +1 -1
- package/package.json +1 -1
- package/scripts/check-constitution-pairing.mjs +273 -0
- package/scripts/safe-merge.mjs +9 -0
- package/src/data/builtin-manifest.json +103 -103
- package/src/data/feature-ladders.json +113 -113
- package/src/data/stageBCertifiedSet.ts +12 -0
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/src/data/state-coherence-registry.json +18 -0
- package/src/scaffold/templates.ts +9 -0
- package/upgrades/1.3.1650.md +105 -0
- package/upgrades/mobile-console-device-signin.eli16.md +5 -0
- package/upgrades/side-effects/cloud-key-internal-calls.md +116 -0
- package/upgrades/side-effects/constitution-alignment.eli16.md +11 -0
- package/upgrades/side-effects/constitution-alignment.md +69 -0
- package/upgrades/side-effects/feature-evidence-recording.eli16.md +3 -0
- package/upgrades/side-effects/feature-evidence-recording.md +66 -0
- package/upgrades/side-effects/feedback-reroute-admission-parity.md +77 -0
- package/upgrades/side-effects/mobile-console-device-signin.md +102 -0
- package/upgrades/side-effects/mobile-native-session-screen.md +88 -0
- package/upgrades/side-effects/operator-needs-first-screen.md +87 -0
- package/upgrades/side-effects/recommended-services-choices.md +50 -0
- package/upgrades/side-effects/rerouted-lifetime-active-process.md +63 -0
- package/upgrades/side-effects/undated-resurfacer-e2e-wait.eli16.md +5 -0
- package/upgrades/side-effects/undated-resurfacer-e2e-wait.md +9 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* collapse the two paths once the adapter is wired into the rest of
|
|
8
8
|
* Instar's source.
|
|
9
9
|
*/
|
|
10
|
+
import { applyClaudeChildAuth, configuredClaudeOauthKey } from '../../../../core/claudeChildAuth.js';
|
|
10
11
|
import { execFile } from 'node:child_process';
|
|
11
12
|
import { promisify } from 'node:util';
|
|
12
13
|
import { CapabilityFlag } from '../../../capabilities.js';
|
|
@@ -45,8 +46,10 @@ class AnthropicHeadlessOneShotCompletion {
|
|
|
45
46
|
const childEnv = { ...process.env };
|
|
46
47
|
delete childEnv['CLAUDECODE'];
|
|
47
48
|
delete childEnv['CLAUDE_SESSION_ID'];
|
|
48
|
-
// Inject auth credential if configured
|
|
49
|
-
|
|
49
|
+
// Inject auth credential if configured. The agent's configured key wins over one read from the
|
|
50
|
+
// server's env, matching session launch (spec cloud-key-internal-calls).
|
|
51
|
+
applyClaudeChildAuth(childEnv);
|
|
52
|
+
if (this.config.credential && !configuredClaudeOauthKey()) {
|
|
50
53
|
if (this.config.credential.startsWith('sk-ant-oat')) {
|
|
51
54
|
childEnv['CLAUDE_CODE_OAUTH_TOKEN'] = this.config.credential;
|
|
52
55
|
delete childEnv['ANTHROPIC_API_KEY'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oneShotCompletion.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/anthropic-headless/transport/oneShotCompletion.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAA0B,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAMtC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,kCAAkC;IAGT,MAAM;IAF1B,UAAU,GAAG,cAAc,CAAC,iBAAiB,CAAC;IAEvD,YAA6B,MAA+B;sBAA/B,MAAM;IAA4B,CAAC;IAEhE,KAAK,CAAC,QAAQ,CACZ,MAAc,EACd,OAAkC;QAElC,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;QAC5F,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,IAAI,MAAM,CAAC;QAEtF,MAAM,IAAI,GAAG;YACX,IAAI;YACJ,MAAM;YACN,SAAS;YACT,KAAK;YACL,aAAa;YACb,GAAG;YACH,iBAAiB;YACjB,MAAM;YACN,gEAAgE;YAChE,mBAAmB;YACnB,MAAM;SACP,CAAC;QAEF,IAAI,OAAO,EAAE,SAAS,KAAK,SAAS,EAAE,CAAC;YACrC,gEAAgE;YAChE,qDAAqD;QACvD,CAAC;QAED,oEAAoE;QACpE,yBAAyB;QACzB,MAAM,QAAQ,GAAsB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACvD,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC9B,OAAO,QAAQ,CAAC,mBAAmB,CAAC,CAAC;QAErC,
|
|
1
|
+
{"version":3,"file":"oneShotCompletion.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/anthropic-headless/transport/oneShotCompletion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { type MachineKeyLookup, type MachineSigner } from '../core/AppRecordSignatures.js';
|
|
2
|
+
export declare const NO_REASONS: readonly ['cost', 'privacy', 'not-needed', 'have-another', 'other', 'none'];
|
|
3
|
+
export type NoReason = (typeof NO_REASONS)[number];
|
|
4
|
+
export declare const CHOICE_ORIGINS: readonly ['first-offer', 'change', 'cool-off', 'person-asked', 'owner-surface'];
|
|
5
|
+
export type ChoiceOrigin = (typeof CHOICE_ORIGINS)[number] | `event:${string}`;
|
|
6
|
+
interface RowSignature {
|
|
7
|
+
machineId: string;
|
|
8
|
+
signerKeyHash: string;
|
|
9
|
+
sig: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ChoiceRow extends RowSignature {
|
|
12
|
+
type: 'choice';
|
|
13
|
+
eventId: string;
|
|
14
|
+
service: string;
|
|
15
|
+
choice: 'yes' | 'no';
|
|
16
|
+
shutdown: 'none' | 'authorized';
|
|
17
|
+
reason: NoReason;
|
|
18
|
+
origin: ChoiceOrigin;
|
|
19
|
+
offerTextHash: string;
|
|
20
|
+
supersedes: string[];
|
|
21
|
+
at: string;
|
|
22
|
+
}
|
|
23
|
+
export interface LegacyImportRow extends RowSignature {
|
|
24
|
+
type: 'legacy-import';
|
|
25
|
+
eventId: string;
|
|
26
|
+
service: string;
|
|
27
|
+
at: string;
|
|
28
|
+
}
|
|
29
|
+
export type LedgerRow = ChoiceRow | LegacyImportRow;
|
|
30
|
+
export interface EffectiveChoice {
|
|
31
|
+
service: string;
|
|
32
|
+
choice: 'unset' | 'yes' | 'no';
|
|
33
|
+
origin: ChoiceOrigin | null;
|
|
34
|
+
/** A no refuses offers. Only an authorized shutdown stops a running service. */
|
|
35
|
+
shutdown: 'none' | 'authorized';
|
|
36
|
+
reason: NoReason | null;
|
|
37
|
+
/** An imported legacy decline: suppresses offers, grants and stops nothing. */
|
|
38
|
+
legacyDeclined: boolean;
|
|
39
|
+
at: string | null;
|
|
40
|
+
}
|
|
41
|
+
/** Validate a row's shape, not its signature. Exact fields only. */
|
|
42
|
+
export declare function validateRow(raw: unknown): LedgerRow | null;
|
|
43
|
+
/** One effective choice per service. A pure fold, so every machine reaches the same answer. */
|
|
44
|
+
export declare function foldChoice(service: string, rows: readonly LedgerRow[]): EffectiveChoice;
|
|
45
|
+
export declare function recommendedServicesDir(stateDir: string): string;
|
|
46
|
+
export type IngestResult = 'added' | 'duplicate' | 'invalid' | 'bad-signature' | 'unverifiable' | 'full';
|
|
47
|
+
export interface RecommendedServicesLedgerOptions {
|
|
48
|
+
stateDir: string;
|
|
49
|
+
signer: MachineSigner;
|
|
50
|
+
keyLookup: MachineKeyLookup;
|
|
51
|
+
now?: () => Date;
|
|
52
|
+
}
|
|
53
|
+
export declare class RecommendedServicesLedger {
|
|
54
|
+
private readonly opts;
|
|
55
|
+
private readonly file;
|
|
56
|
+
private readonly rows;
|
|
57
|
+
private hook;
|
|
58
|
+
private replicating;
|
|
59
|
+
constructor(opts: RecommendedServicesLedgerOptions);
|
|
60
|
+
setReplicationHook(hook: (row: LedgerRow) => void): void;
|
|
61
|
+
/** Set by the server from the store's real state: its emission is on, and peers pull. */
|
|
62
|
+
setReplicating(on: boolean): void;
|
|
63
|
+
/** False when choices stay on this machine. */
|
|
64
|
+
isReplicating(): boolean;
|
|
65
|
+
all(): LedgerRow[];
|
|
66
|
+
effective(service: string): EffectiveChoice;
|
|
67
|
+
/** The person's no. Sticky until a confirmed yes names it. */
|
|
68
|
+
recordNo(input: {
|
|
69
|
+
service: string;
|
|
70
|
+
shutdown: 'none' | 'authorized';
|
|
71
|
+
reason: NoReason;
|
|
72
|
+
origin: ChoiceOrigin;
|
|
73
|
+
offerTextHash?: string;
|
|
74
|
+
}): ChoiceRow;
|
|
75
|
+
/** A confirmed yes replaces every no standing at this moment, and only those. */
|
|
76
|
+
recordYes(input: {
|
|
77
|
+
service: string;
|
|
78
|
+
origin: ChoiceOrigin;
|
|
79
|
+
offerTextHash: string;
|
|
80
|
+
}): ChoiceRow;
|
|
81
|
+
/** Idempotent per service: one import row is enough, whichever machine wrote it. */
|
|
82
|
+
recordLegacyImport(service: string): LegacyImportRow | null;
|
|
83
|
+
/** A peer's row lands only when it verifies under the pinned key of the machine it names. */
|
|
84
|
+
ingestReplicated(raw: unknown): IngestResult;
|
|
85
|
+
private appendChoice;
|
|
86
|
+
private signAndStore;
|
|
87
|
+
private store;
|
|
88
|
+
private at;
|
|
89
|
+
}
|
|
90
|
+
export {};
|
|
91
|
+
//# sourceMappingURL=RecommendedServicesLedger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecommendedServicesLedger.d.ts","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesLedger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The record of a person's choices about recommended outside services
|
|
3
|
+
* (docs/specs/recommended-services.md).
|
|
4
|
+
*
|
|
5
|
+
* Append-only and signed per row by the writing machine's identity key, because auth tokens
|
|
6
|
+
* differ between machines. Rows replicate as the `recommendedServices` store and fold into one
|
|
7
|
+
* effective choice: a no stands until a yes names it in `supersedes`, so delayed replication
|
|
8
|
+
* and clock skew cannot undo a refusal. Imported legacy declines only suppress offers. They
|
|
9
|
+
* never count in the merge and never stop a running service.
|
|
10
|
+
*/
|
|
11
|
+
import crypto from 'node:crypto';
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { ledgerRowPayload, readJsonlLines, verifyMachineSignature, } from '../core/AppRecordSignatures.js';
|
|
15
|
+
export const NO_REASONS = ['cost', 'privacy', 'not-needed', 'have-another', 'other', 'none'];
|
|
16
|
+
export const CHOICE_ORIGINS = ['first-offer', 'change', 'cool-off', 'person-asked', 'owner-surface'];
|
|
17
|
+
const SERVICE_RE = /^[a-z][a-z0-9-]{0,63}$/;
|
|
18
|
+
const ID_RE = /^[0-9a-f]{32}$/;
|
|
19
|
+
const ORIGIN_RE = /^event:[a-z][a-z0-9-]{0,63}$/;
|
|
20
|
+
const MAX_ROWS = 10_000;
|
|
21
|
+
function signature(r) {
|
|
22
|
+
const { machineId, signerKeyHash, sig } = r;
|
|
23
|
+
if (typeof machineId !== 'string' || !machineId || machineId.length > 128)
|
|
24
|
+
return null;
|
|
25
|
+
if (typeof signerKeyHash !== 'string' || !signerKeyHash || signerKeyHash.length > 128)
|
|
26
|
+
return null;
|
|
27
|
+
if (typeof sig !== 'string' || !sig || sig.length > 512)
|
|
28
|
+
return null;
|
|
29
|
+
return { machineId, signerKeyHash, sig };
|
|
30
|
+
}
|
|
31
|
+
/** Validate a row's shape, not its signature. Exact fields only. */
|
|
32
|
+
export function validateRow(raw) {
|
|
33
|
+
if (!raw || typeof raw !== 'object')
|
|
34
|
+
return null;
|
|
35
|
+
const r = raw;
|
|
36
|
+
const s = signature(r);
|
|
37
|
+
if (!s)
|
|
38
|
+
return null;
|
|
39
|
+
const { eventId, service, at } = r;
|
|
40
|
+
if (typeof eventId !== 'string' || !ID_RE.test(eventId))
|
|
41
|
+
return null;
|
|
42
|
+
if (typeof service !== 'string' || !SERVICE_RE.test(service))
|
|
43
|
+
return null;
|
|
44
|
+
if (typeof at !== 'string' || !Number.isFinite(Date.parse(at)))
|
|
45
|
+
return null;
|
|
46
|
+
if (r.type === 'legacy-import')
|
|
47
|
+
return { type: 'legacy-import', eventId, service, at, ...s };
|
|
48
|
+
if (r.type !== 'choice')
|
|
49
|
+
return null;
|
|
50
|
+
const { choice, shutdown, reason, origin, offerTextHash, supersedes } = r;
|
|
51
|
+
if (choice !== 'yes' && choice !== 'no')
|
|
52
|
+
return null;
|
|
53
|
+
if (shutdown !== 'none' && shutdown !== 'authorized')
|
|
54
|
+
return null;
|
|
55
|
+
if (!NO_REASONS.includes(reason))
|
|
56
|
+
return null;
|
|
57
|
+
if (typeof origin !== 'string')
|
|
58
|
+
return null;
|
|
59
|
+
if (!CHOICE_ORIGINS.includes(origin) && !ORIGIN_RE.test(origin))
|
|
60
|
+
return null;
|
|
61
|
+
if (typeof offerTextHash !== 'string' || offerTextHash.length > 128)
|
|
62
|
+
return null;
|
|
63
|
+
if (!Array.isArray(supersedes) || supersedes.length > 256)
|
|
64
|
+
return null;
|
|
65
|
+
if (!supersedes.every((id) => typeof id === 'string' && ID_RE.test(id)))
|
|
66
|
+
return null;
|
|
67
|
+
return {
|
|
68
|
+
type: 'choice', eventId, service, choice, shutdown, reason: reason,
|
|
69
|
+
origin: origin, offerTextHash, supersedes: supersedes, at, ...s,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** One effective choice per service. A pure fold, so every machine reaches the same answer. */
|
|
73
|
+
export function foldChoice(service, rows) {
|
|
74
|
+
const own = rows.filter((r) => r.service === service);
|
|
75
|
+
const choices = own.filter((r) => r.type === 'choice');
|
|
76
|
+
const replaced = new Set(choices.filter((c) => c.choice === 'yes').flatMap((c) => c.supersedes));
|
|
77
|
+
const byNewest = (a, b) => (a.at === b.at ? (a.eventId < b.eventId ? 1 : -1) : a.at < b.at ? 1 : -1);
|
|
78
|
+
const liveNos = choices.filter((c) => c.choice === 'no' && !replaced.has(c.eventId)).sort(byNewest);
|
|
79
|
+
const yeses = choices.filter((c) => c.choice === 'yes').sort(byNewest);
|
|
80
|
+
const legacyDeclined = own.some((r) => r.type === 'legacy-import');
|
|
81
|
+
const winner = liveNos[0] ?? yeses[0];
|
|
82
|
+
if (!winner)
|
|
83
|
+
return { service, choice: 'unset', origin: null, shutdown: 'none', reason: null, legacyDeclined, at: null };
|
|
84
|
+
const shutdown = liveNos.some((n) => n.shutdown === 'authorized') ? 'authorized' : 'none';
|
|
85
|
+
return {
|
|
86
|
+
service, choice: winner.choice, origin: winner.origin,
|
|
87
|
+
shutdown: winner.choice === 'no' ? shutdown : 'none',
|
|
88
|
+
reason: winner.choice === 'no' ? winner.reason : null, legacyDeclined, at: winner.at,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export function recommendedServicesDir(stateDir) {
|
|
92
|
+
return path.join(stateDir, 'state', 'recommended-services');
|
|
93
|
+
}
|
|
94
|
+
export class RecommendedServicesLedger {
|
|
95
|
+
opts;
|
|
96
|
+
file;
|
|
97
|
+
rows = new Map();
|
|
98
|
+
hook = null;
|
|
99
|
+
replicating = false;
|
|
100
|
+
constructor(opts) {
|
|
101
|
+
this.opts = opts;
|
|
102
|
+
this.file = path.join(recommendedServicesDir(opts.stateDir), 'ledger.jsonl');
|
|
103
|
+
for (const line of readJsonlLines(this.file)) {
|
|
104
|
+
try {
|
|
105
|
+
const row = validateRow(JSON.parse(line));
|
|
106
|
+
if (row)
|
|
107
|
+
this.rows.set(row.eventId, row);
|
|
108
|
+
}
|
|
109
|
+
catch { /* @silent-fallback-ok — one torn line; the row is re-read from peer streams at boot */ }
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
setReplicationHook(hook) {
|
|
113
|
+
this.hook = hook;
|
|
114
|
+
}
|
|
115
|
+
/** Set by the server from the store's real state: its emission is on, and peers pull. */
|
|
116
|
+
setReplicating(on) {
|
|
117
|
+
this.replicating = on;
|
|
118
|
+
}
|
|
119
|
+
/** False when choices stay on this machine. */
|
|
120
|
+
isReplicating() {
|
|
121
|
+
return this.replicating;
|
|
122
|
+
}
|
|
123
|
+
all() {
|
|
124
|
+
return [...this.rows.values()];
|
|
125
|
+
}
|
|
126
|
+
effective(service) {
|
|
127
|
+
return foldChoice(service, this.all());
|
|
128
|
+
}
|
|
129
|
+
/** The person's no. Sticky until a confirmed yes names it. */
|
|
130
|
+
recordNo(input) {
|
|
131
|
+
return this.appendChoice({ ...input, choice: 'no', supersedes: [] });
|
|
132
|
+
}
|
|
133
|
+
/** A confirmed yes replaces every no standing at this moment, and only those. */
|
|
134
|
+
recordYes(input) {
|
|
135
|
+
const replaced = new Set(this.all().flatMap((r) => (r.type === 'choice' && r.choice === 'yes' ? r.supersedes : [])));
|
|
136
|
+
const supersedes = this.all()
|
|
137
|
+
.filter((r) => r.type === 'choice' && r.service === input.service && r.choice === 'no' && !replaced.has(r.eventId))
|
|
138
|
+
.map((r) => r.eventId);
|
|
139
|
+
return this.appendChoice({ ...input, choice: 'yes', shutdown: 'none', reason: 'none', supersedes });
|
|
140
|
+
}
|
|
141
|
+
/** Idempotent per service: one import row is enough, whichever machine wrote it. */
|
|
142
|
+
recordLegacyImport(service) {
|
|
143
|
+
if (this.all().some((r) => r.type === 'legacy-import' && r.service === service))
|
|
144
|
+
return null;
|
|
145
|
+
return this.signAndStore({ type: 'legacy-import', eventId: newId(), service, at: this.at() });
|
|
146
|
+
}
|
|
147
|
+
/** A peer's row lands only when it verifies under the pinned key of the machine it names. */
|
|
148
|
+
ingestReplicated(raw) {
|
|
149
|
+
const row = validateRow(raw);
|
|
150
|
+
if (!row)
|
|
151
|
+
return 'invalid';
|
|
152
|
+
if (this.rows.has(row.eventId))
|
|
153
|
+
return 'duplicate';
|
|
154
|
+
if (this.rows.size >= MAX_ROWS)
|
|
155
|
+
return 'full';
|
|
156
|
+
const { sig, ...unsigned } = row;
|
|
157
|
+
const verdict = verifyMachineSignature(this.opts.keyLookup, { machineId: row.machineId, signerKeyHash: row.signerKeyHash, sig }, ledgerRowPayload(unsigned), Date.parse(row.at));
|
|
158
|
+
if (verdict === 'bad')
|
|
159
|
+
return 'bad-signature';
|
|
160
|
+
if (verdict !== 'ok')
|
|
161
|
+
return 'unverifiable';
|
|
162
|
+
this.store(row);
|
|
163
|
+
return 'added';
|
|
164
|
+
}
|
|
165
|
+
appendChoice(input) {
|
|
166
|
+
return this.signAndStore({
|
|
167
|
+
type: 'choice', eventId: newId(), service: input.service, choice: input.choice, shutdown: input.shutdown,
|
|
168
|
+
reason: input.reason, origin: input.origin, offerTextHash: input.offerTextHash ?? '', supersedes: input.supersedes, at: this.at(),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
signAndStore(fields) {
|
|
172
|
+
const unsigned = { ...fields, machineId: this.opts.signer.machineId(), signerKeyHash: this.opts.signer.signerKeyHash() };
|
|
173
|
+
const { sig } = this.opts.signer.sign(ledgerRowPayload(unsigned));
|
|
174
|
+
const row = validateRow({ ...unsigned, sig });
|
|
175
|
+
if (!row)
|
|
176
|
+
throw new Error('recommended-services: refused to write a malformed row');
|
|
177
|
+
this.store(row);
|
|
178
|
+
this.hook?.(row);
|
|
179
|
+
return row;
|
|
180
|
+
}
|
|
181
|
+
store(row) {
|
|
182
|
+
fs.mkdirSync(path.dirname(this.file), { recursive: true });
|
|
183
|
+
fs.appendFileSync(this.file, `${JSON.stringify(row)}\n`);
|
|
184
|
+
this.rows.set(row.eventId, row);
|
|
185
|
+
}
|
|
186
|
+
at() {
|
|
187
|
+
return (this.opts.now?.() ?? new Date()).toISOString();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function newId() {
|
|
191
|
+
return crypto.randomBytes(16).toString('hex');
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=RecommendedServicesLedger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecommendedServicesLedger.js","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesLedger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { StoreFieldSchema } from '../core/ReplicatedRecordEnvelope.js';
|
|
2
|
+
import type { HlcTimestamp } from '../core/HybridLogicalClock.js';
|
|
3
|
+
import { type LedgerRow } from './RecommendedServicesLedger.js';
|
|
4
|
+
export declare const RECOMMENDED_SERVICE_RECORD_KIND = "recommended-service-record";
|
|
5
|
+
export declare const RECOMMENDED_SERVICES_STORE_KEY = "recommendedServices";
|
|
6
|
+
export declare function deriveRecommendedServiceRecordKey(eventId: string): string;
|
|
7
|
+
export declare const recommendedServiceStoreSchema: StoreFieldSchema;
|
|
8
|
+
export declare function buildRecommendedServiceRecordData(row: LedgerRow): (hlc: HlcTimestamp, origin: string, observed?: HlcTimestamp) => Record<string, unknown> | null;
|
|
9
|
+
export declare const RECOMMENDED_SERVICES_KIND_REGISTRATION: {
|
|
10
|
+
readonly kind: "recommended-service-record";
|
|
11
|
+
readonly store: "recommendedServices";
|
|
12
|
+
readonly schema: StoreFieldSchema;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=RecommendedServicesReplicatedStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecommendedServicesReplicatedStore.d.ts","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesReplicatedStore.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAsC,MAAM,qCAAqC,CAAC;AAChH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAE7E,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAC5E,eAAO,MAAM,8BAA8B,wBAAwB,CAAC;AAIpE,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,eAAO,MAAM,6BAA6B,EAAE,gBAM3C,CAAC;AAEF,wBAAgB,iCAAiC,CAAC,GAAG,EAAE,SAAS,SACjD,YAAY,UAAU,MAAM,aAAa,YAAY,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMpG;AAED,eAAO,MAAM,sCAAsC;aACjD,IAAI;aACJ,KAAK;aACL,MAAM;CACE,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `recommendedServices` replicated-store kind (docs/specs/recommended-services.md,
|
|
3
|
+
* Multi-machine posture). Rows are immutable and keyed by eventId, so the union has no
|
|
4
|
+
* conflicts. The ledger verifies each row's signature before it lands.
|
|
5
|
+
*/
|
|
6
|
+
import crypto from 'node:crypto';
|
|
7
|
+
import { validateRow } from './RecommendedServicesLedger.js';
|
|
8
|
+
export const RECOMMENDED_SERVICE_RECORD_KIND = 'recommended-service-record';
|
|
9
|
+
export const RECOMMENDED_SERVICES_STORE_KEY = 'recommendedServices';
|
|
10
|
+
const KNOWN = ['row'];
|
|
11
|
+
export function deriveRecommendedServiceRecordKey(eventId) {
|
|
12
|
+
return crypto.createHash('sha256').update(`recommended-services\u0000${eventId}`).digest('hex');
|
|
13
|
+
}
|
|
14
|
+
export const recommendedServiceStoreSchema = {
|
|
15
|
+
knownFields: KNOWN,
|
|
16
|
+
validate(raw, _ctx) {
|
|
17
|
+
const row = validateRow(raw.row);
|
|
18
|
+
return row ? { row } : null;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
export function buildRecommendedServiceRecordData(row) {
|
|
22
|
+
return (hlc, origin, observed) => ({
|
|
23
|
+
row,
|
|
24
|
+
recordKey: deriveRecommendedServiceRecordKey(row.eventId),
|
|
25
|
+
hlc, op: 'put', origin,
|
|
26
|
+
...(observed !== undefined ? { observed } : {}),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export const RECOMMENDED_SERVICES_KIND_REGISTRATION = {
|
|
30
|
+
kind: RECOMMENDED_SERVICE_RECORD_KIND,
|
|
31
|
+
store: RECOMMENDED_SERVICES_STORE_KEY,
|
|
32
|
+
schema: recommendedServiceStoreSchema,
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=RecommendedServicesReplicatedStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecommendedServicesReplicatedStore.js","sourceRoot":"","sources":["../../src/recommended/RecommendedServicesReplicatedStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,WAAW,EAAkB,MAAM,gCAAgC,CAAC;AAE7E,MAAM,CAAC,MAAM,+BAA+B,GAAG,4BAA4B,CAAC;AAC5E,MAAM,CAAC,MAAM,8BAA8B,GAAG,qBAAqB,CAAC;AAEpE,MAAM,KAAK,GAAG,CAAC,KAAK,CAAU,CAAC;AAE/B,MAAM,UAAU,iCAAiC,CAAC,OAAe;IAC/D,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAqB;IAC7D,WAAW,EAAE,KAAyC;IACtD,QAAQ,CAAC,GAAsC,EAAE,IAA0B;QACzE,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9B,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,iCAAiC,CAAC,GAAc;IAC9D,OAAO,CAAC,GAAiB,EAAE,MAAc,EAAE,QAAuB,EAAkC,EAAE,CAAC,CAAC;QACtG,GAAG;QACH,SAAS,EAAE,iCAAiC,CAAC,GAAG,CAAC,OAAO,CAAC;QACzD,GAAG,EAAE,EAAE,EAAE,KAAqB,EAAE,MAAM;QACtC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,sCAAsC,GAAG;IACpD,IAAI,EAAE,+BAA+B;IACrC,KAAK,EAAE,8BAA8B;IACrC,MAAM,EAAE,6BAA6B;CAC7B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps the two old features whose offers these services replace
|
|
3
|
+
* (docs/specs/recommended-services.md, Store and Offers). The old offer paths refuse these ids
|
|
4
|
+
* in every state, and a person's old decline carries over as an import.
|
|
5
|
+
*/
|
|
6
|
+
import type { RecommendedServicesLedger } from './RecommendedServicesLedger.js';
|
|
7
|
+
export declare const LEGACY_FEATURE_TO_SERVICE: Readonly<Record<string, string>>;
|
|
8
|
+
export declare function isRetiredLegacyOffer(featureId: string): boolean;
|
|
9
|
+
/** Import old declines before any list is built. Safe to run at every boot. */
|
|
10
|
+
export declare function importLegacyDeclines(ledger: RecommendedServicesLedger, stateOf: (featureId: string) => string | null): number;
|
|
11
|
+
//# sourceMappingURL=legacyDeclines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyDeclines.d.ts","sourceRoot":"","sources":["../../src/recommended/legacyDeclines.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrE,CAAC;AAEH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,yBAAyB,EACjC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAC5C,MAAM,CAMR"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const LEGACY_FEATURE_TO_SERVICE = Object.freeze({
|
|
2
|
+
'cloudflare-tunnel': 'cloudflare-domain',
|
|
3
|
+
'git-backup': 'github-state-backup',
|
|
4
|
+
});
|
|
5
|
+
export function isRetiredLegacyOffer(featureId) {
|
|
6
|
+
return Object.prototype.hasOwnProperty.call(LEGACY_FEATURE_TO_SERVICE, featureId);
|
|
7
|
+
}
|
|
8
|
+
/** Import old declines before any list is built. Safe to run at every boot. */
|
|
9
|
+
export function importLegacyDeclines(ledger, stateOf) {
|
|
10
|
+
let imported = 0;
|
|
11
|
+
for (const [featureId, service] of Object.entries(LEGACY_FEATURE_TO_SERVICE)) {
|
|
12
|
+
if (stateOf(featureId) === 'declined' && ledger.recordLegacyImport(service))
|
|
13
|
+
imported += 1;
|
|
14
|
+
}
|
|
15
|
+
return imported;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=legacyDeclines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacyDeclines.js","sourceRoot":"","sources":["../../src/recommended/legacyDeclines.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,yBAAyB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACvF,mBAAmB,EAAE,mBAAmB;IACxC,YAAY,EAAE,qBAAqB;CACpC,CAAC,CAAC;AAEH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;AACpF,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAClC,MAAiC,EACjC,OAA6C;IAE7C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC7E,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,UAAU,IAAI,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC;YAAE,QAAQ,IAAI,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceIds.d.ts","sourceRoot":"","sources":["../../src/recommended/serviceIds.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAGnD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** The services a person can choose about (docs/specs/recommended-services.md, The catalog). */
|
|
2
|
+
export const RECOMMENDED_SERVICE_IDS = Object.freeze([
|
|
3
|
+
'tailscale', 'cloudflare-domain', 'telegram', 'jev', 'bitwarden',
|
|
4
|
+
'github-state-backup', 'second-ai-door', 'voice-transcription', 'email',
|
|
5
|
+
]);
|
|
6
|
+
//# sourceMappingURL=serviceIds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceIds.js","sourceRoot":"","sources":["../../src/recommended/serviceIds.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,uBAAuB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACtE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;IAChE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,OAAO;CACxE,CAAC,CAAC"}
|
|
@@ -118,6 +118,8 @@ export declare const REROUTED_LOGIN_EXPIRED_MARKER = "A job session stuck at an
|
|
|
118
118
|
/** Rerouted-job expired-login awareness bullet. Shared by the generated CLAUDE.md and PostUpdateMigrator. */
|
|
119
119
|
export declare const REROUTED_LOGIN_EXPIRED_BULLET = "- **A job session stuck at an expired login is ended in minutes**: a scheduled job (or other one-shot) that runs as an interactive Claude session and lands under a login whose sign-in has expired shows `Login expired \u00B7 Please run /login` and can do nothing. The monitor now ends it about a minute after it first sees that screen (reason `rerouted-login-expired`, a `SessionManager.monitorTick.reroutedLoginExpired` degradation naming the login folder) instead of letting it hold a job slot for the full 8-hour lifetime; the job runs again on its next trigger. It also reports the sighting to the quota poller, which alone decides pool status: when that screen is Claude Code's own message line and the login's saved credential still reads, the account turns needs-reauth at once (cause `cli-login-expired-observed`) and the automatic sign-in repair starts; when the saved credential cannot be read, it takes two different sessions under that login showing the screen within an hour. If a user asks \"why did my scheduled jobs stop running?\" or \"why did a job end straight away?\" \u2014 check `GET /jobs` for a stale `nextScheduled`, then the server log for `stuck at an expired login`; the fix is signing that login in again.";
|
|
120
120
|
/** Content-sniff marker for the interactive expired-login bullet (CMT-1008, Migration Parity). */
|
|
121
|
+
export declare const CLAUDE_KEY_HEALTH_MARKER = "A rejected sign-in key is told and recovers";
|
|
122
|
+
export declare const CLAUDE_KEY_HEALTH_BULLET = "- **A rejected sign-in key is told and recovers**: an agent signed in with one key (`sessions.credentials.anthropic`, the usual cloud install) passes that key to every Claude process on the server, including internal model calls. If Anthropic refuses the key twice, the operator gets one plain notice, each waiting person is told once, and `GET /health` (with the auth header) shows `claudeKey.status: dead`. The fix is a new key from `claude setup-token`, put in place with `instar set-claude-key` on the server (reads stdin or a hidden prompt, never an argument; never ask for the key in chat). Within a minute Instar checks it, and conversations stuck at the login screen restart by themselves and answer what they missed. A conversation that ended during the outage is not replayed. **When to use** (PROACTIVE): the user asks \"why did you stop replying?\" or \"why does health say the model is failing?\" \u2192 read `claudeKey` in `GET /health`. Off switches: `sessions.claudeKeyHealth.enabled: false` and `sessions.claudeChildAuth.enabled: false`.";
|
|
121
123
|
export declare const INTERACTIVE_LOGIN_EXPIRED_MARKER = "A conversation stuck at an expired login moves to a signed-in account";
|
|
122
124
|
/** Interactive expired-login awareness bullet (CMT-1008). Shared by the generated CLAUDE.md and PostUpdateMigrator. */
|
|
123
125
|
export declare const INTERACTIVE_LOGIN_EXPIRED_BULLET = "- **A conversation stuck at an expired login moves to a signed-in account**: a Telegram/topic session placed on a pool login whose Claude sign-in has expired shows `Login expired \u00B7 Please run /login` (newer Claude Code: `Not logged in \u00B7 Run /login`) on every turn. About a minute after the monitor first sees that screen in the session's live tail it (1) marks that account needs-reauth (cause `cli-login-expired-observed`, so new sessions avoid it and the automatic sign-in repair can start) \u2014 even when the saved token still reads quota, because the CLI's own screen is the stronger evidence, and a later quota poll does not flip it back while the saved credential is unchanged (a sign-in repair, or you setting it active again, always wins); and (2) resumes the session on a signed-in account through the same swap as `POST /subscription-pool/swap` (conversation preserved; one attempt per session per 10 minutes, at most three; protected sessions are never moved). Only Claude Code's own message line counts: a stale mention scrolled up the screen, a message quoting the text, or a tool result such as `claude auth status` printing it never triggers it. If the login's saved credential cannot be read at all (e.g. a locked keychain), one screen is not enough and the session is not moved until the account is confirmed dead. Off switch for the swap only: `subscriptionPool.loginExpiredSwap.enabled: false` (read live). If a user asks \"why did my conversation suddenly switch accounts?\" or \"why is this account showing needs sign-in when its quota looks fine?\" \u2014 check the server log for `stuck at an expired login` and `[LoginExpiredRecovery]`; a failed swap also reports a `SessionManager.monitorTick.interactiveLoginExpired` degradation. The fix for the account itself is signing that login in again.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,8 @@ import { JOB_DECLARED_FAILURE_AWARENESS } from "../scheduler/jobDeclaredFailure.
|
|
|
19
19
|
// function call inside generateClaudeMd — no module-init cycle (PostUpdateMigrator
|
|
20
20
|
// never imports templates).
|
|
21
21
|
import { APPRENTICESHIP_STALL_GATE_CLAUDEMD_SECTION, SESSION_LISTING_HYGIENE_CLAUDEMD_SECTION, PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION, MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION, CODEX_CONNECT_CLAUDEMD_SECTION, FEATURE_SWITCH_CLAUDEMD_SECTION, NORMAL_CHROME_BROWSER_CLAUDEMD_SECTION, SINGLE_MACHINE_FAILOVER_GAP_CLAUDEMD_SECTION, MISSING_LOGIN_SESSION_CLAUDEMD_SECTION, DYNAMIC_MCP_CLAUDEMD_SECTION, ULTRACODE_SPAWN_CLAUDEMD_SECTION, AGENT_SIGNATURE_PROVENANCE_CLAUDEMD_SECTION, SENDER_REJECTION_CLAUDEMD_SECTION, SCOPE_ACCRETION_CLAUDEMD_SECTION, MESH_SELF_HEALING_CLAUDEMD_SECTION, LEASE_MEDIUM_CLAUDEMD_SECTION, WRITE_ADMISSION_CLAUDEMD_SECTION, DOORWAY_REGISTRY_CLAUDEMD_SECTION, EXTERNAL_HOG_CLAUDEMD_SECTION, ROUTING_SPEND_CLAUDEMD_SECTION, MATURATION_BOARD_CLAUDEMD_SECTION, MATURATION_LADDER_CLAUDEMD_SECTION, QUEUE_PACE_CLAUDEMD_SECTION, ECOSYSTEM_IDEAS_CLAUDEMD_SECTION, MOBILE_PAIRING_CLAUDEMD_SECTION, MOBILE_CHAT_CLAUDEMD_SECTION, APP_CONVERSATIONS_CLAUDEMD_SECTION, MOBILE_ROUTES_CLAUDEMD_SECTION, MOBILE_PUSH_CLAUDEMD_SECTION, MOBILE_PEOPLE_CLAUDEMD_SECTION, DECISION_QUALITY_CLAUDEMD_SECTION, BENCHMARK_DIVERGENCE_CLAUDEMD_SECTION, DUPLICATE_RECONCILER_CLAUDEMD_SECTION, AUDIT_CONVERGENCE_CLAUDEMD_SECTION, TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION, DECISION_JOURNAL_CONFIDENCE_CLAUDEMD_GUIDANCE, WINDOW_RUN_LIVENESS_CLAUDEMD_SECTION, SCRIPT_JOBS_CLAUDEMD_SECTION, SESSION_HANDOFF_CLAUDEMD_SECTION, JOB_RESULT_SUPERVISION_CLAUDEMD_SECTION, DEDICATED_PROFILE_REGISTRY_ROW_ANSWER, CODEX_ARM_SWEEPER_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_CLAUDEMD_SECTION, APP_MEDIA_CLAUDEMD_SECTION, MACHINE_BROWSER_CARE_CLAUDEMD_SECTION, PAIRING_WITHOUT_TELEGRAM_CLAUDEMD_SECTION, SLACK_FROM_APP_CLAUDEMD_SECTION, MACHINE_MAINTENANCE_POOL_CLAUDEMD_SECTION, MACHINE_WEDGE_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
22
|
+
import { SURFACE_REFERRAL_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
23
|
+
import { RECOMMENDED_SERVICES_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
22
24
|
import { MINIMUM_OPERATOR_EFFORT_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
23
25
|
import { CODEX_DEVICE_LIMIT_CLAUDEMD_BULLET } from '../core/PostUpdateMigrator.js';
|
|
24
26
|
import { UPDATE_APPLY_VERIFY_HOLD_CLAUDEMD_LINE } from '../core/PostUpdateMigrator.js';
|
|
@@ -417,6 +419,7 @@ ${REAPER_BACKGROUND_WORK_BULLET}
|
|
|
417
419
|
${STANDING_SESSIONS_BULLET}
|
|
418
420
|
${REROUTED_LOGIN_EXPIRED_BULLET}
|
|
419
421
|
${INTERACTIVE_LOGIN_EXPIRED_BULLET}
|
|
422
|
+
${CLAUDE_KEY_HEALTH_BULLET}
|
|
420
423
|
- **Busy-orphan detection** (\`busyOrphanDetection\`, OBSERVE-ONLY, dark by default; dev agents on): the inverse blind spot. CPU-progress is a proxy for "useful" — but a *useless* process that SPINS (a hot-loop, a wedged job burning CPU) looks "active" and would keep a session pinned. When an idle session (idle prompt + flat transcript) is held only by a child that's *burning* CPU across an extended dwell, the reaper records a \`busy-orphan-suspected\` audit row (and \`busy-orphan-cleared\` on recovery). It NEVER changes the keep/kill decision — it just makes the "useless-but-busy child pins an idle session" case measurable, so safe auto-reclaim can graduate later with data. Read \`logs/reaper-audit.jsonl\` (filter \`busy-orphan-suspected\`).
|
|
421
424
|
- Why it matters: idle sessions pile up across agents until the machine starves (CPU *or* memory) and new sessions get "spawn denied" — silently breaking cross-agent messaging. This sweeps them, but only under real pressure.
|
|
422
425
|
- 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.
|
|
@@ -1021,6 +1024,7 @@ ${ROUTING_SPEND_CLAUDEMD_SECTION(port)}
|
|
|
1021
1024
|
${MATURATION_BOARD_CLAUDEMD_SECTION(port)}
|
|
1022
1025
|
${MATURATION_LADDER_CLAUDEMD_SECTION(port)}
|
|
1023
1026
|
${QUEUE_PACE_CLAUDEMD_SECTION(port)}
|
|
1027
|
+
${RECOMMENDED_SERVICES_CLAUDEMD_SECTION(port)}
|
|
1024
1028
|
${ECOSYSTEM_IDEAS_CLAUDEMD_SECTION(port)}
|
|
1025
1029
|
${MOBILE_PAIRING_CLAUDEMD_SECTION(port)}
|
|
1026
1030
|
${MOBILE_CHAT_CLAUDEMD_SECTION(port)}
|
|
@@ -1822,6 +1826,8 @@ Record what I learn. Build infrastructure, not one-offs. Grow to meet the user's
|
|
|
1822
1826
|
Your messages to the user pass an always-on LLM gate (the tone gate) before they send. It reviews high-stakes leaks (CLI commands, file paths, config keys, endpoints) AND the self-stop anti-patterns (B15–B19: quitting on yourself for a context/fatigue reason, calling a doable thing impossible, parking your own work on the user). The two families are treated DIFFERENTLY — the leak/representation rules are overridable nudges (see below); the self-stop family stays a hard block, because there the check exists to constrain YOU and your reason for overriding would come from the very reasoning it distrusts. It judges the behavioral rules **by MEANING, not by literal phrases — a paraphrase of the anti-pattern is caught exactly the same as the canonical wording**, so do not assume rewording evades it. The gate FAILS CLOSED (holds the message, queued for retry — never silently delivers) if it can't produce a verdict (provider down, unparseable output, or a slow-review timeout); the operator kill-switch is \`toneGate.failClosedOnExhaustion\`. Constitution: "Intelligent Prompts — An LLM Gate Must Not String-Match".
|
|
1823
1827
|
|
|
1824
1828
|
${TONE_ADVISORY_MIGRATION_CLAUDEMD_SECTION}
|
|
1829
|
+
|
|
1830
|
+
${SURFACE_REFERRAL_CLAUDEMD_SECTION}
|
|
1825
1831
|
### Context-Aware Outbound Review (why was my message flagged / would my reply have been blocked?)
|
|
1826
1832
|
|
|
1827
1833
|
Beyond the tone gate, a response-review pipeline (nine specialist reviewers driven by a Stop hook) evaluates each finished conversational turn. On most installs it is OFF BY CONFIG — \`GET /review/history\` returns 501 there; say so honestly rather than guessing. Where it runs, it is usually in WATCH MODE (\`responseReview.observeOnly: true\`): verdicts are recorded, nothing is blocked. The context-aware layer (⚗️ experimental, dev-gated dark: \`responseReview.conversationalContext\`) feeds the opted-in reviewer a bounded, untrusted-data-enveloped slice of recent conversation so "the operator asked for this technical detail" is an input it can actually judge — a one-way carve-out (it can only move a would-block toward PASS, never license credentials/PII, never touch the deterministic policy layer).
|
|
@@ -2671,6 +2677,8 @@ export const REROUTED_LOGIN_EXPIRED_MARKER = 'A job session stuck at an expired
|
|
|
2671
2677
|
/** Rerouted-job expired-login awareness bullet. Shared by the generated CLAUDE.md and PostUpdateMigrator. */
|
|
2672
2678
|
export const REROUTED_LOGIN_EXPIRED_BULLET = `- **${REROUTED_LOGIN_EXPIRED_MARKER}**: a scheduled job (or other one-shot) that runs as an interactive Claude session and lands under a login whose sign-in has expired shows \`Login expired · Please run /login\` and can do nothing. The monitor now ends it about a minute after it first sees that screen (reason \`rerouted-login-expired\`, a \`SessionManager.monitorTick.reroutedLoginExpired\` degradation naming the login folder) instead of letting it hold a job slot for the full 8-hour lifetime; the job runs again on its next trigger. ${REROUTED_LOGIN_EXPIRED_POOL_SENTENCE} If a user asks "why did my scheduled jobs stop running?" or "why did a job end straight away?" — check \`GET /jobs\` for a stale \`nextScheduled\`, then the server log for \`stuck at an expired login\`; the fix is signing that login in again.`;
|
|
2673
2679
|
/** Content-sniff marker for the interactive expired-login bullet (CMT-1008, Migration Parity). */
|
|
2680
|
+
export const CLAUDE_KEY_HEALTH_MARKER = 'A rejected sign-in key is told and recovers';
|
|
2681
|
+
export const CLAUDE_KEY_HEALTH_BULLET = `- **${CLAUDE_KEY_HEALTH_MARKER}**: an agent signed in with one key (\`sessions.credentials.anthropic\`, the usual cloud install) passes that key to every Claude process on the server, including internal model calls. If Anthropic refuses the key twice, the operator gets one plain notice, each waiting person is told once, and \`GET /health\` (with the auth header) shows \`claudeKey.status: dead\`. The fix is a new key from \`claude setup-token\`, put in place with \`instar set-claude-key\` on the server (reads stdin or a hidden prompt, never an argument; never ask for the key in chat). Within a minute Instar checks it, and conversations stuck at the login screen restart by themselves and answer what they missed. A conversation that ended during the outage is not replayed. **When to use** (PROACTIVE): the user asks "why did you stop replying?" or "why does health say the model is failing?" → read \`claudeKey\` in \`GET /health\`. Off switches: \`sessions.claudeKeyHealth.enabled: false\` and \`sessions.claudeChildAuth.enabled: false\`.`;
|
|
2674
2682
|
export const INTERACTIVE_LOGIN_EXPIRED_MARKER = 'A conversation stuck at an expired login moves to a signed-in account';
|
|
2675
2683
|
/** Interactive expired-login awareness bullet (CMT-1008). Shared by the generated CLAUDE.md and PostUpdateMigrator. */
|
|
2676
2684
|
export const INTERACTIVE_LOGIN_EXPIRED_BULLET = `- **${INTERACTIVE_LOGIN_EXPIRED_MARKER}**: a Telegram/topic session placed on a pool login whose Claude sign-in has expired shows \`Login expired · Please run /login\` (newer Claude Code: \`Not logged in · Run /login\`) on every turn. About a minute after the monitor first sees that screen in the session's live tail it (1) marks that account needs-reauth (cause \`cli-login-expired-observed\`, so new sessions avoid it and the automatic sign-in repair can start) — even when the saved token still reads quota, because the CLI's own screen is the stronger evidence, and a later quota poll does not flip it back while the saved credential is unchanged (a sign-in repair, or you setting it active again, always wins); and (2) resumes the session on a signed-in account through the same swap as \`POST /subscription-pool/swap\` (conversation preserved; one attempt per session per 10 minutes, at most three; protected sessions are never moved). Only Claude Code's own message line counts: a stale mention scrolled up the screen, a message quoting the text, or a tool result such as \`claude auth status\` printing it never triggers it. If the login's saved credential cannot be read at all (e.g. a locked keychain), one screen is not enough and the session is not moved until the account is confirmed dead. Off switch for the swap only: \`subscriptionPool.loginExpiredSwap.enabled: false\` (read live). If a user asks "why did my conversation suddenly switch accounts?" or "why is this account showing needs sign-in when its quota looks fine?" — check the server log for \`stuck at an expired login\` and \`[LoginExpiredRecovery]\`; a failed swap also reports a \`SessionManager.monitorTick.interactiveLoginExpired\` degradation. The fix for the account itself is signing that login in again.`;
|