fix(server): preserve live instruction locks

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-07 08:18:32 +00:00
1 parent 23b4420dbd
commit c4e01860f7
2 files changed
+9 -11

No files matched your search

@@ -667,7 +667,7 @@ describe("agent instructions service", () => {
});
it.skipIf(process.platform !== "linux")(
"does not evict a live lock when process identity falls back to another scheme",
"does not evict a live lock with a stale heartbeat when identity falls back to another scheme",
async () => {
const paperclipHome = await makeTempDir("paperclip-agent-instructions-marker-fallback-");
cleanupDirs.add(paperclipHome);
@@ -698,7 +698,10 @@ describe("agent instructions service", () => {
})}\n`,
"utf8",
);
await fs.writeFile(path.join(lockPath, `heartbeat-${token}`), "", "utf8");
const heartbeatPath = path.join(lockPath, `heartbeat-${token}`);
await fs.writeFile(heartbeatPath, "", "utf8");
const staleHeartbeat = new Date(Date.now() - 60_000);
await fs.utimes(heartbeatPath, staleHeartbeat, staleHeartbeat);
const materialization = svc.materializeManagedBundle(agent, { "AGENTS.md": "# Stock\n" });
const firstOutcome = await Promise.race([
+4 -9
View File
@@ -278,15 +278,11 @@ async function removeStaleManagedBundleLock(lockPath: string): Promise<boolean>
ownerSnapshot = await fs.readFile(path.join(lockPath, "owner.json"), "utf8");
const owner = JSON.parse(ownerSnapshot) as {
pid?: unknown;
token?: unknown;
processStartMarker?: unknown;
};
const pid = typeof owner.pid === "number" && Number.isInteger(owner.pid) && owner.pid > 0
? owner.pid
: null;
const token = typeof owner.token === "string" && /^[0-9a-f-]{36}$/i.test(owner.token)
? owner.token
: null;
if (pid !== null && isProcessAlive(pid)) {
const recordedStart = typeof owner.processStartMarker === "string"
? owner.processStartMarker
@@ -298,12 +294,11 @@ async function removeStaleManagedBundleLock(lockPath: string): Promise<boolean>
&& processStartMarkersComparable(recordedStart, currentStart)
) {
shouldRemove = recordedStart !== currentStart;
} else if (token) {
shouldRemove = await managedBundleLockAgeMs(
path.join(lockPath, `heartbeat-${token}`),
) > MANAGED_BUNDLE_LOCK_STALE_MS;
} else {
shouldRemove = await managedBundleLockAgeMs(lockPath) > MANAGED_BUNDLE_LOCK_STALE_MS;
// A delayed heartbeat does not prove that a live process has stopped
// materializing. Only a comparable process-start marker can safely
// distinguish a reused PID from the original owner.
shouldRemove = false;
}
} else if (pid !== null) {
shouldRemove = true;