practice bug fix — the boot sweep stamped a LIVE run (owner live test 2026-09-29)
Owner report: created a set, 'Interrupted (server restarted)' showed on list + set views, generation proceeded and overwrote it. The sweep's 'generating + no registry row' test had a false-positive mode: it ran at EVERY pipeline instantiation, and an instance could evaluate against a registry whose fresh row it couldn't observe. Three guards, per ruling: 1. HEARTBEAT: ProblemSet.updatedAt? (contract + doc) — bumped on every store write; createSet stamps it = createdAt; saveSet re-stamps (validator tolerates absence for legacy rows). 2. ONCE PER PROCESS: the sweep guards on globalThis .__lhPracticeSweepDone — no instance re-evaluates after the process's first sweep. 3. GRACE WINDOW: only sets whose heartbeat (updatedAt ?? createdAt) is older than 120s are stamped. A live run saves at every phase/ problem transition, so it is structurally unreachable; a true orphan is minutes stale at next boot. One [practice <id>] log line per stamped set (the extraction/jobs console.error idiom). Tests: stale orphan stamped; FRESH generating set untouched (grace); once-guard (second factory instantiation never re-sweeps); live-row protection re-armed via resetSweep() test seam; store pins for updatedAt birth-stamp + re-stamp + legacy tolerance. Architecture.md sweep sentence updated (once-per-process + grace semantics). 1142/1142, tsc 0, lint 0, build 0.
This commit is contained in:
@@ -42,6 +42,26 @@ const init = (over: Partial<Omit<ProblemSet, "id">> = {}): Omit<ProblemSet, "id"
|
||||
|
||||
// ─── round-trip ──────────────────────────────────────────────────────────────
|
||||
|
||||
describe("updatedAt — the live-run heartbeat", () => {
|
||||
it("createSet stamps updatedAt = createdAt; saveSet re-stamps on every write", () => {
|
||||
const set = practiceStore.createSet(init());
|
||||
assert.equal(set.updatedAt, set.createdAt, "birth stamp");
|
||||
const before = new Date().toISOString();
|
||||
const edited = { ...set, title: "Renamed" };
|
||||
practiceStore.saveSet(edited);
|
||||
const read = practiceStore.getSet(set.id)!
|
||||
assert.ok(read.updatedAt !== undefined && read.updatedAt >= before, "every write re-stamps");
|
||||
assert.notEqual(read.title, set.title);
|
||||
});
|
||||
|
||||
it("legacy rows without updatedAt still validate (readers fall back to createdAt)", () => {
|
||||
const set = practiceStore.createSet(init());
|
||||
const bare = { ...set } as Partial<typeof set>;
|
||||
delete bare.updatedAt;
|
||||
assert.ok(isProblemSet({ ...bare, id: set.id }));
|
||||
});
|
||||
});
|
||||
|
||||
describe("the practice store", () => {
|
||||
it("createSet assigns a ps_ id, mkdirs, and round-trips through getSet", () => {
|
||||
const set = practiceStore.createSet(init());
|
||||
|
||||
Reference in New Issue
Block a user