Make workspace authoring converge through immutable Nix candidates
Coordinate registered resource edits bottom-up into retained exact remote sources. Use one Nix-owned source graph for provisional checking, template publication, explicit baseline upgrades and host activation; retain independent runtime pins. Add scoped contract inspection, historical recovery, derived worklists, crash-safe locks, named dependency adoption and plain-QX structural editing. Repair TODO ownership and template instantiation, and document the supported agent workflow. Validated with protocol and command suites, real jj/Nix convergence and cache checks, TS/React installed-command acceptance, and fresh TODO first-edit acceptance. No live deployment or public publication performed. Props projection generation and a one-command rich feature generator remain explicitly outside this delivery.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import { spawn } from "node:child_process";
|
||||
|
||||
/** Kernel-owned lock: a crashed coordinator cannot leave a stale ownership file.
|
||||
* The persistent file is just an inode; EOF releases the helper's lock. */
|
||||
export async function withFileLock<T>(filename: string, work: () => Promise<T>): Promise<T> {
|
||||
const child = spawn("flock", ["--exclusive", "--nonblock", "--conflict-exit-code", "75", filename,
|
||||
process.execPath, "-e", 'process.stdout.write("locked\\n"); process.stdin.resume();'], {stdio: ["pipe", "pipe", "pipe"]});
|
||||
let diagnostics = "";
|
||||
child.stdin.on("error", () => { /* acquisition/exit handling reports helper failure */ });
|
||||
child.stderr.on("data", chunk => { diagnostics = (diagnostics + String(chunk)).slice(-2000); });
|
||||
const closed = new Promise<void>((resolve) => { child.once("close", () => resolve()); });
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
let output = "";
|
||||
child.once("error", reject);
|
||||
child.once("exit", code => reject(new Error(code === 75 ? "Another authoring command owns this repository; retry when it finishes" : `Cannot acquire authoring lock: ${diagnostics}`)));
|
||||
child.stdout.on("data", chunk => { output += chunk; if (output.includes("locked\n")) resolve(); });
|
||||
});
|
||||
return await work();
|
||||
} finally { child.stdin.end(); await closed; }
|
||||
}
|
||||
Reference in New Issue
Block a user