feat(FN-4083): add WAL enforcement, immediate write transactions, and concu

Hardened SQLite concurrent-write safety in `@fusion/core` by auditing WAL enforcement and adding immediate write transactions to prevent stale reads under load, with executor semaphore limit tests in `@fusion/engine` validating the concurrency bounds; added a new `store-concurrent-writes.test.ts` in

Fusion-Task-Id: FN-4083

Fusion-Task-Lineage: adabe51a-a9c4-481a-850d-985c373df51a
This commit is contained in:
Fusion
2026-05-12 03:23:06 -07:00
committed by gsxdsm
parent b1a0464d68
commit 06feb61686
14 changed files with 384 additions and 30 deletions

View File

@@ -199,6 +199,32 @@ describe("AgentSemaphore", () => {
expect(sem.activeCount).toBe(0);
});
it("keeps executor-style write sections within the configured execute concurrency", async () => {
const sem = new AgentSemaphore(2);
let concurrentWrites = 0;
let maxConcurrentWrites = 0;
const performWrite = (taskId: string) =>
sem.run(async () => {
concurrentWrites += 1;
maxConcurrentWrites = Math.max(maxConcurrentWrites, concurrentWrites);
await new Promise((resolve) => setTimeout(resolve, 10));
concurrentWrites -= 1;
return taskId;
}, PRIORITY_EXECUTE);
const completed = await Promise.all([
performWrite("FN-1"),
performWrite("FN-2"),
performWrite("FN-3"),
performWrite("FN-4"),
]);
expect(completed).toEqual(["FN-1", "FN-2", "FN-3", "FN-4"]);
expect(maxConcurrentWrites).toBe(2);
expect(sem.activeCount).toBe(0);
});
it("integration: shared semaphore limits triage + execution + merge together", async () => {
const sem = new AgentSemaphore(2);
let concurrent = 0;

View File

@@ -65,9 +65,11 @@ describe("hydrateWorktreeDb", () => {
const db = new DatabaseSync(join(worktree, ".fusion", "fusion.db"));
const tasks = (db.prepare("SELECT COUNT(*) as c FROM tasks WHERE id IN ('FN-A','FN-B','FN-C')").get() as any).c;
const docs = (db.prepare("SELECT COUNT(*) as c FROM task_documents WHERE taskId='FN-B'").get() as any).c;
const journalMode = db.prepare("PRAGMA journal_mode").get() as { journal_mode: string };
db.close();
expect(tasks).toBe(3);
expect(docs).toBe(1);
expect(journalMode.journal_mode).toBe("wal");
});
it("no-op when rootDir === worktreePath", async () => {

View File

@@ -113,8 +113,10 @@ export async function hydrateWorktreeDb({
}
srcDb = new DatabaseSync(srcDbPath);
srcDb.exec("PRAGMA busy_timeout = 5000");
dstDb = openWorktreeDbWithRecovery(dstDbPath, worktreePath);
dstDb.exec("PRAGMA busy_timeout = 5000");
dstDb.exec("PRAGMA journal_mode = WAL");
const srcTaskCols = getColumns(srcDb, "tasks");