release-2.9.2 (#1566)

* fix: stop full database rewrites on every plugin db call

* fix: restore release video link in 2.9.2 notes

* fix: use TERMIX_PAT in workflows
This commit is contained in:
Luke Gustafson authored and GitHub committed 2026-10-05 20:24:46 -05:00
1 parent 40df00bd95
commit 2b309e9582
19 files changed
+342 -87

No files matched your search

@@ -1,4 +1,15 @@
import { and, asc, desc, eq, gte, inArray, lt, lte, sql } from "drizzle-orm";
import {
and,
asc,
desc,
eq,
gte,
inArray,
isNull,
lt,
lte,
sql,
} from "drizzle-orm";
import { auditLogs } from "../db/schema.js";
import type { DatabaseContext } from "./database-context.js";
import { sqlTimestampDaysAgo } from "./sql-timestamp.js";
@@ -26,6 +37,17 @@ export const AUDIT_RETENTION_DAYS_ENV = "AUDIT_LOG_RETENTION_DAYS";
export const AUDIT_MAX_ENTRIES_ENV = "AUDIT_LOG_MAX_ENTRIES";
const DEFAULT_MAX_ENTRIES = 10000;
// 2.9.1 logged these on every background plugin query and pushed real
// entries out of the capped log. They are now audited once per activation.
export const ROUTINE_PLUGIN_AUDIT_ACTIONS = [
"plugin_db_client",
"plugin_db_refs",
"plugin_kv_get",
"plugin_kv_list",
"plugin_files_data_dir",
"plugin_settings_read_core",
];
const PRUNE_TARGET_RATIO = 0.9;
function positiveIntEnv(key: string, env: NodeJS.ProcessEnv): number | null {
@@ -166,6 +188,24 @@ export class AuditLogRepository {
return rowsAffected(result);
}
async deleteRoutinePluginNoise(): Promise<number> {
AuditLogRepository.cachedCount = null;
const result = await this.context.drizzle
.delete(auditLogs)
.where(
and(
isNull(auditLogs.userId),
inArray(auditLogs.action, ROUTINE_PLUGIN_AUDIT_ACTIONS),
),
);
if (rowsAffected(result) > 0) {
await this.afterWrite();
}
return rowsAffected(result);
}
private buildWhere(filters: AuditLogFilters) {
const conditions = [];
+3 -2
View File
@@ -78,7 +78,7 @@ export function createCurrentRepositoryWriteHook(
*
* Marks the in-memory database dirty and lets DatabaseSaveTrigger's existing
* debounce coalesce the actual serialize+encrypt, instead of forcing one on
* every single sample. A lost 2-second window of telemetry on crash is
* every single sample. Losing up to 30 seconds of these on a crash is
* acceptable; blocking the event loop that serves SSH traffic on every metric
* sample is not.
*/
@@ -128,7 +128,8 @@ export function createCurrentApiKeyRepository(): ApiKeyRepository {
export function createCurrentAuditLogRepository(): AuditLogRepository {
return new AuditLogRepository(
createCurrentRepositoryContext(),
createCurrentRepositoryWriteHook("audit_log_repository_write"),
// Rows land on every audited call; the audited action saves on its own.
createCurrentRepositoryLazyWriteHook("audit_log_repository_write"),
);
}