GitHub
09/15/2026, 7:45 PMQueryRead. Previously, queries expired before the node's next scheduled read on environments with long distributed intervals, forcing operators to refresh repeatedly.
Backend changes
Warmup-aware timeout sizing (cmd/api/handlers/console.go, file_explorer.go)
• Added warmupQueryWait(env, node), which computes the time remaining until the node's next scheduled QueryRead from node.LastQueryRead + env.QueryInterval, capped by maxWarmupWait (raised from 5 → 10 minutes).
• consoleCommandTimeout, consolePrimingTimeout, and fileExplorerRequestTimeout now take (env, node) and add the warmup wait to their base timeout. Dead/overdue nodes get 0 extra wait so they still fail fast.
• Console command submit now resolves the session's node (sessionNode) before sizing the timeout.
• Refactored accelerated-interval lookup into shared acceleratedQueryReadSeconds().
last_query_read tracking (pkg/nodes/checkins.go, models.go, cmd/tls/handlers/post.go, writers.go)
• Added QueryRead bool to `Checkin`; QueryReadHandler flags its check-in event.
• UpdateCheckins now stamps osquery_nodes.last_query_read (new column) for query-read check-ins, with the same monotonic "first writer wins" guard as last_seen.
• Batch writer mergeCheckin preserves the QueryRead marker across merge conflicts.
• OsqueryNode.LastQueryRead is json:"-" (server-side timing data).
expires_at propagation (pkg/console/{manager,models}.go, pkg/fileexplorer/{manager,models}.go)
• Command and Request gained a non-persisted ExpiresAt *time.Time (gorm:"-") mirroring the backing distributed query's expiration.
• Submit paths and `RefreshCommandStatus`/`RefreshRequestStatus` populate it so clients can bound polling to the real deadline.
Frontend changes
File explorer polling (NodeFileExplorerTab.tsx, api/types.ts)
• Replaced the fixed 30-poll cap with a deadline derived from the server's expires_at (+15s grace), falling back to 30 polls only when expires_at is absent.
• ConsoleCommand and FileExplorerRequest types gained optional expires_at.
i18n fix — Recently seen nodes table headers (all 20 locales)
• Added hostname, platform, osquery, ip, tags to the dashboardExt.panels block in every locale file. Only lastSeen had been defined, so the other five headers rendered as raw dashboardExt.panels.* keys. Translations reused each locale's existing nodesPage terminology.
Tests
• console_test.go, file_explorer_test.go, writers_test.go, checkins_test.go, manager_test.go (console + file explorer): added/updated coverage for warmup sizing, last_query_read stamping, QueryRead merge preservation, and expires_at propagation.
• `NodeFileExplorerTab.test.tsx`: added deadline-based polling cases.
• TypeScript check and 415 frontend tests pass; go test ./cmd/api/handlers/ relevant suites pass.
jmpsec/osctrlGitHub
09/15/2026, 7:57 PM