Preserve verified health when provisioning completes

This commit is contained in:
2026-10-06 15:48:38 -04:00
parent 6999a33aef
commit 57d2bd11db
9 changed files with 256 additions and 41 deletions
@@ -0,0 +1,37 @@
import { ONLINE_MAX_MS } from '../../server-freshness.js';
import { monitoringIdentity } from '../fleet/health-observations.js';
import { getServer, setServerFields, type ServerRow } from '../fleet/servers.js';
import { latestGameSubmission, telemetryReport, type VerifiedGameStatus } from '../fleet/status-evidence.js';
import { serverObservation } from '../fleet/status.js';
import { activityFields, successfulStatusFields } from '../fleet/status-updates.js';
/** Called inside the completion transaction; evidence must still describe this process. */
export function handoffVerifiedHealth(server: string, identity: string,
container: { state: string; observedAt: string }, game: VerifiedGameStatus): boolean {
const current = getServer(server);
if (!current || current.desired_state !== 'running' || monitoringIdentity(server) !== identity) return false;
const fresh = (at: string) => {
const age = Date.now() - Date.parse(at);
return age >= 0 && age <= ONLINE_MAX_MS;
};
const gameAt = game.source === 'telemetry' ? game.receivedAt : game.observedAt;
const submission = latestGameSubmission(server);
if (!fresh(container.observedAt) || !fresh(gameAt) || (submission && gameAt <= submission)) return false;
const updates: Partial<ServerRow> = {};
if (!current.container_checked_at || current.container_checked_at <= container.observedAt) {
updates.container_state = container.state;
updates.container_checked_at = container.observedAt;
}
if (game.source === 'rcon' && (!current.last_checked_at || current.last_checked_at <= game.observedAt)) {
Object.assign(updates, successfulStatusFields(game.rcon, game.observedAt));
}
const candidate = { ...current, ...updates };
// Evaluate the health readers will see after the operation and recovery slot
// complete. Newer contradictory evidence must keep verification pending.
const status = serverObservation(candidate, { provisioning: false, settling: false,
submission, telemetry: telemetryReport(server) });
if (status.health !== 'online') return false;
setServerFields(server, { ...updates, ...activityFields(candidate, status) });
return true;
}