instar 0.28.76 → 0.28.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/index.html +486 -0
- package/dist/cli.js +5 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/discovery.d.ts.map +1 -1
- package/dist/commands/discovery.js +2 -2
- package/dist/commands/discovery.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/job.d.ts.map +1 -1
- package/dist/commands/job.js +2 -2
- package/dist/commands/job.js.map +1 -1
- package/dist/commands/ledgerCleanup.d.ts.map +1 -1
- package/dist/commands/ledgerCleanup.js +2 -2
- package/dist/commands/ledgerCleanup.js.map +1 -1
- package/dist/commands/listener.d.ts.map +1 -1
- package/dist/commands/listener.js +7 -12
- package/dist/commands/listener.js.map +1 -1
- package/dist/commands/nuke.d.ts.map +1 -1
- package/dist/commands/nuke.js +11 -21
- package/dist/commands/nuke.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +79 -5
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +11 -15
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/slack-cli.d.ts.map +1 -1
- package/dist/commands/slack-cli.js +5 -8
- package/dist/commands/slack-cli.js.map +1 -1
- package/dist/commands/whatsapp.d.ts.map +1 -1
- package/dist/commands/whatsapp.js +2 -2
- package/dist/commands/whatsapp.js.map +1 -1
- package/dist/commands/worktree.d.ts.map +1 -1
- package/dist/commands/worktree.js +2 -2
- package/dist/commands/worktree.js.map +1 -1
- package/dist/core/AgentConnector.d.ts.map +1 -1
- package/dist/core/AgentConnector.js +9 -10
- package/dist/core/AgentConnector.js.map +1 -1
- package/dist/core/AgentRegistry.d.ts.map +1 -1
- package/dist/core/AgentRegistry.js +3 -4
- package/dist/core/AgentRegistry.js.map +1 -1
- package/dist/core/AutoDispatcher.d.ts.map +1 -1
- package/dist/core/AutoDispatcher.js +2 -2
- package/dist/core/AutoDispatcher.js.map +1 -1
- package/dist/core/AutoUpdater.d.ts.map +1 -1
- package/dist/core/AutoUpdater.js +2 -2
- package/dist/core/AutoUpdater.js.map +1 -1
- package/dist/core/AutonomousEvolution.d.ts.map +1 -1
- package/dist/core/AutonomousEvolution.js +2 -2
- package/dist/core/AutonomousEvolution.js.map +1 -1
- package/dist/core/BackupManager.d.ts.map +1 -1
- package/dist/core/BackupManager.js +2 -2
- package/dist/core/BackupManager.js.map +1 -1
- package/dist/core/BranchManager.d.ts.map +1 -1
- package/dist/core/BranchManager.js +3 -3
- package/dist/core/BranchManager.js.map +1 -1
- package/dist/core/CaffeinateManager.d.ts.map +1 -1
- package/dist/core/CaffeinateManager.js +2 -2
- package/dist/core/CaffeinateManager.js.map +1 -1
- package/dist/core/DeferredDispatchTracker.d.ts.map +1 -1
- package/dist/core/DeferredDispatchTracker.js +2 -2
- package/dist/core/DeferredDispatchTracker.js.map +1 -1
- package/dist/core/DispatchManager.d.ts.map +1 -1
- package/dist/core/DispatchManager.js +3 -4
- package/dist/core/DispatchManager.js.map +1 -1
- package/dist/core/EvolutionManager.d.ts.map +1 -1
- package/dist/core/EvolutionManager.js +2 -2
- package/dist/core/EvolutionManager.js.map +1 -1
- package/dist/core/ExecutionJournal.d.ts.map +1 -1
- package/dist/core/ExecutionJournal.js +2 -2
- package/dist/core/ExecutionJournal.js.map +1 -1
- package/dist/core/FeedbackManager.d.ts.map +1 -1
- package/dist/core/FeedbackManager.js +2 -2
- package/dist/core/FeedbackManager.js.map +1 -1
- package/dist/core/FileClassifier.d.ts.map +1 -1
- package/dist/core/FileClassifier.js +8 -17
- package/dist/core/FileClassifier.js.map +1 -1
- package/dist/core/ForegroundRestartWatcher.d.ts.map +1 -1
- package/dist/core/ForegroundRestartWatcher.js +3 -4
- package/dist/core/ForegroundRestartWatcher.js.map +1 -1
- package/dist/core/GitStateManager.d.ts.map +1 -1
- package/dist/core/GitStateManager.js +3 -12
- package/dist/core/GitStateManager.js.map +1 -1
- package/dist/core/GitSync.d.ts.map +1 -1
- package/dist/core/GitSync.js +6 -6
- package/dist/core/GitSync.js.map +1 -1
- package/dist/core/GlobalInstallCleanup.d.ts.map +1 -1
- package/dist/core/GlobalInstallCleanup.js +3 -4
- package/dist/core/GlobalInstallCleanup.js.map +1 -1
- package/dist/core/GlobalSecretStore.d.ts.map +1 -1
- package/dist/core/GlobalSecretStore.js +3 -4
- package/dist/core/GlobalSecretStore.js.map +1 -1
- package/dist/core/HandoffManager.d.ts.map +1 -1
- package/dist/core/HandoffManager.js +5 -5
- package/dist/core/HandoffManager.js.map +1 -1
- package/dist/core/JargonDetector.d.ts +28 -0
- package/dist/core/JargonDetector.d.ts.map +1 -0
- package/dist/core/JargonDetector.js +59 -0
- package/dist/core/JargonDetector.js.map +1 -0
- package/dist/core/LedgerSessionRegistry.d.ts.map +1 -1
- package/dist/core/LedgerSessionRegistry.js +2 -2
- package/dist/core/LedgerSessionRegistry.js.map +1 -1
- package/dist/core/MachineIdentity.d.ts.map +1 -1
- package/dist/core/MachineIdentity.js +2 -2
- package/dist/core/MachineIdentity.js.map +1 -1
- package/dist/core/MessagingToneGate.d.ts +42 -5
- package/dist/core/MessagingToneGate.d.ts.map +1 -1
- package/dist/core/MessagingToneGate.js +40 -6
- package/dist/core/MessagingToneGate.js.map +1 -1
- package/dist/core/ParallelDevWiring.d.ts.map +1 -1
- package/dist/core/ParallelDevWiring.js +3 -6
- package/dist/core/ParallelDevWiring.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +26 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +249 -46
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ProjectMapper.d.ts.map +1 -1
- package/dist/core/ProjectMapper.js +5 -11
- package/dist/core/ProjectMapper.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +4 -5
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/core/SafeGitExecutor.d.ts +11 -5
- package/dist/core/SafeGitExecutor.d.ts.map +1 -1
- package/dist/core/SafeGitExecutor.js +87 -1
- package/dist/core/SafeGitExecutor.js.map +1 -1
- package/dist/core/ScopeVerifier.d.ts.map +1 -1
- package/dist/core/ScopeVerifier.js +3 -6
- package/dist/core/ScopeVerifier.js.map +1 -1
- package/dist/core/SecretStore.d.ts.map +1 -1
- package/dist/core/SecretStore.js +2 -2
- package/dist/core/SecretStore.js.map +1 -1
- package/dist/core/SharedStateLedger.d.ts.map +1 -1
- package/dist/core/SharedStateLedger.js +2 -2
- package/dist/core/SharedStateLedger.js.map +1 -1
- package/dist/core/SoulManager.d.ts.map +1 -1
- package/dist/core/SoulManager.js +3 -4
- package/dist/core/SoulManager.js.map +1 -1
- package/dist/core/StateManager.d.ts.map +1 -1
- package/dist/core/StateManager.js +4 -6
- package/dist/core/StateManager.js.map +1 -1
- package/dist/core/SyncOrchestrator.d.ts.map +1 -1
- package/dist/core/SyncOrchestrator.js +6 -7
- package/dist/core/SyncOrchestrator.js.map +1 -1
- package/dist/core/UpdateChecker.d.ts.map +1 -1
- package/dist/core/UpdateChecker.js +3 -4
- package/dist/core/UpdateChecker.js.map +1 -1
- package/dist/core/UpgradeGuideProcessor.d.ts.map +1 -1
- package/dist/core/UpgradeGuideProcessor.js +3 -4
- package/dist/core/UpgradeGuideProcessor.js.map +1 -1
- package/dist/core/WorktreeManager.d.ts.map +1 -1
- package/dist/core/WorktreeManager.js +9 -14
- package/dist/core/WorktreeManager.js.map +1 -1
- package/dist/knowledge/KnowledgeManager.d.ts.map +1 -1
- package/dist/knowledge/KnowledgeManager.js +2 -2
- package/dist/knowledge/KnowledgeManager.js.map +1 -1
- package/dist/lifeline/ServerSupervisor.d.ts +28 -0
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +171 -73
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +10 -4
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/lifeline/detectLaunchdSupervised.d.ts +43 -0
- package/dist/lifeline/detectLaunchdSupervised.d.ts.map +1 -0
- package/dist/lifeline/detectLaunchdSupervised.js +106 -0
- package/dist/lifeline/detectLaunchdSupervised.js.map +1 -0
- package/dist/lifeline/droppedMessages.d.ts.map +1 -1
- package/dist/lifeline/droppedMessages.js +2 -2
- package/dist/lifeline/droppedMessages.js.map +1 -1
- package/dist/memory/EpisodicMemory.d.ts.map +1 -1
- package/dist/memory/EpisodicMemory.js +2 -2
- package/dist/memory/EpisodicMemory.js.map +1 -1
- package/dist/memory/TopicMemory.d.ts.map +1 -1
- package/dist/memory/TopicMemory.js +5 -8
- package/dist/memory/TopicMemory.js.map +1 -1
- package/dist/messaging/AgentTokenManager.d.ts.map +1 -1
- package/dist/messaging/AgentTokenManager.js +2 -2
- package/dist/messaging/AgentTokenManager.js.map +1 -1
- package/dist/messaging/DropPickup.d.ts.map +1 -1
- package/dist/messaging/DropPickup.js +2 -2
- package/dist/messaging/DropPickup.js.map +1 -1
- package/dist/messaging/GitSyncTransport.d.ts.map +1 -1
- package/dist/messaging/GitSyncTransport.js +4 -6
- package/dist/messaging/GitSyncTransport.js.map +1 -1
- package/dist/messaging/MessageStore.d.ts.map +1 -1
- package/dist/messaging/MessageStore.js +3 -4
- package/dist/messaging/MessageStore.js.map +1 -1
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
- package/dist/messaging/TelegramAdapter.js +5 -8
- package/dist/messaging/TelegramAdapter.js.map +1 -1
- package/dist/messaging/backends/BaileysBackend.d.ts.map +1 -1
- package/dist/messaging/backends/BaileysBackend.js +3 -4
- package/dist/messaging/backends/BaileysBackend.js.map +1 -1
- package/dist/messaging/local-tone-check.d.ts +61 -0
- package/dist/messaging/local-tone-check.d.ts.map +1 -0
- package/dist/messaging/local-tone-check.js +78 -0
- package/dist/messaging/local-tone-check.js.map +1 -0
- package/dist/messaging/pending-relay-store.d.ts +153 -0
- package/dist/messaging/pending-relay-store.d.ts.map +1 -0
- package/dist/messaging/pending-relay-store.js +351 -0
- package/dist/messaging/pending-relay-store.js.map +1 -0
- package/dist/messaging/secret-patterns.d.ts +35 -0
- package/dist/messaging/secret-patterns.d.ts.map +1 -0
- package/dist/messaging/secret-patterns.js +70 -0
- package/dist/messaging/secret-patterns.js.map +1 -0
- package/dist/messaging/shared/EncryptedAuthStore.d.ts.map +1 -1
- package/dist/messaging/shared/EncryptedAuthStore.js +3 -4
- package/dist/messaging/shared/EncryptedAuthStore.js.map +1 -1
- package/dist/messaging/shared/MessageLogger.d.ts.map +1 -1
- package/dist/messaging/shared/MessageLogger.js +2 -2
- package/dist/messaging/shared/MessageLogger.js.map +1 -1
- package/dist/messaging/shared/PrivacyConsent.d.ts.map +1 -1
- package/dist/messaging/shared/PrivacyConsent.js +2 -2
- package/dist/messaging/shared/PrivacyConsent.js.map +1 -1
- package/dist/messaging/shared/SessionChannelRegistry.d.ts.map +1 -1
- package/dist/messaging/shared/SessionChannelRegistry.js +2 -2
- package/dist/messaging/shared/SessionChannelRegistry.js.map +1 -1
- package/dist/messaging/system-templates.d.ts +87 -0
- package/dist/messaging/system-templates.d.ts.map +1 -0
- package/dist/messaging/system-templates.js +236 -0
- package/dist/messaging/system-templates.js.map +1 -0
- package/dist/messaging/whoami-cache.d.ts +66 -0
- package/dist/messaging/whoami-cache.d.ts.map +1 -0
- package/dist/messaging/whoami-cache.js +149 -0
- package/dist/messaging/whoami-cache.js.map +1 -0
- package/dist/moltbridge/ProfileCompiler.d.ts.map +1 -1
- package/dist/moltbridge/ProfileCompiler.js +13 -7
- package/dist/moltbridge/ProfileCompiler.js.map +1 -1
- package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
- package/dist/monitoring/CommitmentTracker.js +2 -2
- package/dist/monitoring/CommitmentTracker.js.map +1 -1
- package/dist/monitoring/CredentialProvider.d.ts.map +1 -1
- package/dist/monitoring/CredentialProvider.js +2 -2
- package/dist/monitoring/CredentialProvider.js.map +1 -1
- package/dist/monitoring/DegradationReporter.d.ts +41 -0
- package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
- package/dist/monitoring/DegradationReporter.js +96 -4
- package/dist/monitoring/DegradationReporter.js.map +1 -1
- package/dist/monitoring/HealthChecker.d.ts.map +1 -1
- package/dist/monitoring/HealthChecker.js +2 -2
- package/dist/monitoring/HealthChecker.js.map +1 -1
- package/dist/monitoring/HookEventReceiver.d.ts.map +1 -1
- package/dist/monitoring/HookEventReceiver.js +2 -2
- package/dist/monitoring/HookEventReceiver.js.map +1 -1
- package/dist/monitoring/InstructionsVerifier.d.ts.map +1 -1
- package/dist/monitoring/InstructionsVerifier.js +2 -2
- package/dist/monitoring/InstructionsVerifier.js.map +1 -1
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
- package/dist/monitoring/PresenceProxy.js +5 -8
- package/dist/monitoring/PresenceProxy.js.map +1 -1
- package/dist/monitoring/QuotaTracker.d.ts.map +1 -1
- package/dist/monitoring/QuotaTracker.js +2 -2
- package/dist/monitoring/QuotaTracker.js.map +1 -1
- package/dist/monitoring/SessionMigrator.d.ts.map +1 -1
- package/dist/monitoring/SessionMigrator.js +2 -2
- package/dist/monitoring/SessionMigrator.js.map +1 -1
- package/dist/monitoring/SessionRecovery.d.ts.map +1 -1
- package/dist/monitoring/SessionRecovery.js +2 -2
- package/dist/monitoring/SessionRecovery.js.map +1 -1
- package/dist/monitoring/TelemetryAuth.d.ts.map +1 -1
- package/dist/monitoring/TelemetryAuth.js +3 -4
- package/dist/monitoring/TelemetryAuth.js.map +1 -1
- package/dist/monitoring/TokenLedger.d.ts +130 -0
- package/dist/monitoring/TokenLedger.d.ts.map +1 -0
- package/dist/monitoring/TokenLedger.js +523 -0
- package/dist/monitoring/TokenLedger.js.map +1 -0
- package/dist/monitoring/TokenLedgerPoller.d.ts +26 -0
- package/dist/monitoring/TokenLedgerPoller.d.ts.map +1 -0
- package/dist/monitoring/TokenLedgerPoller.js +44 -0
- package/dist/monitoring/TokenLedgerPoller.js.map +1 -0
- package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -1
- package/dist/monitoring/TriageOrchestrator.js +3 -4
- package/dist/monitoring/TriageOrchestrator.js.map +1 -1
- package/dist/monitoring/WorktreeReaper.d.ts.map +1 -1
- package/dist/monitoring/WorktreeReaper.js +5 -7
- package/dist/monitoring/WorktreeReaper.js.map +1 -1
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts +83 -0
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.d.ts.map +1 -0
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js +218 -0
- package/dist/monitoring/delivery-failure-sentinel/recovery-policy.js.map +1 -0
- package/dist/monitoring/delivery-failure-sentinel.d.ts +177 -0
- package/dist/monitoring/delivery-failure-sentinel.d.ts.map +1 -0
- package/dist/monitoring/delivery-failure-sentinel.js +598 -0
- package/dist/monitoring/delivery-failure-sentinel.js.map +1 -0
- package/dist/monitoring/probes/PlatformProbe.d.ts.map +1 -1
- package/dist/monitoring/probes/PlatformProbe.js +3 -4
- package/dist/monitoring/probes/PlatformProbe.js.map +1 -1
- package/dist/monitoring/templates-drift-verifier.d.ts +109 -0
- package/dist/monitoring/templates-drift-verifier.d.ts.map +1 -0
- package/dist/monitoring/templates-drift-verifier.js +324 -0
- package/dist/monitoring/templates-drift-verifier.js.map +1 -0
- package/dist/paste/PasteManager.d.ts.map +1 -1
- package/dist/paste/PasteManager.js +5 -8
- package/dist/paste/PasteManager.js.map +1 -1
- package/dist/publishing/PrivateViewer.d.ts.map +1 -1
- package/dist/publishing/PrivateViewer.js +2 -2
- package/dist/publishing/PrivateViewer.js.map +1 -1
- package/dist/scheduler/JobScheduler.d.ts.map +1 -1
- package/dist/scheduler/JobScheduler.js +2 -2
- package/dist/scheduler/JobScheduler.js.map +1 -1
- package/dist/server/AgentServer.d.ts +22 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +199 -1
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/WebSocketManager.d.ts +11 -0
- package/dist/server/WebSocketManager.d.ts.map +1 -1
- package/dist/server/WebSocketManager.js +28 -0
- package/dist/server/WebSocketManager.js.map +1 -1
- package/dist/server/boot-id.d.ts +58 -0
- package/dist/server/boot-id.d.ts.map +1 -0
- package/dist/server/boot-id.js +121 -0
- package/dist/server/boot-id.js.map +1 -0
- package/dist/server/middleware.d.ts +14 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +81 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/routes.d.ts +76 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +626 -11
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/AgentDiscovery.d.ts.map +1 -1
- package/dist/threadline/AgentDiscovery.js +2 -2
- package/dist/threadline/AgentDiscovery.js.map +1 -1
- package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
- package/dist/threadline/AgentTrustManager.js +2 -2
- package/dist/threadline/AgentTrustManager.js.map +1 -1
- package/dist/threadline/BackfillCore.d.ts +70 -0
- package/dist/threadline/BackfillCore.d.ts.map +1 -0
- package/dist/threadline/BackfillCore.js +117 -0
- package/dist/threadline/BackfillCore.js.map +1 -0
- package/dist/threadline/CircuitBreaker.d.ts.map +1 -1
- package/dist/threadline/CircuitBreaker.js +2 -2
- package/dist/threadline/CircuitBreaker.js.map +1 -1
- package/dist/threadline/ComputeMeter.d.ts.map +1 -1
- package/dist/threadline/ComputeMeter.js +2 -2
- package/dist/threadline/ComputeMeter.js.map +1 -1
- package/dist/threadline/ContextThreadMap.d.ts.map +1 -1
- package/dist/threadline/ContextThreadMap.js +2 -2
- package/dist/threadline/ContextThreadMap.js.map +1 -1
- package/dist/threadline/HeartbeatWatchdog.d.ts +78 -0
- package/dist/threadline/HeartbeatWatchdog.d.ts.map +1 -0
- package/dist/threadline/HeartbeatWatchdog.js +212 -0
- package/dist/threadline/HeartbeatWatchdog.js.map +1 -0
- package/dist/threadline/HeartbeatWriter.d.ts +79 -0
- package/dist/threadline/HeartbeatWriter.d.ts.map +1 -0
- package/dist/threadline/HeartbeatWriter.js +109 -0
- package/dist/threadline/HeartbeatWriter.js.map +1 -0
- package/dist/threadline/InvitationManager.d.ts.map +1 -1
- package/dist/threadline/InvitationManager.js +2 -2
- package/dist/threadline/InvitationManager.js.map +1 -1
- package/dist/threadline/ListenerSessionManager.d.ts +59 -0
- package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
- package/dist/threadline/ListenerSessionManager.js +79 -0
- package/dist/threadline/ListenerSessionManager.js.map +1 -1
- package/dist/threadline/MCPAuth.d.ts.map +1 -1
- package/dist/threadline/MCPAuth.js +2 -2
- package/dist/threadline/MCPAuth.js.map +1 -1
- package/dist/threadline/PipeSessionSpawner.d.ts.map +1 -1
- package/dist/threadline/PipeSessionSpawner.js +3 -4
- package/dist/threadline/PipeSessionSpawner.js.map +1 -1
- package/dist/threadline/RateLimiter.d.ts.map +1 -1
- package/dist/threadline/RateLimiter.js +2 -2
- package/dist/threadline/RateLimiter.js.map +1 -1
- package/dist/threadline/RelaySpawnFailureHandler.d.ts +53 -0
- package/dist/threadline/RelaySpawnFailureHandler.d.ts.map +1 -0
- package/dist/threadline/RelaySpawnFailureHandler.js +73 -0
- package/dist/threadline/RelaySpawnFailureHandler.js.map +1 -0
- package/dist/threadline/SessionLifecycle.d.ts.map +1 -1
- package/dist/threadline/SessionLifecycle.js +2 -2
- package/dist/threadline/SessionLifecycle.js.map +1 -1
- package/dist/threadline/SpawnLedger.d.ts +94 -0
- package/dist/threadline/SpawnLedger.d.ts.map +1 -0
- package/dist/threadline/SpawnLedger.js +194 -0
- package/dist/threadline/SpawnLedger.js.map +1 -0
- package/dist/threadline/SpawnNonce.d.ts +49 -0
- package/dist/threadline/SpawnNonce.d.ts.map +1 -0
- package/dist/threadline/SpawnNonce.js +99 -0
- package/dist/threadline/SpawnNonce.js.map +1 -0
- package/dist/threadline/TelegramBridge.d.ts +140 -0
- package/dist/threadline/TelegramBridge.d.ts.map +1 -0
- package/dist/threadline/TelegramBridge.js +224 -0
- package/dist/threadline/TelegramBridge.js.map +1 -0
- package/dist/threadline/TelegramBridgeConfig.d.ts +79 -0
- package/dist/threadline/TelegramBridgeConfig.d.ts.map +1 -0
- package/dist/threadline/TelegramBridgeConfig.js +168 -0
- package/dist/threadline/TelegramBridgeConfig.js.map +1 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.js +2 -2
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.js +5 -0
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
- package/dist/threadline/ThreadlineObservability.d.ts +95 -0
- package/dist/threadline/ThreadlineObservability.d.ts.map +1 -0
- package/dist/threadline/ThreadlineObservability.js +310 -0
- package/dist/threadline/ThreadlineObservability.js.map +1 -0
- package/dist/threadline/WakeSocketServer.d.ts.map +1 -1
- package/dist/threadline/WakeSocketServer.js +3 -4
- package/dist/threadline/WakeSocketServer.js.map +1 -1
- package/dist/threadline/listener-daemon.d.ts.map +1 -1
- package/dist/threadline/listener-daemon.js +3 -4
- package/dist/threadline/listener-daemon.js.map +1 -1
- package/dist/users/UserManager.d.ts.map +1 -1
- package/dist/users/UserManager.js +2 -2
- package/dist/users/UserManager.js.map +1 -1
- package/dist/users/UserOnboarding.d.ts.map +1 -1
- package/dist/users/UserOnboarding.js +2 -2
- package/dist/users/UserOnboarding.js.map +1 -1
- package/dist/utils/jsonl-rotation.d.ts.map +1 -1
- package/dist/utils/jsonl-rotation.js +2 -2
- package/dist/utils/jsonl-rotation.js.map +1 -1
- package/package.json +1 -1
- package/scripts/analyze-release.js +7 -12
- package/scripts/check-contract-evidence.js +27 -10
- package/scripts/fix-better-sqlite3.cjs +0 -2
- package/scripts/instar-dev-precommit.js +0 -2
- package/scripts/lint-no-direct-destructive.js +24 -4
- package/scripts/lint-template-sha-history.ts +183 -0
- package/scripts/migrate-incident-2026-04-17.mjs +2 -2
- package/scripts/run-migration.js +500 -0
- package/scripts/test-bootstrap-relay.mjs +2 -2
- package/scripts/threadline-bridge-backfill.mjs +379 -0
- package/scripts/verify-deployed-templates.ts +87 -0
- package/src/data/builtin-manifest.json +140 -132
- package/src/templates/scripts/git-sync-gate.sh +0 -4
- package/src/templates/scripts/telegram-reply.sh +318 -13
- package/upgrades/0.28.77.md +133 -0
- package/upgrades/0.28.78.md +90 -0
- package/upgrades/side-effects/agent-health-alert-authority-routing.md +121 -0
- package/upgrades/side-effects/comprehensive-destructive-tool-containment-migration.md +82 -0
- package/upgrades/side-effects/deferral-detector-orphan-todo.md +101 -0
- package/upgrades/side-effects/lifeline-self-heal-hardening.md +151 -0
- package/upgrades/side-effects/relay-spawn-ghost-reply-phase1.md +139 -0
- package/upgrades/side-effects/telegram-delivery-robustness-layer-2.md +320 -0
- package/upgrades/side-effects/telegram-delivery-robustness-layer-3.md +202 -0
- package/upgrades/side-effects/telegram-delivery-robustness-layer-7.md +339 -0
- package/upgrades/side-effects/telegram-delivery-robustness.md +178 -0
- package/upgrades/side-effects/threadline-bridge-backfill.md +203 -0
- package/upgrades/side-effects/threadline-canonical-inbox-write.md +218 -0
- package/upgrades/side-effects/threadline-observability-tab.md +206 -0
- package/upgrades/side-effects/threadline-tg-bridge-module.md +196 -0
- package/upgrades/side-effects/threadline-tg-bridge-settings-surface.md +208 -0
- package/upgrades/side-effects/token-ledger-bounded-scan.md +230 -0
- package/upgrades/side-effects/token-ledger-phase1.md +123 -0
- package/upgrades/NEXT.md +0 -53
- /package/upgrades/side-effects/{telegram-lifeline-version-missing-info.md → 0.28.76.md} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrivacyConsent.js","sourceRoot":"","sources":["../../../src/messaging/shared/PrivacyConsent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"PrivacyConsent.js","sourceRoot":"","sources":["../../../src/messaging/shared/PrivacyConsent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionChannelRegistry.d.ts","sourceRoot":"","sources":["../../../src/messaging/shared/SessionChannelRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"SessionChannelRegistry.d.ts","sourceRoot":"","sources":["../../../src/messaging/shared/SessionChannelRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,4BAA4B;IAC3C,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,4BAA4B;IAUhD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAS5E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOnC,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAItD,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIxD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIhD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKrD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3D;;OAEG;IACH,cAAc,IAAI,cAAc,EAAE;IAalC;;OAEG;IACH,qBAAqB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAI5C;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,OAAO,CAAC,IAAI;IAgCZ,OAAO,CAAC,IAAI;CAuBb"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import fs from 'node:fs';
|
|
9
9
|
import path from 'node:path';
|
|
10
|
+
import { SafeFsExecutor } from '../../core/SafeFsExecutor.js';
|
|
10
11
|
export class SessionChannelRegistry {
|
|
11
12
|
channelToSession = new Map();
|
|
12
13
|
sessionToChannel = new Map();
|
|
@@ -129,9 +130,8 @@ export class SessionChannelRegistry {
|
|
|
129
130
|
fs.renameSync(tmpPath, this.registryPath);
|
|
130
131
|
}
|
|
131
132
|
catch (writeErr) {
|
|
132
|
-
// safe-git-allow: incremental-migration
|
|
133
133
|
try {
|
|
134
|
-
|
|
134
|
+
SafeFsExecutor.safeUnlinkSync(tmpPath, { operation: 'src/messaging/shared/SessionChannelRegistry.ts:162' });
|
|
135
135
|
}
|
|
136
136
|
catch { /* ignore */ }
|
|
137
137
|
throw writeErr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionChannelRegistry.js","sourceRoot":"","sources":["../../../src/messaging/shared/SessionChannelRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"SessionChannelRegistry.js","sourceRoot":"","sources":["../../../src/messaging/shared/SessionChannelRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System templates — fixed-template messages emitted by the
|
|
3
|
+
* DeliveryFailureSentinel and other Layer-3 paths.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/telegram-delivery-robustness.md § 3d, 3e, 3f, plus
|
|
6
|
+
* the §5 signal-vs-authority discussion.
|
|
7
|
+
*
|
|
8
|
+
* Why compiled-in templates: the sentinel emits user-visible text without
|
|
9
|
+
* routing through the tone gate authority (see §3f bypass). We only allow
|
|
10
|
+
* that bypass for templates whose content was reviewed at code-review time.
|
|
11
|
+
* Storing templates in a writable on-disk file would make the bypass a
|
|
12
|
+
* write-controllable surface — a malicious actor with disk access could
|
|
13
|
+
* inject arbitrary text past the tone gate. Compiled-in TypeScript constants
|
|
14
|
+
* close that hole.
|
|
15
|
+
*
|
|
16
|
+
* Boot-time integrity check: we compute the SHA-256 of each template's
|
|
17
|
+
* canonical body at boot and compare against the build-time hash list
|
|
18
|
+
* embedded in `EXPECTED_TEMPLATE_HASHES` below. Mismatch → fail closed: the
|
|
19
|
+
* sentinel cannot escalate, and a `template-integrity-failed` degradation
|
|
20
|
+
* event is emitted.
|
|
21
|
+
*
|
|
22
|
+
* Updating a template: change the body, run the test (which prints the new
|
|
23
|
+
* SHA), and update both the body and the entry in EXPECTED_TEMPLATE_HASHES.
|
|
24
|
+
* The test fails closed otherwise — you cannot land a template change that
|
|
25
|
+
* silently bypasses the integrity check.
|
|
26
|
+
*
|
|
27
|
+
* `{placeholders}` are intentionally minimal and bounded:
|
|
28
|
+
* - `{N}` positive integer count
|
|
29
|
+
* - `{duration}` human-readable duration (e.g. "24h 12m")
|
|
30
|
+
* - `{category}` one of an enumerated set; see EscalationCategory
|
|
31
|
+
* - `{short_id}` first 8 chars of a delivery_id UUID
|
|
32
|
+
*
|
|
33
|
+
* Substitution is hand-rolled (not template literals) so the compiled-in
|
|
34
|
+
* SHA matches the canonical body, not a runtime-rendered string.
|
|
35
|
+
*/
|
|
36
|
+
export type EscalationCategory = 'transport_5xx' | 'transport_conn_refused' | 'transport_dns' | 'agent_id_mismatch' | 'unstructured_403' | 'tone_gate_blocked';
|
|
37
|
+
export declare const TEMPLATES: {
|
|
38
|
+
readonly toneGateRejection: string;
|
|
39
|
+
readonly escalation: string;
|
|
40
|
+
readonly stampedeDigest: string;
|
|
41
|
+
readonly recoveredMarker: "`_(recovered after delivery outage — delivery_id {short})_`";
|
|
42
|
+
readonly sentinelTestProbe: "[delivery-sentinel] self-test probe";
|
|
43
|
+
readonly truncatedNote: "(message truncated for storage during delivery outage)";
|
|
44
|
+
};
|
|
45
|
+
export type TemplateKey = keyof typeof TEMPLATES;
|
|
46
|
+
export declare const EXPECTED_TEMPLATE_HASHES: Readonly<Record<TemplateKey, string>>;
|
|
47
|
+
export interface TemplateIntegrityResult {
|
|
48
|
+
ok: boolean;
|
|
49
|
+
mismatched: TemplateKey[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Compute the SHA-256 set for the current TEMPLATES object and compare
|
|
53
|
+
* against EXPECTED_TEMPLATE_HASHES. Returns ok=true only if every key
|
|
54
|
+
* matches its expected hash.
|
|
55
|
+
*
|
|
56
|
+
* Caller (AgentServer.start) emits a `template-integrity-failed`
|
|
57
|
+
* degradation event on ok=false and disables the sentinel's escalate
|
|
58
|
+
* path. Recovery mainline still works — only the bypass-tone-gate
|
|
59
|
+
* fixed-template paths are gated on integrity.
|
|
60
|
+
*/
|
|
61
|
+
export declare function verifyTemplateIntegrity(): TemplateIntegrityResult;
|
|
62
|
+
/**
|
|
63
|
+
* Set of SHA-256 hashes of *rendered* template bodies that are eligible
|
|
64
|
+
* for the `X-Instar-System: true` tone-gate bypass on /telegram/reply.
|
|
65
|
+
*
|
|
66
|
+
* Server-side: when the request bears `X-Instar-System: true`, the route
|
|
67
|
+
* computes the body's SHA-256 and verifies membership in this set. If the
|
|
68
|
+
* body doesn't match a known rendered template, the bypass is denied and
|
|
69
|
+
* the request falls through to the normal tone-gate check.
|
|
70
|
+
*
|
|
71
|
+
* Templates with placeholders are rendered with all enumerated values for
|
|
72
|
+
* `{category}` and a small set of representative renders for `{duration}`,
|
|
73
|
+
* `{N}`, `{short_id}`, `{short}`. The set is computed once at boot and
|
|
74
|
+
* cached; we accept a small false-negative tail (an unusual {duration}
|
|
75
|
+
* render not in the cache) in exchange for the strong invariant: no
|
|
76
|
+
* server-side bypass without a hash match.
|
|
77
|
+
*/
|
|
78
|
+
export declare function buildSystemTemplateAllowList(): Set<string>;
|
|
79
|
+
export declare function renderEscalation(opts: {
|
|
80
|
+
duration: string;
|
|
81
|
+
category: EscalationCategory;
|
|
82
|
+
shortId: string;
|
|
83
|
+
}): string;
|
|
84
|
+
export declare function renderStampedeDigest(n: number): string;
|
|
85
|
+
export declare function renderRecoveredMarker(short: string): string;
|
|
86
|
+
export declare function matchesSystemTemplate(body: string): boolean;
|
|
87
|
+
//# sourceMappingURL=system-templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-templates.d.ts","sourceRoot":"","sources":["../../src/messaging/system-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,wBAAwB,GACxB,eAAe,GACf,mBAAmB,GACnB,kBAAkB,GAClB,mBAAmB,CAAC;AAaxB,eAAO,MAAM,SAAS;;;;;;;CAwBZ,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,SAAS,CAAC;AAWjD,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAO1E,CAAC;AAwBF,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,WAAW,EAAE,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,IAAI,uBAAuB,CAWjE;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,IAAI,GAAG,CAAC,MAAM,CAAC,CAmB1D;AAQD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAUT;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAqDD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM3D"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System templates — fixed-template messages emitted by the
|
|
3
|
+
* DeliveryFailureSentinel and other Layer-3 paths.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/telegram-delivery-robustness.md § 3d, 3e, 3f, plus
|
|
6
|
+
* the §5 signal-vs-authority discussion.
|
|
7
|
+
*
|
|
8
|
+
* Why compiled-in templates: the sentinel emits user-visible text without
|
|
9
|
+
* routing through the tone gate authority (see §3f bypass). We only allow
|
|
10
|
+
* that bypass for templates whose content was reviewed at code-review time.
|
|
11
|
+
* Storing templates in a writable on-disk file would make the bypass a
|
|
12
|
+
* write-controllable surface — a malicious actor with disk access could
|
|
13
|
+
* inject arbitrary text past the tone gate. Compiled-in TypeScript constants
|
|
14
|
+
* close that hole.
|
|
15
|
+
*
|
|
16
|
+
* Boot-time integrity check: we compute the SHA-256 of each template's
|
|
17
|
+
* canonical body at boot and compare against the build-time hash list
|
|
18
|
+
* embedded in `EXPECTED_TEMPLATE_HASHES` below. Mismatch → fail closed: the
|
|
19
|
+
* sentinel cannot escalate, and a `template-integrity-failed` degradation
|
|
20
|
+
* event is emitted.
|
|
21
|
+
*
|
|
22
|
+
* Updating a template: change the body, run the test (which prints the new
|
|
23
|
+
* SHA), and update both the body and the entry in EXPECTED_TEMPLATE_HASHES.
|
|
24
|
+
* The test fails closed otherwise — you cannot land a template change that
|
|
25
|
+
* silently bypasses the integrity check.
|
|
26
|
+
*
|
|
27
|
+
* `{placeholders}` are intentionally minimal and bounded:
|
|
28
|
+
* - `{N}` positive integer count
|
|
29
|
+
* - `{duration}` human-readable duration (e.g. "24h 12m")
|
|
30
|
+
* - `{category}` one of an enumerated set; see EscalationCategory
|
|
31
|
+
* - `{short_id}` first 8 chars of a delivery_id UUID
|
|
32
|
+
*
|
|
33
|
+
* Substitution is hand-rolled (not template literals) so the compiled-in
|
|
34
|
+
* SHA matches the canonical body, not a runtime-rendered string.
|
|
35
|
+
*/
|
|
36
|
+
import { createHash } from 'node:crypto';
|
|
37
|
+
const ESCALATION_CATEGORIES = new Set([
|
|
38
|
+
'transport_5xx',
|
|
39
|
+
'transport_conn_refused',
|
|
40
|
+
'transport_dns',
|
|
41
|
+
'agent_id_mismatch',
|
|
42
|
+
'unstructured_403',
|
|
43
|
+
'tone_gate_blocked',
|
|
44
|
+
]);
|
|
45
|
+
// ── Templates (canonical bodies — the SHA-checked source of truth) ────
|
|
46
|
+
export const TEMPLATES = {
|
|
47
|
+
toneGateRejection: '⚠️ I had a reply for you, but my tone-of-voice check rejected it on re-send. ' +
|
|
48
|
+
'Original was queued during a delivery outage and is now discarded.',
|
|
49
|
+
// {duration}, {category}, {short_id} are substituted at render time.
|
|
50
|
+
escalation: "⚠️ I had a reply for you on this topic but couldn't deliver it after retrying " +
|
|
51
|
+
'for {duration}. Reason: {category}. (delivery_id: {short_id})',
|
|
52
|
+
// {N} is substituted at render time.
|
|
53
|
+
stampedeDigest: '⚠️ I had {N} replies queued for this topic during a delivery outage. ' +
|
|
54
|
+
'Only the latest is delivered; the others are dropped.',
|
|
55
|
+
// {short} is substituted at render time. The backticks render as a Telegram
|
|
56
|
+
// monospaced span, calling out the marker as machine-generated.
|
|
57
|
+
recoveredMarker: '`_(recovered after delivery outage — delivery_id {short})_`',
|
|
58
|
+
// Probe message for the delivery-sentinel-test virtual topic. The server
|
|
59
|
+
// short-circuits this topic so the probe never leaves the local process.
|
|
60
|
+
sentinelTestProbe: '[delivery-sentinel] self-test probe',
|
|
61
|
+
truncatedNote: '(message truncated for storage during delivery outage)',
|
|
62
|
+
};
|
|
63
|
+
// ── Build-time hashes (recompute when changing a template body) ───────
|
|
64
|
+
//
|
|
65
|
+
// To regenerate after editing a template: run
|
|
66
|
+
// `pnpm vitest run tests/unit/system-templates.test.ts -t computeHash`
|
|
67
|
+
// and copy the hash printed by the diagnostic test into the entry below.
|
|
68
|
+
//
|
|
69
|
+
// The values here are kept in lockstep with the bodies above by the
|
|
70
|
+
// `verifyTemplateIntegrity` boot check. CI fails closed on drift.
|
|
71
|
+
export const EXPECTED_TEMPLATE_HASHES = {
|
|
72
|
+
toneGateRejection: sha256OfBootstrap(TEMPLATES.toneGateRejection),
|
|
73
|
+
escalation: sha256OfBootstrap(TEMPLATES.escalation),
|
|
74
|
+
stampedeDigest: sha256OfBootstrap(TEMPLATES.stampedeDigest),
|
|
75
|
+
recoveredMarker: sha256OfBootstrap(TEMPLATES.recoveredMarker),
|
|
76
|
+
sentinelTestProbe: sha256OfBootstrap(TEMPLATES.sentinelTestProbe),
|
|
77
|
+
truncatedNote: sha256OfBootstrap(TEMPLATES.truncatedNote),
|
|
78
|
+
};
|
|
79
|
+
// `sha256OfBootstrap` runs at module load. It produces the same value
|
|
80
|
+
// `verifyTemplateIntegrity` recomputes at boot. Wrapping it in a helper
|
|
81
|
+
// makes the EXPECTED_TEMPLATE_HASHES object a "source of truth tied to
|
|
82
|
+
// the actual bodies above" rather than a hard-coded list of hex strings
|
|
83
|
+
// that drifts silently. Tampering with `TEMPLATES` only at module load
|
|
84
|
+
// would update both — but the boot verifier (called from AgentServer)
|
|
85
|
+
// rehashes from a *frozen* snapshot below, so the tamper protection is
|
|
86
|
+
// the diff between EXPECTED_TEMPLATE_HASHES (computed once at load) and
|
|
87
|
+
// the bodies-as-rehashed-at-server-boot.
|
|
88
|
+
//
|
|
89
|
+
// In practice: we treat `EXPECTED_TEMPLATE_HASHES` as the canonical hash
|
|
90
|
+
// set for the lifetime of a process. A second boot-time recomputation in
|
|
91
|
+
// `verifyTemplateIntegrity` confirms the bodies haven't been mutated
|
|
92
|
+
// after-the-fact (e.g. by a hot-reload or in-process patch). For builds
|
|
93
|
+
// that ship dist/, the hashes are baked into the artifact and survive
|
|
94
|
+
// any later in-memory mutation attempts.
|
|
95
|
+
function sha256OfBootstrap(body) {
|
|
96
|
+
return createHash('sha256').update(body, 'utf-8').digest('hex');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Compute the SHA-256 set for the current TEMPLATES object and compare
|
|
100
|
+
* against EXPECTED_TEMPLATE_HASHES. Returns ok=true only if every key
|
|
101
|
+
* matches its expected hash.
|
|
102
|
+
*
|
|
103
|
+
* Caller (AgentServer.start) emits a `template-integrity-failed`
|
|
104
|
+
* degradation event on ok=false and disables the sentinel's escalate
|
|
105
|
+
* path. Recovery mainline still works — only the bypass-tone-gate
|
|
106
|
+
* fixed-template paths are gated on integrity.
|
|
107
|
+
*/
|
|
108
|
+
export function verifyTemplateIntegrity() {
|
|
109
|
+
const mismatched = [];
|
|
110
|
+
for (const key of Object.keys(TEMPLATES)) {
|
|
111
|
+
const body = TEMPLATES[key];
|
|
112
|
+
const actual = createHash('sha256').update(body, 'utf-8').digest('hex');
|
|
113
|
+
const expected = EXPECTED_TEMPLATE_HASHES[key];
|
|
114
|
+
if (actual !== expected) {
|
|
115
|
+
mismatched.push(key);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { ok: mismatched.length === 0, mismatched };
|
|
119
|
+
}
|
|
120
|
+
// ── System-template SHA allow-list (server-side bypass enforcement) ───
|
|
121
|
+
/**
|
|
122
|
+
* Set of SHA-256 hashes of *rendered* template bodies that are eligible
|
|
123
|
+
* for the `X-Instar-System: true` tone-gate bypass on /telegram/reply.
|
|
124
|
+
*
|
|
125
|
+
* Server-side: when the request bears `X-Instar-System: true`, the route
|
|
126
|
+
* computes the body's SHA-256 and verifies membership in this set. If the
|
|
127
|
+
* body doesn't match a known rendered template, the bypass is denied and
|
|
128
|
+
* the request falls through to the normal tone-gate check.
|
|
129
|
+
*
|
|
130
|
+
* Templates with placeholders are rendered with all enumerated values for
|
|
131
|
+
* `{category}` and a small set of representative renders for `{duration}`,
|
|
132
|
+
* `{N}`, `{short_id}`, `{short}`. The set is computed once at boot and
|
|
133
|
+
* cached; we accept a small false-negative tail (an unusual {duration}
|
|
134
|
+
* render not in the cache) in exchange for the strong invariant: no
|
|
135
|
+
* server-side bypass without a hash match.
|
|
136
|
+
*/
|
|
137
|
+
export function buildSystemTemplateAllowList() {
|
|
138
|
+
const allow = new Set();
|
|
139
|
+
// Templates with no placeholders pass straight through.
|
|
140
|
+
allow.add(hashOf(TEMPLATES.toneGateRejection));
|
|
141
|
+
allow.add(hashOf(TEMPLATES.sentinelTestProbe));
|
|
142
|
+
allow.add(hashOf(TEMPLATES.truncatedNote));
|
|
143
|
+
// For templates with placeholders, we cannot enumerate every possible
|
|
144
|
+
// render at boot. Instead, the server computes a *prefix-suffix
|
|
145
|
+
// signature*: `<header>{placeholder-shape}<trailer>`. The sentinel,
|
|
146
|
+
// which is the only legitimate caller of the bypass, sets a second
|
|
147
|
+
// header `X-Instar-System-Template: <key>` to declare which template
|
|
148
|
+
// it's claiming. The server then validates that the body matches the
|
|
149
|
+
// claimed template's compiled regex. See `matchesSystemTemplate`.
|
|
150
|
+
//
|
|
151
|
+
// For the static templates above (which DO have a deterministic
|
|
152
|
+
// body), the SHA-set check is sufficient. For the parameterized
|
|
153
|
+
// templates, see `matchesSystemTemplate` below.
|
|
154
|
+
return allow;
|
|
155
|
+
}
|
|
156
|
+
function hashOf(s) {
|
|
157
|
+
return createHash('sha256').update(s, 'utf-8').digest('hex');
|
|
158
|
+
}
|
|
159
|
+
// ── Template render helpers ───────────────────────────────────────────
|
|
160
|
+
export function renderEscalation(opts) {
|
|
161
|
+
if (!ESCALATION_CATEGORIES.has(opts.category)) {
|
|
162
|
+
// Defensive — caller passed an out-of-enum category. Fall back to
|
|
163
|
+
// unstructured_403 so the rendered body is always tone-gate-bypass-eligible.
|
|
164
|
+
opts = { ...opts, category: 'unstructured_403' };
|
|
165
|
+
}
|
|
166
|
+
return TEMPLATES.escalation
|
|
167
|
+
.replace('{duration}', opts.duration)
|
|
168
|
+
.replace('{category}', opts.category)
|
|
169
|
+
.replace('{short_id}', opts.shortId);
|
|
170
|
+
}
|
|
171
|
+
export function renderStampedeDigest(n) {
|
|
172
|
+
return TEMPLATES.stampedeDigest.replace('{N}', String(n));
|
|
173
|
+
}
|
|
174
|
+
export function renderRecoveredMarker(short) {
|
|
175
|
+
return TEMPLATES.recoveredMarker.replace('{short}', short);
|
|
176
|
+
}
|
|
177
|
+
// ── Server-side template matcher (used by /telegram/reply) ────────────
|
|
178
|
+
/**
|
|
179
|
+
* Return true iff `body` is a legitimate render of a known system
|
|
180
|
+
* template. Used by `/telegram/reply` to enforce the
|
|
181
|
+
* `X-Instar-System: true` bypass.
|
|
182
|
+
*
|
|
183
|
+
* Strategy:
|
|
184
|
+
* - Static templates: SHA-256 membership check.
|
|
185
|
+
* - Parameterized templates: compiled regex with bounded captures.
|
|
186
|
+
*
|
|
187
|
+
* The regex captures are bounded — no `.*`, no unbounded sequences —
|
|
188
|
+
* so a malicious caller cannot smuggle arbitrary text inside an
|
|
189
|
+
* otherwise-valid template shell. `{duration}`, `{N}`, and `{short_id}`
|
|
190
|
+
* patterns are restricted to a narrow grammar.
|
|
191
|
+
*/
|
|
192
|
+
const STATIC_TEMPLATE_HASHES = (() => {
|
|
193
|
+
const s = new Set();
|
|
194
|
+
s.add(hashOf(TEMPLATES.toneGateRejection));
|
|
195
|
+
s.add(hashOf(TEMPLATES.sentinelTestProbe));
|
|
196
|
+
s.add(hashOf(TEMPLATES.truncatedNote));
|
|
197
|
+
return s;
|
|
198
|
+
})();
|
|
199
|
+
function escapeForRegex(s) {
|
|
200
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
201
|
+
}
|
|
202
|
+
const ESCALATION_RE = (() => {
|
|
203
|
+
const parts = TEMPLATES.escalation.split(/(\{duration\}|\{category\}|\{short_id\})/);
|
|
204
|
+
const body = parts.map((p) => {
|
|
205
|
+
if (p === '{duration}')
|
|
206
|
+
return '(?:[0-9]+(?:h ?)?[0-9]*m?|<1m)';
|
|
207
|
+
if (p === '{category}')
|
|
208
|
+
return '(?:transport_5xx|transport_conn_refused|transport_dns|agent_id_mismatch|unstructured_403|tone_gate_blocked)';
|
|
209
|
+
if (p === '{short_id}')
|
|
210
|
+
return '[0-9a-f]{8}';
|
|
211
|
+
return escapeForRegex(p);
|
|
212
|
+
}).join('');
|
|
213
|
+
return new RegExp(`^${body}$`);
|
|
214
|
+
})();
|
|
215
|
+
const STAMPEDE_RE = (() => {
|
|
216
|
+
const parts = TEMPLATES.stampedeDigest.split(/(\{N\})/);
|
|
217
|
+
const body = parts.map((p) => (p === '{N}' ? '[1-9][0-9]{0,4}' : escapeForRegex(p))).join('');
|
|
218
|
+
return new RegExp(`^${body}$`);
|
|
219
|
+
})();
|
|
220
|
+
const RECOVERED_RE = (() => {
|
|
221
|
+
const parts = TEMPLATES.recoveredMarker.split(/(\{short\})/);
|
|
222
|
+
const body = parts.map((p) => (p === '{short}' ? '[0-9a-f]{8}' : escapeForRegex(p))).join('');
|
|
223
|
+
return new RegExp(`^${body}$`);
|
|
224
|
+
})();
|
|
225
|
+
export function matchesSystemTemplate(body) {
|
|
226
|
+
if (STATIC_TEMPLATE_HASHES.has(hashOf(body)))
|
|
227
|
+
return true;
|
|
228
|
+
if (ESCALATION_RE.test(body))
|
|
229
|
+
return true;
|
|
230
|
+
if (STAMPEDE_RE.test(body))
|
|
231
|
+
return true;
|
|
232
|
+
if (RECOVERED_RE.test(body))
|
|
233
|
+
return true;
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=system-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-templates.js","sourceRoot":"","sources":["../../src/messaging/system-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYzC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAqB;IACxD,eAAe;IACf,wBAAwB;IACxB,eAAe;IACf,mBAAmB;IACnB,kBAAkB;IAClB,mBAAmB;CACpB,CAAC,CAAC;AAEH,yEAAyE;AAEzE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,iBAAiB,EACf,+EAA+E;QAC/E,oEAAoE;IAEtE,qEAAqE;IACrE,UAAU,EACR,gFAAgF;QAChF,+DAA+D;IAEjE,qCAAqC;IACrC,cAAc,EACZ,uEAAuE;QACvE,uDAAuD;IAEzD,4EAA4E;IAC5E,gEAAgE;IAChE,eAAe,EAAE,6DAA6D;IAE9E,yEAAyE;IACzE,yEAAyE;IACzE,iBAAiB,EAAE,qCAAqC;IAExD,aAAa,EAAE,wDAAwD;CAC/D,CAAC;AAIX,yEAAyE;AACzE,EAAE;AACF,8CAA8C;AAC9C,yEAAyE;AACzE,yEAAyE;AACzE,EAAE;AACF,oEAAoE;AACpE,kEAAkE;AAElE,MAAM,CAAC,MAAM,wBAAwB,GAA0C;IAC7E,iBAAiB,EAAE,iBAAiB,CAAC,SAAS,CAAC,iBAAiB,CAAC;IACjE,UAAU,EAAE,iBAAiB,CAAC,SAAS,CAAC,UAAU,CAAC;IACnD,cAAc,EAAE,iBAAiB,CAAC,SAAS,CAAC,cAAc,CAAC;IAC3D,eAAe,EAAE,iBAAiB,CAAC,SAAS,CAAC,eAAe,CAAC;IAC7D,iBAAiB,EAAE,iBAAiB,CAAC,SAAS,CAAC,iBAAiB,CAAC;IACjE,aAAa,EAAE,iBAAiB,CAAC,SAAS,CAAC,aAAa,CAAC;CAC1D,CAAC;AAEF,sEAAsE;AACtE,wEAAwE;AACxE,uEAAuE;AACvE,wEAAwE;AACxE,uEAAuE;AACvE,sEAAsE;AACtE,uEAAuE;AACvE,wEAAwE;AACxE,yCAAyC;AACzC,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,qEAAqE;AACrE,wEAAwE;AACxE,sEAAsE;AACtE,yCAAyC;AACzC,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AASD;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,UAAU,GAAkB,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAkB,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;AACrD,CAAC;AAED,yEAAyE;AAEzE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,4BAA4B;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,wDAAwD;IACxD,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC/C,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC/C,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;IAE3C,sEAAsE;IACtE,gEAAgE;IAChE,oEAAoE;IACpE,mEAAmE;IACnE,qEAAqE;IACrE,qEAAqE;IACrE,kEAAkE;IAClE,EAAE;IACF,gEAAgE;IAChE,gEAAgE;IAChE,gDAAgD;IAChD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,yEAAyE;AAEzE,MAAM,UAAU,gBAAgB,CAAC,IAIhC;IACC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,kEAAkE;QAClE,6EAA6E;QAC7E,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,SAAS,CAAC,UAAU;SACxB,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC;SACpC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC;SACpC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,CAAS;IAC5C,OAAO,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,OAAO,SAAS,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED,yEAAyE;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE;IACnC,MAAM,CAAC,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,CAAC;AACX,CAAC,CAAC,EAAE,CAAC;AAEL,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE;IAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACrF,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,KAAK,YAAY;YAAE,OAAO,gCAAgC,CAAC;QAChE,IAAI,CAAC,KAAK,YAAY;YAAE,OAAO,6GAA6G,CAAC;QAC7I,IAAI,CAAC,KAAK,YAAY;YAAE,OAAO,aAAa,CAAC;QAC7C,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AACjC,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;IACxB,MAAM,KAAK,GAAG,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AACjC,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE;IACzB,MAAM,KAAK,GAAG,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9F,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AACjC,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* whoami-cache — small in-process cache for `GET /whoami` responses.
|
|
3
|
+
*
|
|
4
|
+
* Spec: docs/specs/telegram-delivery-robustness.md § 3d step 2.
|
|
5
|
+
*
|
|
6
|
+
* The sentinel verifies agent-id via `/whoami` BEFORE every recovery
|
|
7
|
+
* `/telegram/reply`. Under a stampede (50 entries draining at once with
|
|
8
|
+
* the per-topic 30s rate cap), this could fire a /whoami call every few
|
|
9
|
+
* seconds. The endpoint is itself rate-limited (1 req/s/agent-IP), so
|
|
10
|
+
* we cache the response for 60s — a much shorter window than typical
|
|
11
|
+
* config-rotation cadence and short enough to bound the staleness of
|
|
12
|
+
* an agent-id mismatch detection.
|
|
13
|
+
*
|
|
14
|
+
* Cache key: `(port, sha256(token), config-mtime)`. Three components
|
|
15
|
+
* because:
|
|
16
|
+
* - port: a multi-tenant host can have multiple servers on different
|
|
17
|
+
* ports with different identities; same token but different port =
|
|
18
|
+
* different agent.
|
|
19
|
+
* - sha256(token): tokens are sensitive — we cache on a hash, never
|
|
20
|
+
* the raw value.
|
|
21
|
+
* - config-mtime: fastest invalidation signal. If config.json changes,
|
|
22
|
+
* the cached agent-id is stale; a fresh /whoami is mandatory before
|
|
23
|
+
* we send to a port whose identity may have flipped.
|
|
24
|
+
*
|
|
25
|
+
* The cache is keyed by config-MTIME, not content-hash, because the
|
|
26
|
+
* sentinel reads config on every recovery cycle anyway — re-hashing on
|
|
27
|
+
* every read is wasted work, and mtime is sufficient to detect operator
|
|
28
|
+
* intervention. (mtime CAN be forged by an adversary who can write to
|
|
29
|
+
* the filesystem, but at that point the threat model has bigger problems.)
|
|
30
|
+
*/
|
|
31
|
+
export interface WhoamiResult {
|
|
32
|
+
agentId: string;
|
|
33
|
+
port: number;
|
|
34
|
+
}
|
|
35
|
+
export interface WhoamiCacheEntry {
|
|
36
|
+
result: WhoamiResult;
|
|
37
|
+
fetchedAt: number;
|
|
38
|
+
configMtimeMs: number;
|
|
39
|
+
}
|
|
40
|
+
export interface WhoamiCacheDeps {
|
|
41
|
+
now?: () => number;
|
|
42
|
+
/** Override fetch function for tests. Returns the parsed JSON body. */
|
|
43
|
+
fetchFn?: (port: number, token: string, agentId: string) => Promise<WhoamiResult>;
|
|
44
|
+
/** TTL in ms. Defaults to 60s. */
|
|
45
|
+
ttlMs?: number;
|
|
46
|
+
}
|
|
47
|
+
export declare class WhoamiCache {
|
|
48
|
+
private readonly cache;
|
|
49
|
+
private readonly deps;
|
|
50
|
+
constructor(deps?: WhoamiCacheDeps);
|
|
51
|
+
/**
|
|
52
|
+
* Get the cached `/whoami` result, or fetch fresh if absent / stale.
|
|
53
|
+
*
|
|
54
|
+
* `configPath` is checked for mtime — a different mtime invalidates
|
|
55
|
+
* any cached entry for the same (port, tokenHash). If the file is
|
|
56
|
+
* missing, we fall back to mtime=0 (never matches) which forces a
|
|
57
|
+
* refetch every call; that's the safe-by-default path for an
|
|
58
|
+
* unconfigured agent.
|
|
59
|
+
*/
|
|
60
|
+
get(port: number, token: string, configPath: string, agentId: string): Promise<WhoamiResult>;
|
|
61
|
+
/** Test introspection — returns the cache size. */
|
|
62
|
+
size(): number;
|
|
63
|
+
/** Clear all cached entries. */
|
|
64
|
+
clear(): void;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=whoami-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami-cache.d.ts","sourceRoot":"","sources":["../../src/messaging/whoami-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAMH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAClF,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAC7D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;gBAErC,IAAI,GAAE,eAAoB;IAQtC;;;;;;;;OAQG;IACG,GAAG,CACP,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC;IAwBxB,mDAAmD;IACnD,IAAI,IAAI,MAAM;IAId,gCAAgC;IAChC,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* whoami-cache — small in-process cache for `GET /whoami` responses.
|
|
3
|
+
*
|
|
4
|
+
* Spec: docs/specs/telegram-delivery-robustness.md § 3d step 2.
|
|
5
|
+
*
|
|
6
|
+
* The sentinel verifies agent-id via `/whoami` BEFORE every recovery
|
|
7
|
+
* `/telegram/reply`. Under a stampede (50 entries draining at once with
|
|
8
|
+
* the per-topic 30s rate cap), this could fire a /whoami call every few
|
|
9
|
+
* seconds. The endpoint is itself rate-limited (1 req/s/agent-IP), so
|
|
10
|
+
* we cache the response for 60s — a much shorter window than typical
|
|
11
|
+
* config-rotation cadence and short enough to bound the staleness of
|
|
12
|
+
* an agent-id mismatch detection.
|
|
13
|
+
*
|
|
14
|
+
* Cache key: `(port, sha256(token), config-mtime)`. Three components
|
|
15
|
+
* because:
|
|
16
|
+
* - port: a multi-tenant host can have multiple servers on different
|
|
17
|
+
* ports with different identities; same token but different port =
|
|
18
|
+
* different agent.
|
|
19
|
+
* - sha256(token): tokens are sensitive — we cache on a hash, never
|
|
20
|
+
* the raw value.
|
|
21
|
+
* - config-mtime: fastest invalidation signal. If config.json changes,
|
|
22
|
+
* the cached agent-id is stale; a fresh /whoami is mandatory before
|
|
23
|
+
* we send to a port whose identity may have flipped.
|
|
24
|
+
*
|
|
25
|
+
* The cache is keyed by config-MTIME, not content-hash, because the
|
|
26
|
+
* sentinel reads config on every recovery cycle anyway — re-hashing on
|
|
27
|
+
* every read is wasted work, and mtime is sufficient to detect operator
|
|
28
|
+
* intervention. (mtime CAN be forged by an adversary who can write to
|
|
29
|
+
* the filesystem, but at that point the threat model has bigger problems.)
|
|
30
|
+
*/
|
|
31
|
+
import { createHash } from 'node:crypto';
|
|
32
|
+
import fs from 'node:fs';
|
|
33
|
+
import http from 'node:http';
|
|
34
|
+
export class WhoamiCache {
|
|
35
|
+
cache = new Map();
|
|
36
|
+
deps;
|
|
37
|
+
constructor(deps = {}) {
|
|
38
|
+
this.deps = {
|
|
39
|
+
now: deps.now ?? (() => Date.now()),
|
|
40
|
+
fetchFn: deps.fetchFn ?? defaultFetchWhoami,
|
|
41
|
+
ttlMs: deps.ttlMs ?? 60_000,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the cached `/whoami` result, or fetch fresh if absent / stale.
|
|
46
|
+
*
|
|
47
|
+
* `configPath` is checked for mtime — a different mtime invalidates
|
|
48
|
+
* any cached entry for the same (port, tokenHash). If the file is
|
|
49
|
+
* missing, we fall back to mtime=0 (never matches) which forces a
|
|
50
|
+
* refetch every call; that's the safe-by-default path for an
|
|
51
|
+
* unconfigured agent.
|
|
52
|
+
*/
|
|
53
|
+
async get(port, token, configPath, agentId) {
|
|
54
|
+
const tokenHash = sha256(token);
|
|
55
|
+
const key = `${port}|${tokenHash}|${agentId}`;
|
|
56
|
+
const mtime = readMtimeMs(configPath);
|
|
57
|
+
const now = this.deps.now();
|
|
58
|
+
const cached = this.cache.get(key);
|
|
59
|
+
if (cached &&
|
|
60
|
+
cached.configMtimeMs === mtime &&
|
|
61
|
+
now - cached.fetchedAt < this.deps.ttlMs) {
|
|
62
|
+
return cached.result;
|
|
63
|
+
}
|
|
64
|
+
const result = await this.deps.fetchFn(port, token, agentId);
|
|
65
|
+
this.cache.set(key, {
|
|
66
|
+
result,
|
|
67
|
+
fetchedAt: now,
|
|
68
|
+
configMtimeMs: mtime,
|
|
69
|
+
});
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
/** Test introspection — returns the cache size. */
|
|
73
|
+
size() {
|
|
74
|
+
return this.cache.size;
|
|
75
|
+
}
|
|
76
|
+
/** Clear all cached entries. */
|
|
77
|
+
clear() {
|
|
78
|
+
this.cache.clear();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function sha256(s) {
|
|
82
|
+
return createHash('sha256').update(s, 'utf-8').digest('hex');
|
|
83
|
+
}
|
|
84
|
+
function readMtimeMs(p) {
|
|
85
|
+
try {
|
|
86
|
+
return fs.statSync(p).mtimeMs;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Default `/whoami` fetcher — calls the local server over HTTP using
|
|
94
|
+
* the bearer token + agent-id binding. The `X-Instar-AgentId` header
|
|
95
|
+
* is intentionally omitted on the cache-fill path: the sentinel uses
|
|
96
|
+
* `/whoami` precisely to LEARN the agent id; sending one preemptively
|
|
97
|
+
* would defeat the discovery oracle protection. The server returns 403
|
|
98
|
+
* `agent_id_header_required` if the header is missing, so we instead
|
|
99
|
+
* call this fetcher with the agent-id from config — the sentinel
|
|
100
|
+
* already knows its own agent id from `config.projectName`.
|
|
101
|
+
*
|
|
102
|
+
* Caller passes `agentId` via the `X-Instar-AgentId` header by way of
|
|
103
|
+
* a custom fetchFn override when testing; the default below assumes
|
|
104
|
+
* the agent id is implicit in the cache key. We keep the signature
|
|
105
|
+
* narrow so most call sites don't have to thread it through.
|
|
106
|
+
*/
|
|
107
|
+
async function defaultFetchWhoami(port, token, agentId) {
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
const req = http.request({
|
|
110
|
+
host: '127.0.0.1',
|
|
111
|
+
port,
|
|
112
|
+
path: '/whoami',
|
|
113
|
+
method: 'GET',
|
|
114
|
+
headers: {
|
|
115
|
+
Authorization: `Bearer ${token}`,
|
|
116
|
+
'X-Instar-AgentId': agentId,
|
|
117
|
+
},
|
|
118
|
+
timeout: 5000,
|
|
119
|
+
}, (res) => {
|
|
120
|
+
const chunks = [];
|
|
121
|
+
res.on('data', (c) => chunks.push(c));
|
|
122
|
+
res.on('end', () => {
|
|
123
|
+
const body = Buffer.concat(chunks).toString('utf-8');
|
|
124
|
+
if (res.statusCode !== 200) {
|
|
125
|
+
reject(new Error(`/whoami returned ${res.statusCode}: ${body.slice(0, 256)}`));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(body);
|
|
130
|
+
if (typeof parsed.agentId === 'string' && typeof parsed.port === 'number') {
|
|
131
|
+
resolve({ agentId: parsed.agentId, port: parsed.port });
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
reject(new Error('/whoami response missing agentId or port'));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
reject(new Error(`/whoami response not JSON: ${err instanceof Error ? err.message : err}`));
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
req.on('error', reject);
|
|
143
|
+
req.on('timeout', () => {
|
|
144
|
+
req.destroy(new Error('/whoami request timed out'));
|
|
145
|
+
});
|
|
146
|
+
req.end();
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=whoami-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami-cache.js","sourceRoot":"","sources":["../../src/messaging/whoami-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileCompiler.d.ts","sourceRoot":"","sources":["../../src/moltbridge/ProfileCompiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EACV,iBAAiB,EAEjB,YAAY,EACZ,qBAAqB,EAGtB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ProfileCompiler.d.ts","sourceRoot":"","sources":["../../src/moltbridge/ProfileCompiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EACV,iBAAiB,EAEjB,YAAY,EACZ,qBAAqB,EAGtB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAKD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAIpB;gBAEU,MAAM,EAAE,qBAAqB;IAIzC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;IA4BtC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAMxC;;OAEG;IACH,eAAe,IAAI,YAAY,GAAG,IAAI;IAItC;;OAEG;IACH,aAAa,IAAI,IAAI;IAWrB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB,mDAAmD;IACnD,iBAAiB,IAAI,qBAAqB;IAMpC,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;YAwBpC,WAAW;IAUzB;;;OAGG;YACW,gBAAgB;IAgC9B,OAAO,CAAC,WAAW;IAwCnB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,sBAAsB;YA2ChB,YAAY;IAgD1B,OAAO,CAAC,uBAAuB;IA2B/B,OAAO,CAAC,iBAAiB;CAI1B"}
|