@mycadet/assistant 0.12.9 → 0.12.11
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/Dockerfile +0 -8
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +1 -1
- package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +8 -8
- package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/ingress.ts +1 -1
- package/node_modules/@mycadet/ces-client/src/http-credentials.ts +18 -1
- package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +8 -8
- package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/ingress.ts +1 -1
- package/node_modules/@mycadet/service-contracts/src/__tests__/ingress.test.ts +8 -8
- package/node_modules/@mycadet/service-contracts/src/ingress.ts +1 -1
- package/openapi.yaml +62 -910
- package/package.json +3 -7
- package/scripts/build-test-fixtures.ts +1 -1
- package/scripts/generate-openapi.ts +22 -6
- package/scripts/postinstall.ts +4 -10
- package/scripts/run-tests.ts +0 -21
- package/src/__tests__/adaptive-thinking-repair.test.ts +19 -57
- package/src/__tests__/agent-loop.test.ts +0 -76
- package/src/__tests__/anthropic-provider.test.ts +6 -6
- package/src/__tests__/assert-not-live-db.ts +1 -1
- package/src/__tests__/assistant-id-boundary-guard.test.ts +3 -3
- package/src/__tests__/attachments-store-heic-normalize.test.ts +1 -1
- package/src/__tests__/attachments-store.test.ts +1 -1
- package/src/__tests__/audit-log-rotation.test.ts +1 -1
- package/src/__tests__/btw-routes.test.ts +1 -1
- package/src/__tests__/byok-default-profile-ensure.test.ts +21 -27
- package/src/__tests__/call-conversation-messages.test.ts +0 -5
- package/src/__tests__/call-recovery.test.ts +2 -7
- package/src/__tests__/call-routes-http.test.ts +0 -12
- package/src/__tests__/call-store.test.ts +2 -7
- package/src/__tests__/catalog-files.test.ts +7 -5
- package/src/__tests__/checker.test.ts +1 -1
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +4 -4
- package/src/__tests__/cloud-client-verify-credential.test.ts +0 -4
- package/src/__tests__/cloud-credential-catalog-cli.test.ts +14 -14
- package/src/__tests__/cloud-profile-guard.test.ts +87 -404
- package/src/__tests__/compaction-events.test.ts +2 -2
- package/src/__tests__/config-loader-backfill.test.ts +74 -163
- package/src/__tests__/config-loader-cloud-defaults.test.ts +11 -11
- package/src/__tests__/config-loader-corrupt.test.ts +10 -10
- package/src/__tests__/config-loader-quarantine-notice.test.ts +7 -7
- package/src/__tests__/config-loader-validation-reset-notice.test.ts +11 -11
- package/src/__tests__/config-schema.test.ts +26 -27
- package/src/__tests__/config-set-route.test.ts +2 -6
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +28 -300
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +39 -246
- package/src/__tests__/conversation-agent-loop.test.ts +2 -58
- package/src/__tests__/conversation-clear-safety.test.ts +0 -30
- package/src/__tests__/conversation-inference-profile-route.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +1 -1
- package/src/__tests__/conversation-skill-tools.test.ts +4 -444
- package/src/__tests__/conversation-slash-commands.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -84
- package/src/__tests__/conversation-surface-state.test.ts +0 -16
- package/src/__tests__/credential-health-service.test.ts +14 -1
- package/src/__tests__/credential-record-retire.test.ts +1 -1
- package/src/__tests__/credential-record-write-through.test.ts +1 -1
- package/src/__tests__/credential-security-invariants.test.ts +0 -145
- package/src/__tests__/custom-profile-ensure.test.ts +1 -1
- package/src/__tests__/default-profile-catalog-fallback.test.ts +5 -15
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -2
- package/src/__tests__/dictation-profile-store.test.ts +6 -6
- package/src/__tests__/disk-usage.test.ts +28 -164
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +1 -1
- package/src/__tests__/embedding-cloud-proxy-selection.test.ts +1 -1
- package/src/__tests__/emit-event-signal.test.ts +1 -1
- package/src/__tests__/gateway-client-cloud-outbound.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +0 -13
- package/src/__tests__/helpers/seed-app.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/identity-routes.test.ts +1 -1
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/inference-profile-session-ipc.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-config-quarantine-notice.test.ts +1 -1
- package/src/__tests__/injector-config-validation-reset-notice.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/{platform.test.ts → layout.test.ts} +1 -1
- package/src/__tests__/list-all-apps.test.ts +1 -1
- package/src/__tests__/live-workspace-guard.test.ts +2 -2
- package/src/__tests__/llm-resolver-override-or-default.test.ts +5 -6
- package/src/__tests__/llm-resolver.test.ts +7 -7
- package/src/__tests__/llm-schema-fallback-profile.test.ts +9 -10
- package/src/__tests__/llm-usage-store.test.ts +0 -495
- package/src/__tests__/log-export-routes.test.ts +1 -1
- package/src/__tests__/mcp-config-secret-boundary.test.ts +12 -53
- package/src/__tests__/mcp-list-plugin-servers.test.ts +1 -1
- package/src/__tests__/memory-config-file-parity.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messages-read-boundary-guard.test.ts +0 -2
- package/src/__tests__/notification-guardian-path.test.ts +0 -7
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +8 -8
- package/src/__tests__/path-policy.test.ts +1 -1
- package/src/__tests__/persona-resolver.test.ts +1 -1
- package/src/__tests__/plugin-app-serve-routes.test.ts +1 -1
- package/src/__tests__/plugin-effective-enabled-set.test.ts +1 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +4 -6
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -3
- package/src/__tests__/provider-cloud-proxy-integration.test.ts +1 -5
- package/src/__tests__/provider-connections-backfill.test.ts +10 -10
- package/src/__tests__/prune-old-conversations-job.test.ts +6 -31
- package/src/__tests__/resolve-app.test.ts +1 -1
- package/src/__tests__/run-due-schedules.test.ts +1 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +0 -53
- package/src/__tests__/schedule-routes.test.ts +1 -1
- package/src/__tests__/schedule-store.test.ts +1 -1
- package/src/__tests__/secret-routes-cloud-proxy.test.ts +1 -1
- package/src/__tests__/skill-load-plugin-scope.test.ts +1 -1
- package/src/__tests__/surface-completion-compaction-boundary.test.ts +1 -1
- package/src/__tests__/tool-approval-handler.test.ts +1 -1
- package/src/__tests__/tool-audit.test.ts +5 -235
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +54 -114
- package/src/__tests__/tools-get-route.test.ts +1 -1
- package/src/__tests__/turn-outcome-read.test.ts +1 -1
- package/src/__tests__/twilio-routes.test.ts +0 -1
- package/src/__tests__/usage-attribution.test.ts +0 -31
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -10
- package/src/__tests__/visible-app-context.test.ts +1 -1
- package/src/__tests__/voice-ingress-preflight.test.ts +1 -1
- package/src/__tests__/workspace-git-service.test.ts +1 -1
- package/src/__tests__/workspace-greetings.test.ts +1 -1
- package/src/acp/__tests__/helpers/acp-config-stub.ts +1 -1
- package/src/activation/progress-store.ts +1 -1
- package/src/activation/turn-hooks.ts +1 -1
- package/src/agent/loop.ts +0 -51
- package/src/apps/app-store.ts +1 -1
- package/src/avatar/__tests__/avatar-store.test.ts +2 -172
- package/src/avatar/accent-backfill.ts +1 -1
- package/src/avatar/avatar-manifest.ts +1 -1
- package/src/avatar/avatar-store.ts +10 -69
- package/src/avatar/ensure-raster.ts +1 -1
- package/src/avatar/identity-avatar.ts +1 -1
- package/src/avatar/sync-avatar.ts +1 -1
- package/src/avatar/traits-png-sync.ts +1 -1
- package/src/bundler/compiler-tools.ts +1 -1
- package/src/bundler/package-resolver.ts +1 -1
- package/src/calls/__tests__/call-controller.test.ts +25 -27
- package/src/calls/active-call-lease.ts +1 -1
- package/src/calls/call-controller.ts +3 -3
- package/src/calls/call-domain.ts +4 -8
- package/src/calls/call-store.ts +2 -76
- package/src/calls/resolve-call-tts-provider.ts +3 -3
- package/src/calls/twilio-config.ts +3 -3
- package/src/calls/twilio-rest.ts +2 -2
- package/src/calls/voice-ingress-preflight.ts +2 -2
- package/src/cli/bundled-modules.ts +0 -2
- package/src/cli/commands/__tests__/apps.test.ts +1 -1
- package/src/cli/commands/__tests__/plugins.test.ts +9 -66
- package/src/cli/commands/__tests__/ps.test.ts +67 -0
- package/src/cli/commands/auth.help.ts +2 -2
- package/src/cli/commands/avatar.ts +1 -1
- package/src/cli/commands/changelog.ts +1 -1
- package/src/cli/commands/cloud/__tests__/subscription.test.ts +2 -2
- package/src/cli/commands/cloud/index.help.ts +1 -1
- package/src/cli/commands/cloud/index.ts +2 -2
- package/src/cli/commands/db/refresh.ts +1 -1
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +1 -1
- package/src/cli/commands/db/repair.ts +1 -1
- package/src/cli/commands/db/status.ts +1 -1
- package/src/cli/commands/inference-profiles.ts +1 -12
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +1 -116
- package/src/cli/commands/memory/index.help.ts +1 -43
- package/src/cli/commands/memory/memory-v3.ts +0 -64
- package/src/cli/commands/plugins.ts +54 -205
- package/src/cli/commands/ps.ts +5 -2
- package/src/cli/commands/status.ts +1 -1
- package/src/cli/index.help.ts +0 -2
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +36 -66
- package/src/cli/lib/__tests__/install-from-cloud.test.ts +1 -1
- package/src/cli/lib/__tests__/install-from-github.test.ts +41 -117
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +2 -185
- package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +36 -66
- package/src/cli/lib/__tests__/plugin-catalog-visibility.test.ts +4 -6
- package/src/cli/lib/__tests__/plugin-details.test.ts +113 -96
- package/src/cli/lib/__tests__/search-plugins.test.ts +9 -16
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +1 -1
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +38 -15
- package/src/cli/lib/diff-plugin.ts +1 -1
- package/src/cli/lib/inspect-plugin.ts +13 -97
- package/src/cli/lib/install-from-cloud.ts +1 -1
- package/src/cli/lib/install-from-github.ts +75 -154
- package/src/cli/lib/install-plugin-dependencies.ts +1 -1
- package/src/cli/lib/list-installed-plugins.ts +1 -1
- package/src/cli/lib/open-browser.ts +1 -1
- package/src/cli/lib/plugin-catalog-cache.ts +8 -51
- package/src/cli/lib/plugin-catalog-resolve.ts +3 -22
- package/src/cli/lib/plugin-details.ts +5 -27
- package/src/cli/lib/plugin-marketplace.ts +18 -266
- package/src/cli/lib/search-plugins.ts +23 -43
- package/src/cli/lib/toggle-plugin.ts +1 -1
- package/src/cli/lib/uninstall-plugin.ts +1 -1
- package/src/cli/lib/upgrade-plugin.ts +3 -49
- package/src/cli/program.ts +1 -3
- package/src/cli.ts +1 -1
- package/src/cloud/client.ts +0 -6
- package/src/cloud/consent-cache.test.ts +22 -201
- package/src/cloud/consent-cache.ts +16 -111
- package/src/cloud/sync-identity.ts +1 -1
- package/src/config/__tests__/chat-settings.test.ts +1 -1
- package/src/config/__tests__/cloud-identity.test.ts +15 -2
- package/src/config/__tests__/default-plugin-skill-discovery.test.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +12 -51
- package/src/config/__tests__/deployment-context-defaults.test.ts +13 -13
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +4 -4
- package/src/config/__tests__/loader-last-known-good.test.ts +9 -9
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +7 -7
- package/src/config/__tests__/plugin-resident-skill-discovery.test.ts +1 -1
- package/src/config/__tests__/profile-materialization.test.ts +2 -4
- package/src/config/__tests__/sync-gated-profiles.test.ts +1 -106
- package/src/config/acp-agent-write.ts +1 -1
- package/src/config/bundled-skills/settings/tools/open-system-settings.test.ts +1 -1
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -1
- package/src/config/call-site-defaults.ts +0 -6
- package/src/config/cloud-identity.ts +12 -5
- package/src/config/composer-preferences.ts +1 -1
- package/src/config/default-profile-catalog.ts +8 -75
- package/src/config/default-profile-names.ts +2 -25
- package/src/config/env-registry.ts +1 -14
- package/src/config/env.ts +8 -6
- package/src/config/llm-resolver.ts +1 -2
- package/src/config/loader.ts +13 -17
- package/src/config/profile-materialization.ts +1 -1
- package/src/config/schema.ts +1 -7
- package/src/config/schemas/call-site-catalog.ts +0 -7
- package/src/config/schemas/llm.ts +25 -32
- package/src/config/seed-inference-profiles.ts +16 -17
- package/src/config/skills.ts +2 -2
- package/src/config/sync-gated-profiles.ts +6 -24
- package/src/credential-health/credential-health-service.ts +10 -3
- package/src/daemon/approval-generators.ts +3 -3
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +0 -18
- package/src/daemon/conversation-agent-loop.ts +6 -97
- package/src/daemon/conversation-process.ts +1 -1
- package/src/daemon/conversation-skill-tools.ts +4 -72
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surface-state.ts +0 -33
- package/src/daemon/conversation-surfaces.ts +1 -86
- package/src/daemon/conversation-tool-setup.test.ts +1 -1
- package/src/daemon/conversation-tool-setup.ts +0 -23
- package/src/daemon/conversation.ts +3 -5
- package/src/daemon/daemon-control.ts +3 -3
- package/src/daemon/dictation-profile-store.ts +3 -3
- package/src/daemon/event-loop-watchdog.test.ts +2 -198
- package/src/daemon/event-loop-watchdog.ts +0 -185
- package/src/daemon/external-plugins-bootstrap.ts +1 -1
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/skills.ts +1 -1
- package/src/daemon/host-app-control-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +2 -2
- package/src/daemon/identity-helpers.ts +1 -1
- package/src/daemon/lifecycle.ts +11 -15
- package/src/daemon/main.ts +1 -1
- package/src/daemon/now-scratchpad.ts +1 -1
- package/src/daemon/process-message.ts +4 -4
- package/src/daemon/profiler-run-store.ts +2 -2
- package/src/daemon/providers-setup.ts +2 -2
- package/src/daemon/shutdown-handlers.ts +0 -10
- package/src/daemon/sqlite-corruption-watchdog.test.ts +2 -142
- package/src/daemon/sqlite-corruption-watchdog.ts +17 -81
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/desktop/desktop-session-manager.ts +1 -1
- package/src/desktop/desktop-wallpaper-renderer.ts +1 -1
- package/src/heartbeat/heartbeat-service.ts +1 -1
- package/src/home/feed-writer.ts +1 -1
- package/src/home/home-greeting-cache.ts +1 -1
- package/src/home/relationship-state-writer.ts +2 -2
- package/src/hooks/__tests__/hook-live-reload.test.ts +1 -1
- package/src/hooks/hook-loader.ts +2 -2
- package/src/inbound/__tests__/oauth-callback-url.test.ts +2 -2
- package/src/inbound/oauth-callback-url.ts +3 -3
- package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
- package/src/ipc/socket-path.ts +1 -1
- package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -1
- package/src/live-voice/__tests__/live-voice-vad.test.ts +1 -1
- package/src/live-voice/live-voice-session.ts +3 -66
- package/src/mcp/__tests__/effective-config.test.ts +1 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +2 -2
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +2 -3
- package/src/mcp/__tests__/reload-signal-emission.test.ts +1 -1
- package/src/mcp/__tests__/reload-signal.test.ts +1 -1
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +19 -21
- package/src/mcp/reload-signal.ts +1 -1
- package/src/mcp/workspace-mcp-config.ts +1 -23
- package/src/messaging/draft-store.ts +1 -1
- package/src/monitoring/__tests__/active-conversations.test.ts +1 -1
- package/src/monitoring/__tests__/page-cache.test.ts +1 -1
- package/src/monitoring/__tests__/stall-capture.test.ts +1 -1
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +1 -1
- package/src/monitoring/active-conversations.ts +1 -1
- package/src/monitoring/control.ts +1 -1
- package/src/monitoring/daemon-boot-time.ts +1 -1
- package/src/monitoring/daemon-heartbeat.ts +1 -1
- package/src/monitoring/page-cache.ts +1 -1
- package/src/monitoring/plugin-auto-update.ts +1 -7
- package/src/monitoring/plugin-source-watch.ts +1 -1
- package/src/monitoring/recovery/db.ts +1 -1
- package/src/monitoring/recovery/inflight-content.ts +1 -1
- package/src/monitoring/resource-sampler.ts +3 -14
- package/src/monitoring/stall-capture.ts +1 -1
- package/src/monitoring/worker.ts +9 -76
- package/src/monitoring/workspace-git-heartbeat.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +4 -4
- package/src/permissions/checker.ts +1 -1
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/persistence/__tests__/main-db-readonly-probe.ts +27 -52
- package/src/persistence/__tests__/message-content-file.test.ts +1 -1
- package/src/persistence/__tests__/slow-sync-log.test.ts +0 -2
- package/src/persistence/attachments-store.ts +1 -1
- package/src/persistence/conversation-crud.ts +1 -38
- package/src/persistence/conversation-directories.ts +1 -1
- package/src/persistence/conversation-types.ts +0 -8
- package/src/persistence/db-async-query.ts +1 -1
- package/src/persistence/db-connection.ts +11 -1
- package/src/persistence/db-init.ts +1 -1
- package/src/persistence/db-maintenance.ts +1 -1
- package/src/persistence/embeddings/__tests__/embedding-local-lifecycle.test.ts +1 -1
- package/src/persistence/embeddings/embedding-local.ts +4 -4
- package/src/persistence/embeddings/embedding-runtime-manager.ts +1 -1
- package/src/persistence/embeddings/qdrant-client.ts +1 -1
- package/src/persistence/embeddings/qdrant-manager.ts +1 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +1 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +1 -1
- package/src/persistence/job-handlers/cleanup.ts +8 -17
- package/src/persistence/llm-usage-store.ts +2 -229
- package/src/persistence/message-content-file.ts +1 -1
- package/src/persistence/migrations/209-strip-thinking-from-consolidated.ts +1 -1
- package/src/persistence/migrations/222-strip-placeholder-sentinels-from-messages.ts +1 -1
- package/src/persistence/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +1 -1
- package/src/persistence/migrations/306-rewrite-frontier-profile-pins.test.ts +1 -1
- package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.test.ts +13 -0
- package/src/persistence/migrations/333-create-telemetry-events-table.test.ts +7 -4
- package/src/persistence/migrations/334-backfill-telemetry-events-outbox.test.ts +13 -0
- package/src/persistence/migrations/387-drop-telemetry-tables.ts +51 -0
- package/src/persistence/migrations/__tests__/327-create-flush-checkpoints.test.ts +9 -1
- package/src/persistence/migrations/__tests__/387-drop-telemetry-tables.test.ts +79 -0
- package/src/persistence/migrations/helpers/relocation.ts +1 -1
- package/src/persistence/migrations/run-migrations.ts +1 -1
- package/src/persistence/migrations/validate-migration-state.ts +1 -1
- package/src/persistence/raw-query.ts +1 -29
- package/src/persistence/slow-sync-log.ts +0 -23
- package/src/persistence/steps.ts +2 -0
- package/src/{telemetry → persistence}/tool-audit.ts +6 -121
- package/src/plugin-api/index.ts +1 -1
- package/src/plugin-api/plugin-name-env.ts +1 -1
- package/src/plugins/__tests__/installed-plugin-dirs.test.ts +1 -1
- package/src/plugins/collect-source-versions.ts +1 -1
- package/src/plugins/defaults/channel/package.json +1 -1
- package/src/plugins/defaults/cloud-hosted/package.json +1 -1
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/documents/package.json +1 -1
- package/src/plugins/defaults/empty-response/package.json +1 -1
- package/src/plugins/defaults/exploration-drift/package.json +1 -1
- package/src/plugins/defaults/image-fallback/package.json +1 -1
- package/src/plugins/defaults/image-recovery/package.json +1 -1
- package/src/plugins/defaults/max-tokens-continue/package.json +1 -1
- package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/db-maintenance.test.ts +1 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +0 -82
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +0 -41
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -2
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -52
- package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +0 -18
- package/src/plugins/defaults/memory/package.json +1 -1
- package/src/plugins/defaults/memory/paths.ts +4 -4
- package/src/plugins/defaults/memory/src/__tests__/memory-worker-routes.test.ts +1 -1
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +5 -5
- package/src/plugins/defaults/memory/src/memory-v3-routes.ts +0 -207
- package/src/plugins/defaults/memory/src/memory-worker-routes.ts +1 -1
- package/src/plugins/defaults/memory/startup.ts +1 -22
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +2 -253
- package/src/plugins/defaults/memory/v3/orchestrate.ts +5 -129
- package/src/plugins/defaults/memory/worker-control.ts +1 -1
- package/src/plugins/defaults/memory/worker.ts +2 -2
- package/src/plugins/defaults/session/package.json +1 -1
- package/src/plugins/defaults/surface-completion-nudge/package.json +1 -1
- package/src/plugins/defaults/task-progress/package.json +1 -1
- package/src/plugins/defaults/task-progress-nudge/package.json +1 -1
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +1 -1
- package/src/plugins/defaults/turn-context/package.json +1 -1
- package/src/plugins/defaults/workspace/injectors.ts +1 -1
- package/src/plugins/defaults/workspace/package.json +1 -1
- package/src/plugins/disabled-state.ts +1 -1
- package/src/plugins/ensure-plugin-api-shim.ts +1 -1
- package/src/plugins/ensure-shared-dep-links.ts +1 -1
- package/src/plugins/installed-plugin-dirs.ts +1 -1
- package/src/plugins/mcp-servers.ts +7 -9
- package/src/plugins/mtime-cache.ts +2 -2
- package/src/plugins/source-versions.ts +1 -1
- package/src/prompts/bootstrap-cleanup.ts +1 -1
- package/src/prompts/persona-resolver.ts +1 -1
- package/src/prompts/sections.ts +2 -2
- package/src/prompts/system-prompt.ts +10 -42
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +0 -37
- package/src/providers/__tests__/cadet-connection-routing.test.ts +2 -2
- package/src/providers/cadet/client.ts +1 -1
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +1 -1
- package/src/providers/inference/adapter-factory.ts +1 -1
- package/src/providers/inference/backfill.ts +3 -10
- package/src/providers/inference/profile-probe.ts +1 -1
- package/src/providers/retry.ts +0 -2
- package/src/providers/types.ts +0 -7
- package/src/providers/usage-tracking.ts +1 -1
- package/src/routes/__tests__/route-host.test.ts +1 -1
- package/src/routes/control.ts +1 -1
- package/src/routes/route-host-client.ts +1 -1
- package/src/routes/worker.ts +2 -2
- package/src/runtime/agent-wake.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +1 -1
- package/src/runtime/auth/token-service.ts +1 -1
- package/src/runtime/background-job-runner.ts +1 -1
- package/src/runtime/middleware/twilio-validation.ts +2 -2
- package/src/runtime/routes/__tests__/app-pin-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +1 -1
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +3 -33
- package/src/runtime/routes/__tests__/cloud-credits-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/cloud-invoice-routes.test.ts +4 -3
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +72 -298
- package/src/runtime/routes/__tests__/default-plugin-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/deprecated-route-context.test.ts +15 -62
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +105 -12
- package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +47 -211
- package/src/runtime/routes/__tests__/route-host-worker-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +1 -1
- package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-routes-cli.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-routes-notices.test.ts +1 -1
- package/src/runtime/routes/__tests__/user-routes-request.test.ts +1 -1
- package/src/runtime/routes/app-management-routes.ts +1 -1
- package/src/runtime/routes/attachment-routes.ts +1 -1
- package/src/runtime/routes/audit-routes.ts +1 -1
- package/src/runtime/routes/avatar-routes.ts +3 -10
- package/src/runtime/routes/cloud-routes.ts +3 -3
- package/src/runtime/routes/content-source-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +49 -706
- package/src/runtime/routes/conversation-routes.ts +1 -38
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/deprecated-route-context.ts +5 -61
- package/src/runtime/routes/heartbeat-routes.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +1 -1
- package/src/runtime/routes/index.ts +0 -6
- package/src/runtime/routes/inference-profile-session-handler.ts +3 -3
- package/src/runtime/routes/inference-profiles-routes.ts +48 -21
- package/src/runtime/routes/inference-provider-connection-routes.ts +0 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +3 -3
- package/src/runtime/routes/log-export/__tests__/installed-inventory.test.ts +1 -1
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +1 -1
- package/src/runtime/routes/log-export/__tests__/workspace-allowlist.test.ts +1 -1
- package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
- package/src/runtime/routes/log-export-routes.ts +17 -15
- package/src/runtime/routes/migration-rollback-routes.ts +1 -1
- package/src/runtime/routes/migration-routes.ts +2 -3
- package/src/runtime/routes/monitoring-routes.ts +2 -2
- package/src/runtime/routes/oauth-providers.ts +5 -5
- package/src/runtime/routes/plugins-routes.ts +38 -163
- package/src/runtime/routes/profiler-routes.ts +1 -1
- package/src/runtime/routes/route-host-worker-routes.ts +1 -1
- package/src/runtime/routes/sanity-routes.ts +1 -1
- package/src/runtime/routes/schedule-routes.ts +1 -1
- package/src/runtime/routes/schedule-worker-routes.ts +1 -1
- package/src/runtime/routes/settings-routes.ts +1 -1
- package/src/runtime/routes/sounds-config-routes.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +1 -7
- package/src/runtime/routes/user-route-dispatcher.ts +1 -3
- package/src/runtime/routes/user-route-import.ts +1 -1
- package/src/runtime/routes/user-route-resolution.ts +1 -1
- package/src/runtime/routes/user-routes-cli.ts +1 -1
- package/src/runtime/routes/workspace-commit-routes.ts +1 -1
- package/src/runtime/routes/workspace-greetings.ts +1 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +1 -1
- package/src/runtime/sync/resource-sync-events.ts +1 -1
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +1 -1
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +1 -1
- package/src/schedule/plugin-schedule-availability.ts +1 -1
- package/src/schedule/plugin-schedule-declarations.ts +1 -1
- package/src/schedule/run-script.ts +1 -1
- package/src/schedule/scheduler.ts +1 -11
- package/src/schedule/worker-control.ts +1 -1
- package/src/schedule/worker.ts +3 -3
- package/src/security/oauth2.ts +2 -2
- package/src/security/secret-allowlist.ts +1 -1
- package/src/signals/cancel.ts +1 -1
- package/src/signals/conversation-undo.ts +1 -1
- package/src/signals/emit-event.ts +1 -1
- package/src/signals/event-stream.ts +1 -1
- package/src/signals/user-message.ts +1 -1
- package/src/skills/catalog-install.ts +2 -1
- package/src/skills/clawhub.ts +1 -1
- package/src/skills/cloud-store.ts +1 -1
- package/src/skills/path-classifier.ts +1 -1
- package/src/skills/skill-history.ts +1 -1
- package/src/skills/skillssh-registry.ts +1 -1
- package/src/skills/uninstall.ts +1 -1
- package/src/skills/workspace-skill-md-signature.ts +1 -1
- package/src/subagent/manager.ts +1 -1
- package/src/theme/workspace-theme.ts +1 -1
- package/src/tools/browser/auth-cache.ts +1 -1
- package/src/tools/browser/browser-manager.ts +1 -1
- package/src/tools/browser/runtime-check.ts +1 -1
- package/src/tools/executor.ts +4 -4
- package/src/tools/filesystem/write.ts +1 -1
- package/src/tools/permission-checker.ts +2 -51
- package/src/tools/run-standalone.ts +1 -1
- package/src/tools/skills/format-input-schema.ts +1 -1
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/skills/scaffold-cloud.ts +0 -32
- package/src/tools/terminal/safe-env.ts +1 -2
- package/src/tools/terminal/sanitized-bash.ts +1 -1
- package/src/tools/terminal/shell.ts +1 -1
- package/src/tools/tool-approval-handler.ts +4 -1
- package/src/tools/workflows/manage-workflows.ts +2 -2
- package/src/tools/workflows/run-workflow.test.ts +1 -1
- package/src/tools/workspace-tools/loader.ts +1 -1
- package/src/tts/synthesis-stream.ts +2 -2
- package/src/usage/attribution.ts +1 -11
- package/src/util/browser.ts +1 -1
- package/src/util/bun-runtime.ts +2 -1
- package/src/util/device-id.ts +1 -1
- package/src/util/disk-usage.ts +4 -139
- package/src/util/layout.ts +3 -3
- package/src/util/logger.ts +1 -1
- package/src/util/logs-db-path.ts +1 -1
- package/src/util/memory-db-path.ts +1 -1
- package/src/util/{platform.ts → os.ts} +5 -30
- package/src/util/process-tree.ts +19 -0
- package/src/util/sqlite3-runtime.ts +1 -1
- package/src/util/telemetry-db-path.ts +1 -1
- package/src/watcher/__tests__/engine.test.ts +0 -23
- package/src/watcher/engine.ts +0 -7
- package/src/windows-compiled-cli.ts +0 -4
- package/src/windows-compiled-worker-entry.ts +0 -6
- package/src/workflows/leaf-runner.test.ts +1 -1
- package/src/workflows/leaf-runner.ts +1 -1
- package/src/workflows/library.ts +1 -1
- package/src/workspace/adaptive-thinking-repair.ts +5 -24
- package/src/workspace/byok-default-profile-ensure.ts +24 -26
- package/src/workspace/custom-profile-ensure.ts +2 -2
- package/src/workspace/git-service.ts +1 -1
- package/src/workspace/hatched-date.ts +1 -1
- package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +2 -2
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +1 -1
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +1 -1
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +1 -1
- package/src/workspace/migrations/registry.ts +0 -4
- package/src/workspace/turn-commit.ts +1 -1
- package/docs/activation-funnel-telemetry.md +0 -324
- package/scripts/bundled-plugin-packages.ts +0 -154
- package/scripts/generate-bundled-plugin-packages.ts +0 -29
- package/src/__tests__/activation-early-marking.test.ts +0 -114
- package/src/__tests__/auth-fallback-events-store.test.ts +0 -99
- package/src/__tests__/config-get-vision-flag.test.ts +0 -139
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +0 -400
- package/src/__tests__/internal-telemetry-routes.test.ts +0 -213
- package/src/__tests__/telemetry-routes.test.ts +0 -182
- package/src/__tests__/turn-events-store.test.ts +0 -376
- package/src/__tests__/ui-channel-variants.test.ts +0 -53
- package/src/avatar/__tests__/avatar-changed-telemetry.test.ts +0 -217
- package/src/avatar/avatar-changed-telemetry.ts +0 -128
- package/src/calls/__tests__/call-funnel-telemetry.test.ts +0 -204
- package/src/cli/commands/telemetry.help.ts +0 -27
- package/src/cli/commands/telemetry.ts +0 -83
- package/src/cli/lib/__tests__/local-plugin-upgrade.test.ts +0 -251
- package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +0 -113
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +0 -384
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +0 -164
- package/src/cli/lib/__tests__/plugins-install-offline.test.ts +0 -228
- package/src/cli/lib/bundled-marketplace.json +0 -1575
- package/src/cli/lib/bundled-plugin-packages.json +0 -827
- package/src/cli/lib/bundled-plugin-packages.ts +0 -87
- package/src/cli/lib/plugin-catalog-local.ts +0 -94
- package/src/cli/lib/plugin-pin-history.ts +0 -276
- package/src/cloud/feature-gate.ts +0 -8
- package/src/config/__tests__/cloud-rehydration.test.ts +0 -180
- package/src/config/cloud-rehydration.ts +0 -35
- package/src/daemon/__tests__/auto-profile-router.test.ts +0 -380
- package/src/daemon/auto-profile-router.ts +0 -428
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +0 -391
- package/src/monitoring/__tests__/db-integrity-sample.test.ts +0 -113
- package/src/monitoring/__tests__/oom-kill-reporter.test.ts +0 -374
- package/src/monitoring/db-integrity-check.ts +0 -163
- package/src/monitoring/db-integrity-sample.ts +0 -176
- package/src/monitoring/oom-kill-reporter.ts +0 -469
- package/src/onboarding/__tests__/onboarding-events-store.test.ts +0 -158
- package/src/onboarding/onboarding-events-store.ts +0 -296
- package/src/persistence/__tests__/raw-query-telemetry.test.ts +0 -76
- package/src/persistence/lifecycle-events-store.test.ts +0 -134
- package/src/persistence/lifecycle-events-store.ts +0 -110
- package/src/plugins/defaults/memory/__tests__/activation-session-store.test.ts +0 -76
- package/src/plugins/defaults/memory/activation-session-store.ts +0 -50
- package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +0 -281
- package/src/runtime/routes/auto-profile-routes.ts +0 -83
- package/src/runtime/routes/internal-telemetry-routes.ts +0 -142
- package/src/runtime/routes/telemetry-routes.ts +0 -274
- package/src/security/auth-fallback-events-store.ts +0 -57
- package/src/telemetry/__tests__/activation-funnel.test.ts +0 -95
- package/src/telemetry/__tests__/config-setting-events-store.test.ts +0 -63
- package/src/telemetry/__tests__/config-setting-snapshot.test.ts +0 -143
- package/src/telemetry/__tests__/flush-checkpoints.test.ts +0 -56
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +0 -174
- package/src/telemetry/__tests__/outbox-test-harness.ts +0 -85
- package/src/telemetry/__tests__/phone-call-funnel.test.ts +0 -72
- package/src/telemetry/__tests__/telemetry-event-fixtures.ts +0 -282
- package/src/telemetry/__tests__/watchdog-events-store.test.ts +0 -71
- package/src/telemetry/activation-funnel.ts +0 -172
- package/src/telemetry/config-setting-events-store.ts +0 -40
- package/src/telemetry/config-setting-snapshot.ts +0 -170
- package/src/telemetry/flush-checkpoints.ts +0 -70
- package/src/telemetry/live-voice-funnel.ts +0 -185
- package/src/telemetry/memory-corpus-size.test.ts +0 -120
- package/src/telemetry/memory-corpus-size.ts +0 -184
- package/src/telemetry/memory-tier-reporter.test.ts +0 -195
- package/src/telemetry/memory-tier-reporter.ts +0 -130
- package/src/telemetry/phone-call-funnel.ts +0 -144
- package/src/telemetry/skill-loaded-events-store.test.ts +0 -93
- package/src/telemetry/skill-loaded-events-store.ts +0 -39
- package/src/telemetry/telemetry-event-sources.test.ts +0 -223
- package/src/telemetry/telemetry-event-sources.ts +0 -597
- package/src/telemetry/telemetry-events-outbox.test.ts +0 -375
- package/src/telemetry/telemetry-events-outbox.ts +0 -237
- package/src/telemetry/telemetry-main-db.ts +0 -48
- package/src/telemetry/telemetry-wire-source.json +0 -4
- package/src/telemetry/telemetry-wire-validation.test.ts +0 -157
- package/src/telemetry/telemetry-wire-validation.ts +0 -162
- package/src/telemetry/telemetry-wire.generated.ts +0 -483
- package/src/telemetry/tool-executed-events-store.test.ts +0 -210
- package/src/telemetry/tool-executed-events-store.ts +0 -102
- package/src/telemetry/trace-collection-policy.test.ts +0 -28
- package/src/telemetry/trace-collection-policy.ts +0 -30
- package/src/telemetry/turn-events-store.ts +0 -216
- package/src/telemetry/turn-trace-store.test.ts +0 -884
- package/src/telemetry/turn-trace-store.ts +0 -399
- package/src/telemetry/types.test.ts +0 -38
- package/src/telemetry/types.ts +0 -780
- package/src/telemetry/usage-telemetry-reporter.test.ts +0 -3445
- package/src/telemetry/usage-telemetry-reporter.ts +0 -566
- package/src/telemetry/watchdog-direct-emit.test.ts +0 -112
- package/src/telemetry/watchdog-direct-emit.ts +0 -104
- package/src/telemetry/watchdog-events-store.ts +0 -31
- package/src/tools/ui-surface/channel-variants.ts +0 -52
- package/src/watcher/__tests__/telemetry.test.ts +0 -178
- package/src/watcher/telemetry.ts +0 -93
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +0 -165
- package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +0 -151
- /package/src/{telemetry → persistence}/tool-usage-store.ts +0 -0
- /package/src/{telemetry → persistence}/turn-outcome.ts +0 -0
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Periodic database integrity sample, reported as a `db_integrity` watchdog
|
|
3
|
-
* event so the cloud can read corruption prevalence across the fleet.
|
|
4
|
-
*
|
|
5
|
-
* The `PRAGMA quick_check` itself runs in a short-lived subprocess
|
|
6
|
-
* (`db-integrity-check.ts`) — bun:sqlite's page walk is synchronous, and a
|
|
7
|
-
* multi-second scan inside this process would stall the resource sampler and
|
|
8
|
-
* signal handling, the exact things the monitor exists to keep responsive.
|
|
9
|
-
* The check opens a read-only handle and never mutates the database.
|
|
10
|
-
*
|
|
11
|
-
* At most one sample per 24h per install (stamped on disk), so the
|
|
12
|
-
* denominator is "installs that reported today" rather than "daemon
|
|
13
|
-
* restarts". The stamp is written only after the event is queued: a failed
|
|
14
|
-
* enqueue leaves the install due, so it retries next poll instead of
|
|
15
|
-
* silently dropping out of the day's denominator.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import { existsSync, statSync, writeFileSync } from "node:fs";
|
|
19
|
-
import { join } from "node:path";
|
|
20
|
-
|
|
21
|
-
import { getRawShareAnalytics } from "../cloud/consent-cache.js";
|
|
22
|
-
import { recordWatchdogEvent } from "../telemetry/watchdog-events-store.js";
|
|
23
|
-
import { getLogger } from "../util/logger.js";
|
|
24
|
-
import { getDbPath, getMonitoringDataDir } from "../util/platform.js";
|
|
25
|
-
import { resolveWorkerCommand } from "../util/worker-process.js";
|
|
26
|
-
import type { IntegritySampleResult } from "./db-integrity-check.js";
|
|
27
|
-
|
|
28
|
-
const log = getLogger("db-integrity-sample");
|
|
29
|
-
|
|
30
|
-
/** Watchdog `check_name` carrying the quick_check outcome. */
|
|
31
|
-
const CHECK_NAME = "db_integrity";
|
|
32
|
-
|
|
33
|
-
/** Minimum spacing between samples on one install. */
|
|
34
|
-
const SAMPLE_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
35
|
-
|
|
36
|
-
/** How often the sampler re-tests the 24h stamp (covers long-uptime installs). */
|
|
37
|
-
const POLL_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
38
|
-
|
|
39
|
-
/** Delay before the first attempt, keeping the scan off the boot I/O path. */
|
|
40
|
-
const BOOT_DELAY_MS = 60_000;
|
|
41
|
-
|
|
42
|
-
/** Kill switch for a check subprocess wedged on pathological I/O. */
|
|
43
|
-
const CHECK_TIMEOUT_MS = 10 * 60 * 1000;
|
|
44
|
-
|
|
45
|
-
const STAMP_FILENAME = "db-integrity-last-run-at";
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Run the quick_check probe in a subprocess and parse its JSON verdict.
|
|
49
|
-
* Returns null — "no sample" — on a non-zero exit, unparseable output, or
|
|
50
|
-
* timeout (the child is killed).
|
|
51
|
-
*/
|
|
52
|
-
/**
|
|
53
|
-
* The in-flight check subprocess, retained so sampler shutdown can kill it —
|
|
54
|
-
* a non-detached child survives the monitor's exit and would otherwise hold
|
|
55
|
-
* its SQLite read snapshot for up to CHECK_TIMEOUT_MS while the daemon
|
|
56
|
-
* restarts.
|
|
57
|
-
*/
|
|
58
|
-
let activeChild: ReturnType<typeof Bun.spawn> | null = null;
|
|
59
|
-
|
|
60
|
-
async function runCheckSubprocess(
|
|
61
|
-
dbPath: string,
|
|
62
|
-
): Promise<IntegritySampleResult | null> {
|
|
63
|
-
const command = resolveWorkerCommand(
|
|
64
|
-
new URL("./db-integrity-check.ts", import.meta.url),
|
|
65
|
-
"db-integrity",
|
|
66
|
-
);
|
|
67
|
-
const child = Bun.spawn({
|
|
68
|
-
cmd: [...command, dbPath],
|
|
69
|
-
windowsHide: true,
|
|
70
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
71
|
-
});
|
|
72
|
-
activeChild = child;
|
|
73
|
-
const killTimer = setTimeout(() => child.kill(), CHECK_TIMEOUT_MS);
|
|
74
|
-
killTimer.unref?.();
|
|
75
|
-
try {
|
|
76
|
-
const stdout = await new Response(child.stdout).text();
|
|
77
|
-
if ((await child.exited) !== 0) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return JSON.parse(stdout) as IntegritySampleResult | null;
|
|
81
|
-
} catch {
|
|
82
|
-
return null;
|
|
83
|
-
} finally {
|
|
84
|
-
clearTimeout(killTimer);
|
|
85
|
-
activeChild = null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function stampPath(): string {
|
|
90
|
-
return join(getMonitoringDataDir(), STAMP_FILENAME);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function due(): boolean {
|
|
94
|
-
try {
|
|
95
|
-
return Date.now() - statSync(stampPath()).mtimeMs >= SAMPLE_INTERVAL_MS;
|
|
96
|
-
} catch {
|
|
97
|
-
return true; // never sampled (or unreadable stamp) — sample now
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Sample once if the install is due, emitting one `db_integrity` watchdog
|
|
103
|
-
* event. Never throws. Skips entirely on a confirmed analytics opt-out,
|
|
104
|
-
* where the event would be dropped at record time anyway and the scan would
|
|
105
|
-
* be pure wasted I/O.
|
|
106
|
-
*/
|
|
107
|
-
export async function sampleDbIntegrityIfDue(): Promise<void> {
|
|
108
|
-
if (getRawShareAnalytics() === false || !due()) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
try {
|
|
112
|
-
if (!existsSync(getDbPath())) {
|
|
113
|
-
return; // no database yet — stay due, retry next poll
|
|
114
|
-
}
|
|
115
|
-
const result = await runCheckSubprocess(getDbPath());
|
|
116
|
-
if (!result) {
|
|
117
|
-
return; // locked, operational failure, or timeout — stay due
|
|
118
|
-
}
|
|
119
|
-
const queued = recordWatchdogEvent({
|
|
120
|
-
checkName: CHECK_NAME,
|
|
121
|
-
value: result.errors.length,
|
|
122
|
-
detail: {
|
|
123
|
-
ok: result.ok,
|
|
124
|
-
mode: "quick_check",
|
|
125
|
-
page_count: result.pageCount,
|
|
126
|
-
duration_ms: result.durationMs,
|
|
127
|
-
errors: result.errors,
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
if (queued) {
|
|
131
|
-
writeFileSync(stampPath(), "");
|
|
132
|
-
}
|
|
133
|
-
if (!result.ok) {
|
|
134
|
-
log.warn(
|
|
135
|
-
{ errors: result.errors, pageCount: result.pageCount },
|
|
136
|
-
"Database integrity sample reported corruption",
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
} catch (err) {
|
|
140
|
-
log.warn({ err }, "Database integrity sample failed (non-fatal)");
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
let bootTimer: ReturnType<typeof setTimeout> | null = null;
|
|
145
|
-
let pollTimer: ReturnType<typeof setInterval> | null = null;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Start the integrity sampler in the monitor process. No-op in dev mode
|
|
149
|
-
* (CADET_DEV=1) and idempotent if already started.
|
|
150
|
-
*/
|
|
151
|
-
export function startDbIntegritySampler(): void {
|
|
152
|
-
if (process.env.CADET_DEV === "1" || pollTimer) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
bootTimer = setTimeout(() => void sampleDbIntegrityIfDue(), BOOT_DELAY_MS);
|
|
156
|
-
bootTimer.unref?.();
|
|
157
|
-
pollTimer = setInterval(
|
|
158
|
-
() => void sampleDbIntegrityIfDue(),
|
|
159
|
-
POLL_INTERVAL_MS,
|
|
160
|
-
);
|
|
161
|
-
pollTimer.unref?.();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/** Stop the sampler loop and any in-flight check subprocess. Idempotent. */
|
|
165
|
-
export function stopDbIntegritySampler(): void {
|
|
166
|
-
if (bootTimer) {
|
|
167
|
-
clearTimeout(bootTimer);
|
|
168
|
-
bootTimer = null;
|
|
169
|
-
}
|
|
170
|
-
if (pollTimer) {
|
|
171
|
-
clearInterval(pollTimer);
|
|
172
|
-
pollTimer = null;
|
|
173
|
-
}
|
|
174
|
-
activeChild?.kill();
|
|
175
|
-
activeChild = null;
|
|
176
|
-
}
|
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reports kernel OOM kills in this container as `oom_kill` watchdog events.
|
|
3
|
-
*
|
|
4
|
-
* The log comes from `dmesg`, not `/dev/kmsg`: the device is not mounted in
|
|
5
|
-
* the container, while `dmesg` uses the syslog syscall the container is
|
|
6
|
-
* allowed. The log is per kernel, not per container. A kill is this
|
|
7
|
-
* container's when the kernel's `oom-kill:` header names a cgroup carrying
|
|
8
|
-
* this container's id, which the container learns from its own mount table
|
|
9
|
-
* since `/proc/self/cgroup` reads `/` inside a cgroup namespace. The kernel
|
|
10
|
-
* rate-limits that header in a burst, so header-less kills fall back to the
|
|
11
|
-
* cgroup `memory.events` counter.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
15
|
-
import { dirname, join } from "node:path";
|
|
16
|
-
|
|
17
|
-
import { getRawShareAnalytics } from "../cloud/consent-cache.js";
|
|
18
|
-
import { recordWatchdogEvent } from "../telemetry/watchdog-events-store.js";
|
|
19
|
-
import { getContainerMemoryEvents } from "../util/cgroup-memory.js";
|
|
20
|
-
import { getLogger } from "../util/logger.js";
|
|
21
|
-
import { DAEMON_OOM_SCORE_ADJ } from "../util/oom-priority.js";
|
|
22
|
-
import { getMonitoringDataDir } from "../util/platform.js";
|
|
23
|
-
import type { ResourceSample } from "./resource-sample-types.js";
|
|
24
|
-
|
|
25
|
-
const log = getLogger("oom-kill-reporter");
|
|
26
|
-
|
|
27
|
-
export const OOM_KILL_CHECK_NAME = "oom_kill";
|
|
28
|
-
const CURSOR_FILENAME = "oom-kill-cursor.json";
|
|
29
|
-
/** Cadence for hosts without `memory.events`. */
|
|
30
|
-
const FALLBACK_SCAN_INTERVAL_MS = 60_000;
|
|
31
|
-
/** The detail bag is capped at 4 KiB server-side. */
|
|
32
|
-
const MAX_VICTIMS_IN_DETAIL = 10;
|
|
33
|
-
const DMESG_TIMEOUT_MS = 5_000;
|
|
34
|
-
/** Mounts whose source path the container runtime names after the container. */
|
|
35
|
-
const CONTAINER_ID_MOUNTPOINTS = new Set([
|
|
36
|
-
"/etc/hosts",
|
|
37
|
-
"/etc/hostname",
|
|
38
|
-
"/etc/resolv.conf",
|
|
39
|
-
"/dev/termination-log",
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
export interface KernelLogEntry {
|
|
43
|
-
/** Seconds since boot, monotonic for the life of the kernel. */
|
|
44
|
-
time: number;
|
|
45
|
-
msg: string;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface OomKill {
|
|
49
|
-
time: number;
|
|
50
|
-
pid: number;
|
|
51
|
-
comm: string;
|
|
52
|
-
oomScoreAdj: number | null;
|
|
53
|
-
anonRssKb: number | null;
|
|
54
|
-
totalVmKb: number | null;
|
|
55
|
-
/** Victim's cgroup from the `oom-kill:` header; null when the header was rate-limited away. */
|
|
56
|
-
memcg: string | null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
type Attribution = "cgroup" | "cgroup_counter" | "kernel_log";
|
|
60
|
-
|
|
61
|
-
/** `dmesg --json`: `{"dmesg":[{"pri":3,"time":44170.542,"msg":"..."}]}`. */
|
|
62
|
-
export function parseDmesgJson(text: string): KernelLogEntry[] | null {
|
|
63
|
-
try {
|
|
64
|
-
const parsed: unknown = JSON.parse(text);
|
|
65
|
-
const rows = (parsed as { dmesg?: unknown }).dmesg;
|
|
66
|
-
if (!Array.isArray(rows)) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
const entries: KernelLogEntry[] = [];
|
|
70
|
-
for (const row of rows) {
|
|
71
|
-
const { time, msg } = row as { time?: unknown; msg?: unknown };
|
|
72
|
-
if (typeof time === "number" && typeof msg === "string") {
|
|
73
|
-
entries.push({ time, msg });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return entries;
|
|
77
|
-
} catch {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Plain `dmesg`: `[ 44170.542000] message` per line. */
|
|
83
|
-
export function parseDmesgText(text: string): KernelLogEntry[] {
|
|
84
|
-
const entries: KernelLogEntry[] = [];
|
|
85
|
-
for (const line of text.split("\n")) {
|
|
86
|
-
const match = /^\[\s*(\d+\.\d+)\]\s?(.*)$/.exec(line);
|
|
87
|
-
if (match) {
|
|
88
|
-
entries.push({ time: parseFloat(match[1]), msg: match[2] });
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return entries;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const OOM_KILL_RE = /[Oo]ut of memory: Killed process (\d+) \(([^)]*)\)(.*)$/;
|
|
95
|
-
const OOM_HEADER_RE = /^oom-kill:.*task_memcg=([^,]*),task=[^,]*,pid=(\d+)/;
|
|
96
|
-
|
|
97
|
-
function kb(fields: string, key: string): number | null {
|
|
98
|
-
const match = new RegExp(`${key}:(\\d+)kB`).exec(fields);
|
|
99
|
-
return match ? parseInt(match[1], 10) : null;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function oomKillsFromEntries(entries: KernelLogEntry[]): OomKill[] {
|
|
103
|
-
const sorted = [...entries].sort((a, b) => a.time - b.time);
|
|
104
|
-
// The header precedes its "Killed process" line and names the same pid.
|
|
105
|
-
const memcgByPid = new Map<number, string>();
|
|
106
|
-
const kills: OomKill[] = [];
|
|
107
|
-
for (const entry of sorted) {
|
|
108
|
-
const header = OOM_HEADER_RE.exec(entry.msg);
|
|
109
|
-
if (header) {
|
|
110
|
-
memcgByPid.set(parseInt(header[2], 10), header[1]);
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
const kill = OOM_KILL_RE.exec(entry.msg);
|
|
114
|
-
if (!kill) {
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
const pid = parseInt(kill[1], 10);
|
|
118
|
-
const fields = kill[3];
|
|
119
|
-
const adj = /oom_score_adj:(-?\d+)/.exec(fields);
|
|
120
|
-
kills.push({
|
|
121
|
-
time: entry.time,
|
|
122
|
-
pid,
|
|
123
|
-
comm: kill[2],
|
|
124
|
-
oomScoreAdj: adj ? parseInt(adj[1], 10) : null,
|
|
125
|
-
anonRssKb: kb(fields, "anon-rss"),
|
|
126
|
-
totalVmKb: kb(fields, "total-vm"),
|
|
127
|
-
memcg: memcgByPid.get(pid) ?? null,
|
|
128
|
-
});
|
|
129
|
-
memcgByPid.delete(pid);
|
|
130
|
-
}
|
|
131
|
-
return kills;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** Null when `dmesg` is absent or lacks CAP_SYSLOG. */
|
|
135
|
-
export async function readKernelLog(): Promise<KernelLogEntry[] | null> {
|
|
136
|
-
if (process.platform !== "linux") {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
const run = async (args: string[]): Promise<string | null> => {
|
|
140
|
-
try {
|
|
141
|
-
const proc = Bun.spawn(["dmesg", ...args], {
|
|
142
|
-
stdout: "pipe",
|
|
143
|
-
stderr: "ignore",
|
|
144
|
-
windowsHide: true,
|
|
145
|
-
timeout: DMESG_TIMEOUT_MS,
|
|
146
|
-
});
|
|
147
|
-
const text = await new Response(proc.stdout).text();
|
|
148
|
-
return (await proc.exited) === 0 ? text : null;
|
|
149
|
-
} catch {
|
|
150
|
-
return null;
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
const json = await run(["--json"]);
|
|
154
|
-
const fromJson = json != null ? parseDmesgJson(json) : null;
|
|
155
|
-
if (fromJson) {
|
|
156
|
-
return fromJson;
|
|
157
|
-
}
|
|
158
|
-
const text = await run([]);
|
|
159
|
-
return text != null ? parseDmesgText(text) : null;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Container ids from `/proc/self/mountinfo`: the runtime names the source of
|
|
164
|
-
* the hosts, hostname, resolv.conf and termination-log mounts after the
|
|
165
|
-
* container (Kata: `<id>-<hash>-hosts`; Docker: `.../containers/<id>/hosts`).
|
|
166
|
-
*/
|
|
167
|
-
export function parseOwnContainerIds(mountinfo: string): Set<string> {
|
|
168
|
-
const ids = new Set<string>();
|
|
169
|
-
for (const line of mountinfo.split("\n")) {
|
|
170
|
-
const fields = line.split(" ");
|
|
171
|
-
if (fields.length < 5 || !CONTAINER_ID_MOUNTPOINTS.has(fields[4])) {
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
for (const id of line.match(/[0-9a-f]{64}/g) ?? []) {
|
|
175
|
-
ids.add(id);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return ids;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function readOwnContainerIds(): Set<string> {
|
|
182
|
-
try {
|
|
183
|
-
return parseOwnContainerIds(readFileSync("/proc/self/mountinfo", "utf-8"));
|
|
184
|
-
} catch {
|
|
185
|
-
return new Set();
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function readBootId(): string | null {
|
|
190
|
-
try {
|
|
191
|
-
return readFileSync("/proc/sys/kernel/random/boot_id", "utf-8").trim();
|
|
192
|
-
} catch {
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
interface Cursor {
|
|
198
|
-
bootId: string | null;
|
|
199
|
-
lastTime: number;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function readCursor(path: string): Cursor | null {
|
|
203
|
-
try {
|
|
204
|
-
const parsed = JSON.parse(readFileSync(path, "utf-8")) as Partial<Cursor>;
|
|
205
|
-
if (typeof parsed.lastTime === "number") {
|
|
206
|
-
return { bootId: parsed.bootId ?? null, lastTime: parsed.lastTime };
|
|
207
|
-
}
|
|
208
|
-
} catch {
|
|
209
|
-
// Missing or unreadable.
|
|
210
|
-
}
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function writeCursor(path: string, cursor: Cursor): void {
|
|
215
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
216
|
-
writeFileSync(path, JSON.stringify(cursor));
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function memcgIsOurs(memcg: string, ids: ReadonlySet<string>): boolean {
|
|
220
|
-
for (const id of ids) {
|
|
221
|
-
if (memcg.includes(id)) {
|
|
222
|
-
return true;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return false;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export interface OomKillReporterOptions {
|
|
229
|
-
readKernelLog?: () => Promise<KernelLogEntry[] | null>;
|
|
230
|
-
/** Cumulative cgroup oom_kill count, read after the log so it covers every logged kill. */
|
|
231
|
-
readKillCounter?: () => number | null;
|
|
232
|
-
readOwnContainerIds?: () => ReadonlySet<string>;
|
|
233
|
-
readBootId?: () => string | null;
|
|
234
|
-
shareAnalytics?: () => boolean | null;
|
|
235
|
-
cursorPath?: string;
|
|
236
|
-
record?: typeof recordWatchdogEvent;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export interface OomKillReport {
|
|
240
|
-
attribution: Attribution;
|
|
241
|
-
victims: OomKill[];
|
|
242
|
-
/** Kills the counter saw that the log could not name. */
|
|
243
|
-
unnamed: number;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export interface OomKillReporter {
|
|
247
|
-
/** Returns what was queued, for tests. */
|
|
248
|
-
check(
|
|
249
|
-
sample: ResourceSample,
|
|
250
|
-
now: number,
|
|
251
|
-
daemonPid: number | null,
|
|
252
|
-
): Promise<OomKillReport | null>;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export function createOomKillReporter(
|
|
256
|
-
options: OomKillReporterOptions = {},
|
|
257
|
-
): OomKillReporter {
|
|
258
|
-
const read = options.readKernelLog ?? readKernelLog;
|
|
259
|
-
const readKillCounter =
|
|
260
|
-
options.readKillCounter ??
|
|
261
|
-
(() => getContainerMemoryEvents()?.oomKill ?? null);
|
|
262
|
-
const ownIds = options.readOwnContainerIds ?? readOwnContainerIds;
|
|
263
|
-
const bootId = options.readBootId ?? readBootId;
|
|
264
|
-
const shareAnalytics = options.shareAnalytics ?? getRawShareAnalytics;
|
|
265
|
-
const cursorPath =
|
|
266
|
-
options.cursorPath ?? join(getMonitoringDataDir(), CURSOR_FILENAME);
|
|
267
|
-
const record = options.record ?? recordWatchdogEvent;
|
|
268
|
-
|
|
269
|
-
let firstScan = true;
|
|
270
|
-
let lastScanAt = 0;
|
|
271
|
-
let lastKillCounter: number | null = null;
|
|
272
|
-
/**
|
|
273
|
-
* Counter credit with no log line yet: the kernel prints the kill line
|
|
274
|
-
* before it increments the counter, so a kill between the log read and the
|
|
275
|
-
* counter read is counted but not yet visible. Credit is spent on the next
|
|
276
|
-
* scan and reported as unnamed if still unspent, so a kill that never logs
|
|
277
|
-
* a line cannot claim a neighbour's later.
|
|
278
|
-
*/
|
|
279
|
-
let owed = 0;
|
|
280
|
-
/** A scan was skipped mid-way; the next tick scans regardless of the sampler. */
|
|
281
|
-
let scanDue = false;
|
|
282
|
-
/** A report the telemetry store refused; retried before the next scan. */
|
|
283
|
-
let pending: {
|
|
284
|
-
report: OomKillReport;
|
|
285
|
-
sample: ResourceSample;
|
|
286
|
-
daemonPid: number | null;
|
|
287
|
-
cursor: Cursor;
|
|
288
|
-
} | null = null;
|
|
289
|
-
|
|
290
|
-
const queue = (
|
|
291
|
-
report: OomKillReport,
|
|
292
|
-
sample: ResourceSample,
|
|
293
|
-
daemonPid: number | null,
|
|
294
|
-
cursor: Cursor,
|
|
295
|
-
): boolean => {
|
|
296
|
-
if (shareAnalytics() === false) {
|
|
297
|
-
writeCursor(cursorPath, cursor);
|
|
298
|
-
return true;
|
|
299
|
-
}
|
|
300
|
-
const killedDaemon = report.victims.some(
|
|
301
|
-
(kill) =>
|
|
302
|
-
kill.oomScoreAdj === DAEMON_OOM_SCORE_ADJ ||
|
|
303
|
-
(daemonPid != null && kill.pid === daemonPid),
|
|
304
|
-
);
|
|
305
|
-
const detail = {
|
|
306
|
-
attribution: report.attribution,
|
|
307
|
-
victim_count: report.victims.length + report.unnamed,
|
|
308
|
-
unnamed_victims: report.unnamed,
|
|
309
|
-
victims: report.victims.slice(-MAX_VICTIMS_IN_DETAIL).map((kill) => ({
|
|
310
|
-
pid: kill.pid,
|
|
311
|
-
comm: kill.comm,
|
|
312
|
-
oom_score_adj: kill.oomScoreAdj,
|
|
313
|
-
anon_rss_kb: kill.anonRssKb,
|
|
314
|
-
total_vm_kb: kill.totalVmKb,
|
|
315
|
-
})),
|
|
316
|
-
daemon_pid: daemonPid,
|
|
317
|
-
killed_daemon: killedDaemon,
|
|
318
|
-
memory_current_bytes: sample.memory?.currentBytes ?? null,
|
|
319
|
-
memory_limit_bytes: sample.memory?.limitBytes ?? null,
|
|
320
|
-
memory_peak_bytes: sample.memory?.peakBytes ?? null,
|
|
321
|
-
};
|
|
322
|
-
const queued = record({
|
|
323
|
-
checkName: OOM_KILL_CHECK_NAME,
|
|
324
|
-
value: detail.victim_count,
|
|
325
|
-
detail,
|
|
326
|
-
});
|
|
327
|
-
if (!queued) {
|
|
328
|
-
return false;
|
|
329
|
-
}
|
|
330
|
-
writeCursor(cursorPath, cursor);
|
|
331
|
-
log.warn(detail, "Kernel OOM kill in the assistant container");
|
|
332
|
-
return true;
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
return {
|
|
336
|
-
async check(sample, now, daemonPid) {
|
|
337
|
-
if (pending) {
|
|
338
|
-
if (
|
|
339
|
-
!queue(
|
|
340
|
-
pending.report,
|
|
341
|
-
pending.sample,
|
|
342
|
-
pending.daemonPid,
|
|
343
|
-
pending.cursor,
|
|
344
|
-
)
|
|
345
|
-
) {
|
|
346
|
-
return null;
|
|
347
|
-
}
|
|
348
|
-
pending = null;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
const sampleDelta = sample.deltas?.events?.oomKill ?? 0;
|
|
352
|
-
if (
|
|
353
|
-
!firstScan &&
|
|
354
|
-
!scanDue &&
|
|
355
|
-
sampleDelta === 0 &&
|
|
356
|
-
now - lastScanAt < FALLBACK_SCAN_INTERVAL_MS
|
|
357
|
-
) {
|
|
358
|
-
return null;
|
|
359
|
-
}
|
|
360
|
-
scanDue = false;
|
|
361
|
-
|
|
362
|
-
const entries = await read();
|
|
363
|
-
const currentBootId = bootId();
|
|
364
|
-
if (entries == null) {
|
|
365
|
-
firstScan = false;
|
|
366
|
-
lastScanAt = now;
|
|
367
|
-
lastKillCounter = readKillCounter() ?? lastKillCounter;
|
|
368
|
-
if (sampleDelta === 0) {
|
|
369
|
-
return null;
|
|
370
|
-
}
|
|
371
|
-
const report: OomKillReport = {
|
|
372
|
-
attribution: "cgroup_counter",
|
|
373
|
-
victims: [],
|
|
374
|
-
unnamed: sampleDelta,
|
|
375
|
-
};
|
|
376
|
-
const cursor = { bootId: currentBootId, lastTime: 0 };
|
|
377
|
-
if (!queue(report, sample, daemonPid, cursor)) {
|
|
378
|
-
pending = { report, sample, daemonPid, cursor };
|
|
379
|
-
}
|
|
380
|
-
return report;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Read after the log so the count covers every line the log holds.
|
|
384
|
-
const killCounter = readKillCounter();
|
|
385
|
-
if (killCounter == null && sample.events != null) {
|
|
386
|
-
// One failed read of a counter that exists: try again next tick
|
|
387
|
-
// rather than treating every kill on the kernel as ours.
|
|
388
|
-
scanDue = true;
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
|
-
const isFirstScan = firstScan;
|
|
392
|
-
firstScan = false;
|
|
393
|
-
lastScanAt = now;
|
|
394
|
-
const counterDelta =
|
|
395
|
-
killCounter != null && lastKillCounter != null
|
|
396
|
-
? Math.max(0, killCounter - lastKillCounter)
|
|
397
|
-
: null;
|
|
398
|
-
lastKillCounter = killCounter ?? lastKillCounter;
|
|
399
|
-
|
|
400
|
-
const all = oomKillsFromEntries(entries);
|
|
401
|
-
const maxTime = all.length > 0 ? all[all.length - 1].time : 0;
|
|
402
|
-
const stored = readCursor(cursorPath);
|
|
403
|
-
// A different boot id, or a log that has not yet reached the stored
|
|
404
|
-
// timestamp, means the kernel restarted and the cursor is stale.
|
|
405
|
-
const sameBoot =
|
|
406
|
-
stored != null &&
|
|
407
|
-
stored.bootId === currentBootId &&
|
|
408
|
-
maxTime >= stored.lastTime;
|
|
409
|
-
const sinceTime = sameBoot ? stored.lastTime : -1;
|
|
410
|
-
const fresh = all.filter((kill) => kill.time > sinceTime);
|
|
411
|
-
const cursor: Cursor = {
|
|
412
|
-
bootId: currentBootId,
|
|
413
|
-
lastTime: Math.max(sinceTime, maxTime),
|
|
414
|
-
};
|
|
415
|
-
const ids = ownIds();
|
|
416
|
-
|
|
417
|
-
let report: OomKillReport | null = null;
|
|
418
|
-
if (counterDelta == null || isFirstScan) {
|
|
419
|
-
// No counter to lean on: a kill that took the daemon down restarted
|
|
420
|
-
// this monitor with it, and the new container's counter starts at 0.
|
|
421
|
-
const ours = fresh.filter(
|
|
422
|
-
(kill) => kill.memcg == null || memcgIsOurs(kill.memcg, ids),
|
|
423
|
-
);
|
|
424
|
-
if (ours.length > 0) {
|
|
425
|
-
report = { attribution: "kernel_log", victims: ours, unnamed: 0 };
|
|
426
|
-
}
|
|
427
|
-
owed = 0;
|
|
428
|
-
} else {
|
|
429
|
-
const byHeader = fresh.filter(
|
|
430
|
-
(kill) => kill.memcg != null && memcgIsOurs(kill.memcg, ids),
|
|
431
|
-
);
|
|
432
|
-
const unknown = fresh.filter((kill) => kill.memcg == null);
|
|
433
|
-
// Header-attributed kills spend counter credit first; what is left
|
|
434
|
-
// names header-less kills oldest first. Header-less kills beyond the
|
|
435
|
-
// credit are neighbours', since our counter would have covered ours.
|
|
436
|
-
const carry = owed;
|
|
437
|
-
let credit = counterDelta + carry - byHeader.length;
|
|
438
|
-
const byCounter = unknown.slice(0, Math.max(0, credit));
|
|
439
|
-
credit = Math.max(0, credit - byCounter.length);
|
|
440
|
-
owed = Math.min(credit, counterDelta);
|
|
441
|
-
const unnamed = credit - owed;
|
|
442
|
-
const victims = [...byHeader, ...byCounter].sort(
|
|
443
|
-
(a, b) => a.time - b.time,
|
|
444
|
-
);
|
|
445
|
-
if (victims.length > 0 || unnamed > 0) {
|
|
446
|
-
report = {
|
|
447
|
-
attribution:
|
|
448
|
-
byCounter.length === 0 && unnamed === 0
|
|
449
|
-
? "cgroup"
|
|
450
|
-
: "cgroup_counter",
|
|
451
|
-
victims,
|
|
452
|
-
unnamed,
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
if (report == null) {
|
|
458
|
-
if (!sameBoot || cursor.lastTime !== stored?.lastTime) {
|
|
459
|
-
writeCursor(cursorPath, cursor);
|
|
460
|
-
}
|
|
461
|
-
return null;
|
|
462
|
-
}
|
|
463
|
-
if (!queue(report, sample, daemonPid, cursor)) {
|
|
464
|
-
pending = { report, sample, daemonPid, cursor };
|
|
465
|
-
}
|
|
466
|
-
return report;
|
|
467
|
-
},
|
|
468
|
-
};
|
|
469
|
-
}
|