instar 0.28.76 → 0.28.77
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 +306 -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 +35 -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 +91 -0
- package/dist/monitoring/TokenLedger.d.ts.map +1 -0
- package/dist/monitoring/TokenLedger.js +426 -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 +18 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +186 -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 +69 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +528 -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/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 +24 -0
- package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
- package/dist/threadline/ListenerSessionManager.js +38 -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/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/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/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/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-canonical-inbox-write.md +218 -0
- package/upgrades/side-effects/threadline-tg-bridge-settings-surface.md +208 -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
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Side-Effects Review — Threadline Canonical Inbox Write at Relay-Ingest
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `threadline-canonical-inbox-write`
|
|
4
|
+
**Date:** `2026-05-02`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `self (incident-grounded reasoning)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
The threadline relay handler in `src/commands/server.ts` (`gate-passed`
|
|
11
|
+
event listener) had three routing branches — pipe-mode (`PipeSessionSpawner`),
|
|
12
|
+
warm-listener (`ListenerSessionManager.writeToInbox`), and cold-spawn
|
|
13
|
+
(`ThreadlineRouter.handleInboundMessage`). Only the warm-listener branch
|
|
14
|
+
wrote to a per-rotation queue file (`state/listener-inbox-{rotation}.jsonl`);
|
|
15
|
+
none of the three branches wrote to the **canonical** threadline inbox at
|
|
16
|
+
`.instar/threadline/inbox.jsonl.active`. As a result the canonical inbox
|
|
17
|
+
file was frozen since 2026-04-05, hiding ~4 weeks of inbound traffic from
|
|
18
|
+
the dashboard, observability, and any consumer that reads the canonical
|
|
19
|
+
file (e.g. the planned threadline → telegram bridge).
|
|
20
|
+
|
|
21
|
+
This change adds a single canonical-inbox append at relay-ingest, BEFORE
|
|
22
|
+
the pipe / listener / cold-spawn branching, so all three paths agree on
|
|
23
|
+
one source of truth. The hoist runs through a new
|
|
24
|
+
`ListenerSessionManager.appendCanonicalInboxEntry()` helper that writes
|
|
25
|
+
HMAC-signed entries to `threadline/inbox.jsonl.active` using the same
|
|
26
|
+
HKDF-derived signing key the daemon and warm-listener already share —
|
|
27
|
+
no key divergence, no ambient-key footgun.
|
|
28
|
+
|
|
29
|
+
Files modified:
|
|
30
|
+
|
|
31
|
+
- `src/threadline/ListenerSessionManager.ts` — adds
|
|
32
|
+
`canonicalInboxPath` getter and `appendCanonicalInboxEntry(opts)` method.
|
|
33
|
+
The new method writes to the canonical inbox path; it does NOT write
|
|
34
|
+
the wake sentinel (the warm-listener queue and its sentinel remain a
|
|
35
|
+
separate, listener-only concern).
|
|
36
|
+
- `src/commands/server.ts` — in the `gate-passed` event handler, after
|
|
37
|
+
auto-ack and BEFORE the pipe / listener / cold-spawn branching, calls
|
|
38
|
+
`listenerManager.appendCanonicalInboxEntry({ ... })` once. Wrapped in
|
|
39
|
+
try/catch with a non-fatal warn — routing continues even if the
|
|
40
|
+
canonical append fails, preserving message liveness over auditability.
|
|
41
|
+
|
|
42
|
+
Tests added: 6 new unit cases in
|
|
43
|
+
`tests/unit/ListenerSessionManager.test.ts > canonical inbox`:
|
|
44
|
+
|
|
45
|
+
1. `canonicalInboxPath` getter returns `threadline/inbox.jsonl.active`
|
|
46
|
+
2. `appendCanonicalInboxEntry` creates the directory on first write and
|
|
47
|
+
appends a parseable JSON line with the right fields
|
|
48
|
+
3. The HMAC of a canonical entry round-trips through the existing
|
|
49
|
+
`verifyEntry()` — proves daemon/listener/relay share one signing key
|
|
50
|
+
4. Multiple appends produce multiple lines in chronological order
|
|
51
|
+
5. An optional caller-supplied `messageId` is honored as the entry id
|
|
52
|
+
6. The canonical inbox file is created with `0o600` permissions
|
|
53
|
+
|
|
54
|
+
Local result: 45/46 pass; the 1 failing case
|
|
55
|
+
(`state management > starts in dead state`) is a pre-existing failure
|
|
56
|
+
documented in prior `instar-dev` traces (e.g.
|
|
57
|
+
`2026-04-27T15-50-00Z-telegram-delivery-robustness-layer-3.json`) and
|
|
58
|
+
unrelated to this change.
|
|
59
|
+
|
|
60
|
+
## Decision-point inventory
|
|
61
|
+
|
|
62
|
+
- `ListenerSessionManager.appendCanonicalInboxEntry` — **add** — pure
|
|
63
|
+
canonical-inbox append, no wake sentinel.
|
|
64
|
+
- `ListenerSessionManager.canonicalInboxPath` — **add** — getter for the
|
|
65
|
+
canonical inbox path, kept side-by-side with `inboxPath` (warm-listener
|
|
66
|
+
queue) so the two roles are visibly distinct in the API surface.
|
|
67
|
+
- `gate-passed` handler in `server.ts` — **modify** — runs canonical
|
|
68
|
+
append once, before any branching. No change to pipe-mode, warm-listener,
|
|
69
|
+
or cold-spawn routing decisions or behavior.
|
|
70
|
+
- HMAC key — **pass-through** — the new helper uses the same HKDF-derived
|
|
71
|
+
signing key (`info: 'instar-inbox-signing'`) that
|
|
72
|
+
`writeToInbox` and the listener daemon already use; no new key, no new
|
|
73
|
+
derivation parameter.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 1. Over-block
|
|
78
|
+
|
|
79
|
+
**What legitimate inputs does this change reject that it shouldn't?**
|
|
80
|
+
|
|
81
|
+
None. The hoist is a relay (write-only), not a gate. It does not block,
|
|
82
|
+
delay, or filter messages. Routing decisions — pipe vs warm vs cold-spawn —
|
|
83
|
+
are unchanged. Auto-ack timing is unchanged. The canonical write happens
|
|
84
|
+
synchronously in the same event handler, on the same Node.js event loop,
|
|
85
|
+
adding a single `appendFileSync` call — no I/O contention with the routing
|
|
86
|
+
branches that follow.
|
|
87
|
+
|
|
88
|
+
The append is wrapped in try/catch with a non-fatal warning. If the
|
|
89
|
+
canonical write fails (disk full, permission error, etc.), the message
|
|
90
|
+
still routes through pipe / listener / cold-spawn as it does today.
|
|
91
|
+
Liveness is preserved over auditability when those two are in tension.
|
|
92
|
+
|
|
93
|
+
## 2. Under-block
|
|
94
|
+
|
|
95
|
+
**What failure modes does this still miss?**
|
|
96
|
+
|
|
97
|
+
- **Failure-open on canonical-inbox write.** A disk error during
|
|
98
|
+
`appendFileSync` produces a single warn line and the message routes
|
|
99
|
+
normally. The canonical inbox loses that entry. Acceptable: the same
|
|
100
|
+
behavior is already in place for the warm-listener `writeToInbox` and
|
|
101
|
+
for the daemon's `writeInboxEntry` — none of them block routing on
|
|
102
|
+
inbox-write failure. The canonical inbox is an audit / observability
|
|
103
|
+
surface, not a gate.
|
|
104
|
+
- **Pre-existing freeze (Apr 5 → May 1).** Backfilling the missing
|
|
105
|
+
~4 weeks of inbound messages is OUT OF SCOPE for this PR — that's
|
|
106
|
+
deliverable (c) in the topic-8686 build (separate PR, separate review).
|
|
107
|
+
This PR fixes the write-path going forward; (c) reconstructs the
|
|
108
|
+
history from spawn-session transcripts and the thread-resume map.
|
|
109
|
+
- **Listener daemon path (`listener-daemon.ts`) still bypasses this code
|
|
110
|
+
path.** The daemon connects to the relay independently and has its own
|
|
111
|
+
`writeInboxEntry` that already targets the canonical file. This PR
|
|
112
|
+
does NOT alter the daemon. When the daemon is the active relay
|
|
113
|
+
consumer, it continues to write canonically as it does today; when the
|
|
114
|
+
in-process relay client (server.ts handler) is the consumer, the new
|
|
115
|
+
hoist takes care of canonical writes. Both paths converge on the same
|
|
116
|
+
file with the same HMAC key.
|
|
117
|
+
|
|
118
|
+
## 3. Level-of-abstraction fit
|
|
119
|
+
|
|
120
|
+
**Is this at the right layer?**
|
|
121
|
+
|
|
122
|
+
Yes. The relay handler is the natural choke point: it is the single
|
|
123
|
+
function in the in-process relay consumer that sees every inbound
|
|
124
|
+
message exactly once before any routing decision. Doing the canonical
|
|
125
|
+
write here — rather than inside each routing branch — is the
|
|
126
|
+
single-source-of-truth pattern the spec calls for.
|
|
127
|
+
|
|
128
|
+
The helper lives on `ListenerSessionManager` because that class already
|
|
129
|
+
owns the HMAC key derivation and the existing `writeToInbox` + `verifyEntry`
|
|
130
|
+
methods. Adding a sibling method that targets the canonical path keeps
|
|
131
|
+
the key derivation, HMAC computation, and entry shape in one place.
|
|
132
|
+
A future refactor could extract a separate `CanonicalInboxWriter` class,
|
|
133
|
+
but the cost-of-now (one new method, ~30 LoC, one new getter) is lower
|
|
134
|
+
than the cost-of-extraction (new class, dependency wiring, test scaffolding).
|
|
135
|
+
|
|
136
|
+
## 4. Signal-vs-authority compliance
|
|
137
|
+
|
|
138
|
+
**Where is the signal? Where is the authority?**
|
|
139
|
+
|
|
140
|
+
- **Signal:** the inbound `gate-passed` event itself, which has already
|
|
141
|
+
been authorized by `InboundMessageGate`. The canonical append is a
|
|
142
|
+
pure observation of that signal — write-once, append-only, no decision
|
|
143
|
+
surface.
|
|
144
|
+
- **Authority:** unchanged. The pipe / warm-listener / cold-spawn
|
|
145
|
+
routing decision still lives in `server.ts` (and downstream in
|
|
146
|
+
`PipeSessionSpawner.shouldUsePipeMode`, `ListenerSessionManager.shouldUseListener`,
|
|
147
|
+
`ThreadlineRouter.handleInboundMessage`). The canonical inbox does not
|
|
148
|
+
gate, throttle, or veto routing.
|
|
149
|
+
|
|
150
|
+
The split passes the signal-vs-authority memory test: a brittle/low-context
|
|
151
|
+
write path (the canonical append) emits a signal; the higher-level
|
|
152
|
+
intelligent gate (already-existing `InboundMessageGate` upstream of the
|
|
153
|
+
`gate-passed` event) holds the blocking authority.
|
|
154
|
+
|
|
155
|
+
## 5. Interactions
|
|
156
|
+
|
|
157
|
+
**What other systems does this touch?**
|
|
158
|
+
|
|
159
|
+
- **Warm-listener queue (`state/listener-inbox-{rotation}.jsonl`).** No
|
|
160
|
+
change. The warm-listener path still calls `writeToInbox` which writes
|
|
161
|
+
to the rotated per-listener file AND the wake sentinel. Both files
|
|
162
|
+
coexist: canonical = audit/observability/bridge source; rotated =
|
|
163
|
+
warm-listener queue.
|
|
164
|
+
- **Listener daemon (`listener-daemon.ts`).** No change. The daemon's
|
|
165
|
+
`writeInboxEntry` already targets the canonical file. After this PR,
|
|
166
|
+
there are exactly two writers to the canonical file — the daemon (for
|
|
167
|
+
the standalone-listener mode) and the in-process relay handler (for
|
|
168
|
+
the in-server mode). They are mutually exclusive at runtime: only one
|
|
169
|
+
is the active relay consumer at a time.
|
|
170
|
+
- **Threadline → Telegram bridge (deliverable b, future PR).** This PR
|
|
171
|
+
is a precondition. The bridge reads the canonical inbox to know which
|
|
172
|
+
messages to mirror into Telegram; without this fix, the bridge would
|
|
173
|
+
see no traffic on the cold-spawn or pipe paths. After this PR the
|
|
174
|
+
bridge has a complete signal stream.
|
|
175
|
+
- **Dashboard observability tab (deliverable 4, future PR).** Same: the
|
|
176
|
+
observability tab reads the canonical inbox and the thread-resume map.
|
|
177
|
+
This PR ensures the canonical inbox is actually populated.
|
|
178
|
+
|
|
179
|
+
## 6. Rollback cost
|
|
180
|
+
|
|
181
|
+
**How easy is it to undo this if it breaks something in production?**
|
|
182
|
+
|
|
183
|
+
Trivially easy. The change is two surgical additions:
|
|
184
|
+
|
|
185
|
+
1. A new method + getter on `ListenerSessionManager` (no callers in
|
|
186
|
+
tests or production reference it except the new test file and the
|
|
187
|
+
new `server.ts` call site).
|
|
188
|
+
2. A 13-line block in `server.ts` that is fully wrapped in `if (listenerManager)`
|
|
189
|
+
and `try/catch`. Removing that block restores the prior behavior
|
|
190
|
+
exactly.
|
|
191
|
+
|
|
192
|
+
No schema migrations, no new file format, no new key material, no
|
|
193
|
+
dashboard changes. The canonical inbox file is append-only JSONL — if a
|
|
194
|
+
subsequent change wants to drop the entries, `rm` the file (or rotate
|
|
195
|
+
it). No referential integrity to unwind.
|
|
196
|
+
|
|
197
|
+
## Plan if a regression appears
|
|
198
|
+
|
|
199
|
+
- **Symptom: routing latency increases.** Profile the `appendFileSync`
|
|
200
|
+
call. The canonical inbox is local-filesystem JSONL; on macOS APFS
|
|
201
|
+
/ ext4 / xfs the syscall is sub-millisecond. If unexpectedly slow,
|
|
202
|
+
hoist into a `setImmediate` so the routing branches run first.
|
|
203
|
+
- **Symptom: canonical inbox file grows unboundedly.** Same growth rate
|
|
204
|
+
as the warm-listener queue's rotation cycle — so we already know the
|
|
205
|
+
steady-state. If growth is a problem, add a rotation policy mirroring
|
|
206
|
+
the listener's (compaction at N messages, archive on rotation).
|
|
207
|
+
- **Symptom: HMAC verification fails for canonical entries.** The signing
|
|
208
|
+
key comes from the same HKDF derivation as `writeToInbox` and
|
|
209
|
+
`loadSigningKey` — verified by the round-trip unit test. If a real
|
|
210
|
+
failure shows up, look for an authToken mismatch between processes.
|
|
211
|
+
|
|
212
|
+
## Phase / scope
|
|
213
|
+
|
|
214
|
+
This is the FIRST of five deliverables in topic-8686 (Threadline → Telegram
|
|
215
|
+
Bridge). Subsequent deliverables — dashboard settings, bridge module,
|
|
216
|
+
observability tab, and four-thread backfill — depend on this canonical
|
|
217
|
+
write-path being live. Each will ship as its own PR with its own
|
|
218
|
+
side-effects review.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Side-Effects Review — Threadline → Telegram Bridge: Settings Surface
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `threadline-tg-bridge-settings-surface`
|
|
4
|
+
**Date:** `2026-05-02`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `self (incident-grounded reasoning)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Ships the **settings surface** for the Threadline → Telegram bridge BEFORE
|
|
11
|
+
the bridge module itself (deliverable b) goes live. This is the second of
|
|
12
|
+
five deliverables in the topic-8686 build; it ensures default-OFF
|
|
13
|
+
auto-create is structurally enforced from day one, so when (b) lights up
|
|
14
|
+
the bridge, the user's noise budget is already wired and respected.
|
|
15
|
+
|
|
16
|
+
The settings surface is three layers:
|
|
17
|
+
|
|
18
|
+
1. **`TelegramBridgeConfig` class** — a thin, validated read/write API over
|
|
19
|
+
`LiveConfig` keys under `threadline.telegramBridge.*`. Owns the policy
|
|
20
|
+
functions `shouldAutoCreateTopic(remoteAgent)` and
|
|
21
|
+
`shouldMirrorIntoExistingTopic()` that the bridge module will call on
|
|
22
|
+
every inbound/outbound message.
|
|
23
|
+
2. **HTTP endpoints** — `GET /threadline/telegram-bridge/config` and
|
|
24
|
+
`PATCH /threadline/telegram-bridge/config`, mounted in the main route
|
|
25
|
+
set (bearer-auth enforced globally). Validation lives in the config
|
|
26
|
+
class; the route handler is a 14-line wrapper.
|
|
27
|
+
3. **Dashboard tab** — a new "Threadline" tab with a Bridge Settings card:
|
|
28
|
+
master switch, two policy toggles, and dual allow/deny-list management.
|
|
29
|
+
The same tab is the natural home for deliverable (4)'s observability
|
|
30
|
+
view; this PR ships a placeholder noting that.
|
|
31
|
+
|
|
32
|
+
Files added:
|
|
33
|
+
|
|
34
|
+
- `src/threadline/TelegramBridgeConfig.ts` — config class + `shouldAutoCreateTopic`, `shouldMirrorIntoExistingTopic` policies.
|
|
35
|
+
- `tests/unit/TelegramBridgeConfig.test.ts` — 22 unit cases.
|
|
36
|
+
- `tests/integration/telegram-bridge-config-routes.test.ts` — 8 supertest cases.
|
|
37
|
+
|
|
38
|
+
Files modified:
|
|
39
|
+
|
|
40
|
+
- `src/server/routes.ts` — `RouteContext.telegramBridgeConfig: TelegramBridgeConfig | null` + two routes.
|
|
41
|
+
- `src/server/AgentServer.ts` — accepts `options.telegramBridgeConfig`, passes through `routeCtx`.
|
|
42
|
+
- `src/commands/server.ts` — instantiates `new TelegramBridgeConfig(liveConfig)` once at boot, hands it to `AgentServer`.
|
|
43
|
+
- `dashboard/index.html` — new Threadline tab (button + panel + load/patch/render JS + tab-registry entry).
|
|
44
|
+
|
|
45
|
+
## Decision-point inventory
|
|
46
|
+
|
|
47
|
+
- `TelegramBridgeConfig.update(patch)` — **add** — partial-patch
|
|
48
|
+
application with type validation; emits `change` events per field.
|
|
49
|
+
- `TelegramBridgeConfig.shouldAutoCreateTopic(remoteAgent)` — **add** —
|
|
50
|
+
policy: `enabled && (allowList match → true; denyList match → false; else autoCreateTopics)`.
|
|
51
|
+
- `TelegramBridgeConfig.shouldMirrorIntoExistingTopic()` — **add** —
|
|
52
|
+
policy: `enabled && mirrorExisting`.
|
|
53
|
+
- `GET /threadline/telegram-bridge/config` — **add** — read endpoint
|
|
54
|
+
(bearer-auth via global `authMiddleware`).
|
|
55
|
+
- `PATCH /threadline/telegram-bridge/config` — **add** — partial-patch
|
|
56
|
+
endpoint with 400 on validation error and 503 when config not initialized.
|
|
57
|
+
- Dashboard `loadThreadlineBridgeConfig` / `tlBridgePatchConfig` — **add** —
|
|
58
|
+
load + optimistic write; rolls back via re-load on 4xx.
|
|
59
|
+
- Toggle change-handlers — **add** — bound once on `DOMContentLoaded` with
|
|
60
|
+
a `tlBridgeWiring` reentrancy guard (avoids feeding back the
|
|
61
|
+
programmatic `checked = ...` set into the change event).
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 1. Over-block
|
|
66
|
+
|
|
67
|
+
**What legitimate inputs does this change reject that it shouldn't?**
|
|
68
|
+
|
|
69
|
+
The settings class deliberately rejects non-boolean toggles and non-string
|
|
70
|
+
list entries with a 400. The error messages name the offending field
|
|
71
|
+
("enabled must be boolean", "allowList must be string[]"). False positives
|
|
72
|
+
are not possible at the type level: a JSON `true`/`false` is unambiguous,
|
|
73
|
+
and a JSON array of strings is unambiguous. The dashboard cannot send
|
|
74
|
+
malformed input — `<input type="checkbox">.checked` is always a boolean
|
|
75
|
+
and the list-management code stringifies entries.
|
|
76
|
+
|
|
77
|
+
The PATCH endpoint **ignores unknown fields silently** (the route filters
|
|
78
|
+
the body to known fields before forwarding to `update`). This is
|
|
79
|
+
intentional: future toggles can be deployed server-side without breaking
|
|
80
|
+
older dashboards that don't know about them. There is a unit test for
|
|
81
|
+
this exact behaviour.
|
|
82
|
+
|
|
83
|
+
## 2. Under-block
|
|
84
|
+
|
|
85
|
+
**What failure modes does this still miss?**
|
|
86
|
+
|
|
87
|
+
- **No rate-limit on PATCH.** A pathological dashboard could thrash
|
|
88
|
+
toggles. The cost is bounded — each PATCH writes config.json
|
|
89
|
+
atomically; throughput is disk-bound, not unbounded. Acceptable for a
|
|
90
|
+
bearer-auth-gated endpoint with one user.
|
|
91
|
+
- **No audit log on config changes.** A future PR could forward the
|
|
92
|
+
`change` events from `TelegramBridgeConfig` into the existing event
|
|
93
|
+
stream, but it's out of scope for this deliverable. Today, config
|
|
94
|
+
changes show up in `config.json` git history (or backup snapshots).
|
|
95
|
+
- **The `enabled` master switch is still load-bearing for the bridge
|
|
96
|
+
module that doesn't exist yet.** This PR does NOT enforce default-OFF
|
|
97
|
+
in any code path that mirrors messages — it only persists the toggles.
|
|
98
|
+
Enforcement happens in deliverable (b), where the bridge module calls
|
|
99
|
+
`shouldAutoCreateTopic` and `shouldMirrorIntoExistingTopic` at every
|
|
100
|
+
routing decision. The unit tests for those two functions in this PR
|
|
101
|
+
pin the policy contract so (b) cannot drift.
|
|
102
|
+
- **Validation does not deduplicate trailing-whitespace in arbitrary
|
|
103
|
+
Unicode whitespace.** `dedupeAndTrim` uses `.trim()` (ASCII whitespace
|
|
104
|
+
+ Unicode whitespace per ECMAScript). Acceptable.
|
|
105
|
+
|
|
106
|
+
## 3. Level-of-abstraction fit
|
|
107
|
+
|
|
108
|
+
**Is this at the right layer?**
|
|
109
|
+
|
|
110
|
+
Yes. The split between class (validation + policy), routes (thin HTTP
|
|
111
|
+
shim), and dashboard (presentation only) is the standard
|
|
112
|
+
"signal-vs-authority" shape: brittle low-context surfaces (the dashboard
|
|
113
|
+
checkboxes) emit signals; the higher-level intelligent gate
|
|
114
|
+
(`TelegramBridgeConfig.update` + the policy functions) holds the
|
|
115
|
+
blocking authority.
|
|
116
|
+
|
|
117
|
+
The settings class lives under `src/threadline/` because it's a
|
|
118
|
+
threadline-specific feature; placing it in `src/config/` would conflate
|
|
119
|
+
it with the generic `LiveConfig`. The bridge module in deliverable (b)
|
|
120
|
+
will instantiate this class — it does NOT instantiate `LiveConfig`
|
|
121
|
+
directly, which keeps key naming centralized.
|
|
122
|
+
|
|
123
|
+
## 4. Signal-vs-authority compliance
|
|
124
|
+
|
|
125
|
+
- **Signal:** dashboard checkbox toggles, dashboard list inputs, REST
|
|
126
|
+
PATCH bodies. Each is a low-context request that "wants" something to
|
|
127
|
+
change.
|
|
128
|
+
- **Authority:** `TelegramBridgeConfig.update` is the single chokepoint
|
|
129
|
+
that validates types, dedupes lists, and writes to config.json. The
|
|
130
|
+
bridge module (b) will read its decisions through `shouldAutoCreateTopic`
|
|
131
|
+
and `shouldMirrorIntoExistingTopic` — both pure functions of the
|
|
132
|
+
current settings.
|
|
133
|
+
|
|
134
|
+
The bridge module itself, when it ships, will be **relay-only** (no
|
|
135
|
+
block/allow surface). The blocking authority for noise control lives
|
|
136
|
+
exactly here, in the config policy. This separation is the
|
|
137
|
+
signal-vs-authority memory pattern applied correctly: the bridge
|
|
138
|
+
forwards messages it sees; the config class decides what gets seen.
|
|
139
|
+
|
|
140
|
+
## 5. Interactions
|
|
141
|
+
|
|
142
|
+
- **`LiveConfig`.** All reads and writes go through the existing
|
|
143
|
+
`LiveConfig.get` / `.set` API. No new file format, no new mtime
|
|
144
|
+
watcher, no new poll. Atomic write semantics are inherited.
|
|
145
|
+
- **`config.json` schema.** The new keys `threadline.telegramBridge.*`
|
|
146
|
+
are namespaced under the existing `threadline` block. Older agents
|
|
147
|
+
without these keys read the documented defaults (defined in
|
|
148
|
+
`DEFAULT_TELEGRAM_BRIDGE_SETTINGS`). No migration needed.
|
|
149
|
+
- **Bridge module (deliverable b, future PR).** Will instantiate
|
|
150
|
+
`TelegramBridgeConfig` from `liveConfig` and call the policy functions.
|
|
151
|
+
This PR pins the contract via unit tests so (b) cannot accidentally
|
|
152
|
+
deliver while `enabled=false` or while a remote agent is in the deny
|
|
153
|
+
list.
|
|
154
|
+
- **Observability tab (deliverable 4, future PR).** Will share the same
|
|
155
|
+
Threadline dashboard tab and extend the panel HTML; the bridge
|
|
156
|
+
settings card stays put.
|
|
157
|
+
- **Bearer-auth via `authMiddleware`.** Both routes are
|
|
158
|
+
globally-authenticated. No change to auth wiring.
|
|
159
|
+
|
|
160
|
+
## 6. Rollback cost
|
|
161
|
+
|
|
162
|
+
**How easy is it to undo this if it breaks something in production?**
|
|
163
|
+
|
|
164
|
+
Trivially. The change is purely additive:
|
|
165
|
+
|
|
166
|
+
- Drop the new `TelegramBridgeConfig` class file → no callers in
|
|
167
|
+
production code (only the new server.ts instantiation + the new
|
|
168
|
+
routes use it).
|
|
169
|
+
- Drop the two routes → unauthenticated GET still 503's elsewhere; the
|
|
170
|
+
dashboard tab silently fails on `loadThreadlineBridgeConfig`.
|
|
171
|
+
- Drop the dashboard tab + JS → no regression elsewhere; other tabs
|
|
172
|
+
unaffected.
|
|
173
|
+
- The new `config.json` keys are silently ignored by older agents — no
|
|
174
|
+
schema migration to unwind.
|
|
175
|
+
|
|
176
|
+
No file format changes, no shared-state changes, no new processes, no
|
|
177
|
+
new sockets. The PR is a pure "API + UI for not-yet-shipped feature"
|
|
178
|
+
shape — the safest possible kind of change.
|
|
179
|
+
|
|
180
|
+
## Plan if a regression appears
|
|
181
|
+
|
|
182
|
+
- **Symptom: dashboard tab errors.** Check `apiFetch` logs in the browser
|
|
183
|
+
console; verify the bridge config endpoints return 200 from the agent
|
|
184
|
+
server; verify auth token is correct.
|
|
185
|
+
- **Symptom: toggle change feeds back into a loop.** The
|
|
186
|
+
`tlBridgeWiring` reentrancy guard skips the change handler while
|
|
187
|
+
`renderThreadlineBridgeConfig` is programmatically setting `.checked`.
|
|
188
|
+
If a regression escapes the guard, log the toggle source — DOM
|
|
189
|
+
`change` events are synchronous, so the guard works as long as the
|
|
190
|
+
programmatic set is followed by `tlBridgeWiring = false` in a
|
|
191
|
+
`try/finally`.
|
|
192
|
+
- **Symptom: config.json gets a stray key.** The `update` method only
|
|
193
|
+
writes the five known keys; no caller has a path to write something
|
|
194
|
+
else. If junk appears, suspect manual editing.
|
|
195
|
+
|
|
196
|
+
## Phase / scope
|
|
197
|
+
|
|
198
|
+
Second of five deliverables in topic-8686. Order:
|
|
199
|
+
|
|
200
|
+
1. (a) Canonical inbox write-path fix — **MERGED** as PR #113 (commit `9cc3e9af`).
|
|
201
|
+
2. **(2) Settings surface — THIS PR.** Default-OFF auto-create, allow/deny list, dashboard tab.
|
|
202
|
+
3. (b) Bridge module — reads this config, mirrors threadline messages.
|
|
203
|
+
4. (4) Observability tab — extends the Threadline dashboard tab.
|
|
204
|
+
5. (c) Backfill four open threads — one-shot script.
|
|
205
|
+
|
|
206
|
+
Subsequent deliverables (b, 4, c) all depend on this settings contract.
|
|
207
|
+
The 22 unit tests + 8 integration tests pin the contract so they cannot
|
|
208
|
+
drift as the bridge module is built.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Side-Effects Review — Token Ledger (Phase 1, read-only observability)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `token-ledger-phase1`
|
|
4
|
+
**Date:** 2026-04-29
|
|
5
|
+
**Author:** echo
|
|
6
|
+
**Second-pass reviewer:** not required (no decision points; see Q4)
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Adds a read-only token-usage ledger as a core instar feature. Every agent now tails Claude Code's per-session JSONL files at `~/.claude/projects/<encoded-cwd>/<session-uuid>.jsonl`, parses each `assistant` line's `message.usage` block, and records token counts to a SQLite DB at `<stateDir>/server-data/token-ledger.db`. Four new GET endpoints (`/tokens/summary`, `/tokens/sessions`, `/tokens/by-project`, `/tokens/orphans`) expose rollups, and a new "Tokens" dashboard tab renders the data.
|
|
11
|
+
|
|
12
|
+
Files touched:
|
|
13
|
+
- `src/monitoring/TokenLedger.ts` (new) — SQLite schema + ingest + query methods
|
|
14
|
+
- `src/monitoring/TokenLedgerPoller.ts` (new) — 60s tick wrapping `scanAll()`
|
|
15
|
+
- `src/server/AgentServer.ts` — wires ledger into route context, starts/stops the poller
|
|
16
|
+
- `src/server/routes.ts` — adds the four GET endpoints under existing auth middleware
|
|
17
|
+
- `dashboard/index.html` — adds "Tokens" tab
|
|
18
|
+
- `tests/unit/token-ledger.test.ts` (new) — 12 unit tests
|
|
19
|
+
|
|
20
|
+
The change interacts with no decision points. The ledger does not gate, block, filter, or alter any agent behavior; it is pure observability.
|
|
21
|
+
|
|
22
|
+
## Decision-point inventory
|
|
23
|
+
|
|
24
|
+
The change has no decision-point surface. There is no block/allow logic, no message filtering, no session-lifecycle mutation, no dispatcher, sentinel, gate, or watchdog. The "orphans" endpoint returns a list of idle sessions as data — it does not act on them.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. Over-block
|
|
29
|
+
|
|
30
|
+
No block/allow surface — over-block not applicable.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 2. Under-block
|
|
35
|
+
|
|
36
|
+
No block/allow surface — under-block not applicable.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 3. Level-of-abstraction fit
|
|
41
|
+
|
|
42
|
+
This is observability infrastructure, not a decision point. It belongs at the same layer as other monitors in `src/monitoring/` (e.g. `QuotaTracker`, `TelemetryCollector`). It does not duplicate any existing primitive: there is no other instar feature reading Claude Code's per-call JSONL token data — `QuotaTracker` reads a separately-written quota state file, which is a different signal (account-level limit usage) at a different cadence.
|
|
43
|
+
|
|
44
|
+
The dashboard tab piggybacks on existing `TAB_REGISTRY` + `apiFetch` patterns rather than introducing a new framework. Storage uses the existing `<stateDir>/server-data/<name>.db` convention established by `StopGateDb`.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 4. Signal vs authority compliance
|
|
49
|
+
|
|
50
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
51
|
+
|
|
52
|
+
- [x] No — this change has no block/allow surface.
|
|
53
|
+
|
|
54
|
+
The ledger is pure read-side observability. Every output is data-for-the-user, never an automated decision. The "orphans" view is explicitly a *signal* (here are sessions idle > N minutes) with no authority to act on the signal. Any future kill-orphan automation, budget enforcement, or compaction trigger would be a separate change with its own review — and per the principle, the orphan list would feed an LLM-backed authority, not become its own brittle blocker.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 5. Interactions
|
|
59
|
+
|
|
60
|
+
- **Shadowing:** None. The ledger reads files Claude Code writes; it does not stand in front of any existing read path. The new routes are under `/tokens/*` — a fresh prefix, no overlap with existing routes.
|
|
61
|
+
- **Double-fire:** None. The poller has a reentry guard (skips a tick if the previous one is still running). Multiple agents on one machine each maintain their own ledger DB under their own state dir, so they don't race on the SQLite file. They DO each scan the same `~/.claude/projects/` tree, but they only read it; the source files are never mutated.
|
|
62
|
+
- **Races:** The ledger writes only to its own DB. `INSERT OR IGNORE` on `request_id` makes ingest idempotent, so even if a file is partially read by one tick and re-read by the next (offset semantics), no double-counting can occur. File-rotation handling resets offset when inode changes.
|
|
63
|
+
- **Feedback loops:** None. The ledger is downstream of Claude Code's logging; it cannot influence what gets logged. It does not call any LLM, does not emit messages, does not write to any path Claude Code reads.
|
|
64
|
+
|
|
65
|
+
One subtle interaction worth naming: per-line ingest uses an explicit `BEGIN`/`COMMIT` per file. If the process is killed mid-file, the offset for that file is not advanced, so on next startup the file will be re-read from the prior offset — `INSERT OR IGNORE` makes that safe. Verified by the offset-resume test.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 6. External surfaces
|
|
70
|
+
|
|
71
|
+
- **Other agents on the same machine:** No effect on their behavior. They each gain the same ledger feature when they upgrade. Each agent's DB lives under its own `<stateDir>/server-data/`, so no cross-agent file contention.
|
|
72
|
+
- **Other users of the install base:** Pure additive feature. No existing API contracts changed. Dashboard gains a new tab; existing tabs unchanged.
|
|
73
|
+
- **External systems:** None. No outbound network calls. No Telegram, Slack, GitHub, or Cloudflare interaction.
|
|
74
|
+
- **Persistent state:** New SQLite DB at `<stateDir>/server-data/token-ledger.db`. Auto-created on first boot. No migration needed for existing installs (the DB simply doesn't exist yet and is created on upgrade). The file can be deleted at any time without affecting agent operation — it will be rebuilt by next scan from the source JSONLs (which are themselves the ground truth).
|
|
75
|
+
- **Timing/runtime:** The poller runs every 60s. Each tick performs file I/O proportional to JSONL bytes written since last tick (typically tens of KB/min on a busy agent). SQLite operations are local and bounded. No LLM calls in the hot path. Verified to be cheap by manual sizing — a busy session writes ~1 line per turn, and parsing+inserting one line is microseconds.
|
|
76
|
+
|
|
77
|
+
The reader is **strictly read-only against `~/.claude/projects/`**. It never opens those files for write. Confirmed by code review of `ingestFile()` — only `fs.openSync(path, 'r')` and `fs.readSync` are used.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 7. Rollback cost
|
|
82
|
+
|
|
83
|
+
Pure additive code change. Rollback steps:
|
|
84
|
+
|
|
85
|
+
1. Revert the commit. Ship as next patch release.
|
|
86
|
+
2. The token-ledger DB file at `<stateDir>/server-data/token-ledger.db` becomes orphaned. Safe to ignore — it doesn't affect agent operation. Cleanup is optional (`rm` the file).
|
|
87
|
+
3. No agent state repair needed. No user-visible regression — the dashboard tab disappears, the four endpoints 404. No other behavior changes.
|
|
88
|
+
4. No data migration. No persistent format outside the isolated DB.
|
|
89
|
+
|
|
90
|
+
Estimated rollback time: minutes. Pure code revert.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Conclusion
|
|
95
|
+
|
|
96
|
+
This change is read-only observability with no decision-point surface, no external network calls, and no interaction with existing message-flow gates. It follows the established `src/monitoring/` pattern for collectors and the `<stateDir>/server-data/` convention for SQLite storage. The signal-vs-authority principle is preserved by design: the ledger never holds blocking authority, and the "orphans" view is explicitly a signal that any future kill-orphan automation would feed into a smart gate rather than acting on directly.
|
|
97
|
+
|
|
98
|
+
The change is clear to ship.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Second-pass review (if required)
|
|
103
|
+
|
|
104
|
+
Not required. This change does not touch any of the trigger criteria from the skill (block/allow on messaging or dispatch, session lifecycle, context exhaustion/compaction, coherence/idempotency/trust, sentinel/guard/gate/watchdog).
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Follow-up fix (2026-04-29, post-CI)
|
|
109
|
+
|
|
110
|
+
CI surfaced a Linux-specific failure in the inode-rotation test: Linux can reuse the same inode number when a file is unlinked and immediately recreated (tmpfs/ext4 behavior). On macOS (where the implementation was first tested) the inode always differs, so the issue was invisible locally.
|
|
111
|
+
|
|
112
|
+
**Fix:** added a 256-byte content fingerprint (`head_hash` column) to `file_offsets`. Rotation is now detected by `(inode change) OR (head_hash change)`, which is robust across both filesystems. Schema migration is idempotent (`ALTER TABLE … ADD COLUMN` is wrapped in a "duplicate column" swallow).
|
|
113
|
+
|
|
114
|
+
This change is internal to the ledger and does not affect any of the seven side-effects review answers above. Specifically:
|
|
115
|
+
- No new decision-point surface (still pure observability).
|
|
116
|
+
- No new external surfaces.
|
|
117
|
+
- Rollback cost unchanged — pure code revert; the extra column is harmless if left in place.
|
|
118
|
+
|
|
119
|
+
## Evidence pointers
|
|
120
|
+
|
|
121
|
+
- Unit tests: `tests/unit/token-ledger.test.ts` — 12/12 passing locally on `token-ledger-phase1` branch.
|
|
122
|
+
- Typecheck: `npm run lint` clean (tsc --noEmit + lint-no-direct-destructive both pass).
|
|
123
|
+
- JSONL shape verified against real samples in `~/.claude/projects/-Users-justin-Documents-Projects-ai-guy/` before implementation.
|
package/upgrades/NEXT.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Upgrade Guide — vNEXT
|
|
2
|
-
|
|
3
|
-
<!-- bump: patch -->
|
|
4
|
-
<!-- Valid values: patch, minor, major -->
|
|
5
|
-
<!-- patch = bug fixes, refactors, test additions, doc updates -->
|
|
6
|
-
<!-- minor = new features, new APIs, new capabilities (backwards-compatible) -->
|
|
7
|
-
<!-- major = breaking changes to existing APIs or behavior -->
|
|
8
|
-
|
|
9
|
-
## What Changed
|
|
10
|
-
|
|
11
|
-
<!-- Describe what changed technically. What new features, APIs, behavioral changes? -->
|
|
12
|
-
<!-- Write this for the AGENT — they need to understand the system deeply. -->
|
|
13
|
-
|
|
14
|
-
## What to Tell Your User
|
|
15
|
-
|
|
16
|
-
<!-- Write talking points the agent should relay to their user. -->
|
|
17
|
-
<!-- This should be warm, conversational, user-facing — not a changelog. -->
|
|
18
|
-
<!-- Focus on what THEY can now do, not internal plumbing. -->
|
|
19
|
-
<!-- -->
|
|
20
|
-
<!-- PROHIBITED in this section (will fail validation): -->
|
|
21
|
-
<!-- camelCase config keys: silentReject, maxRetries, telegramNotify -->
|
|
22
|
-
<!-- Inline code backtick references like silentReject: false -->
|
|
23
|
-
<!-- Fenced code blocks -->
|
|
24
|
-
<!-- Instructions to edit files or run commands -->
|
|
25
|
-
<!-- -->
|
|
26
|
-
<!-- CORRECT style: "I can turn that on for you" not "set X to false" -->
|
|
27
|
-
<!-- The agent relays this to their user — keep it human. -->
|
|
28
|
-
|
|
29
|
-
- **[Feature name]**: "[Brief, friendly description of what this means for the user]"
|
|
30
|
-
|
|
31
|
-
## Summary of New Capabilities
|
|
32
|
-
|
|
33
|
-
| Capability | How to Use |
|
|
34
|
-
|-----------|-----------|
|
|
35
|
-
| [Capability] | [Endpoint, command, or "automatic"] |
|
|
36
|
-
|
|
37
|
-
## Evidence
|
|
38
|
-
|
|
39
|
-
<!-- REQUIRED if this release claims to fix a bug. -->
|
|
40
|
-
<!-- Unit tests passing is NOT evidence. Provide ONE of: -->
|
|
41
|
-
<!-- (a) Reproduction steps + observed before/after on a live system. -->
|
|
42
|
-
<!-- Include log excerpts, observed command output, or behavior -->
|
|
43
|
-
<!-- description. Make it specific enough that a future reader can -->
|
|
44
|
-
<!-- re-run it and see the same thing. -->
|
|
45
|
-
<!-- (b) "Not reproducible in dev — [concrete reason]" if the failure -->
|
|
46
|
-
<!-- mode truly can't be exercised locally (race conditions, -->
|
|
47
|
-
<!-- event-driven paths requiring external signals, etc). -->
|
|
48
|
-
<!-- -->
|
|
49
|
-
<!-- If this release doesn't claim a bug fix (pure feature / refactor), -->
|
|
50
|
-
<!-- leave this section blank or delete it — it's only enforced when -->
|
|
51
|
-
<!-- "What Changed" describes a fix. -->
|
|
52
|
-
|
|
53
|
-
[Describe reproduction + verified fix, OR "Not reproducible in dev — [concrete reason]"]
|
|
File without changes
|