fix(FN-8778): preserve planning lock receiver
Fusion-Task-Id: FN-8778
This commit is contained in:
7
.changeset/fn-8778-planning-lock-receiver.md
Normal file
7
.changeset/fn-8778-planning-lock-receiver.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
summary: Prevent planning finalization from crashing after PROMPT.md writes.
|
||||||
|
category: fix
|
||||||
|
dev: Preserves the TaskStore receiver when invoking the planning lifecycle lock.
|
||||||
@@ -3278,9 +3278,23 @@ describe("specified triage recovery", () => {
|
|||||||
it("fences a stale finalizer after dependency re-seed commits before lifecycle-lock acquisition", async () => {
|
it("fences a stale finalizer after dependency re-seed commits before lifecycle-lock acquisition", async () => {
|
||||||
const stalePlannerSnapshot = createTriageTask({ status: "planning" });
|
const stalePlannerSnapshot = createTriageTask({ status: "planning" });
|
||||||
const store = createMockStore({
|
const store = createMockStore({
|
||||||
withPlanningLifecycleLock: vi.fn(async (_id, callback) => callback()),
|
|
||||||
getTask: vi.fn().mockResolvedValue({ ...stalePlannerSnapshot, status: "needs-replan" }),
|
getTask: vi.fn().mockResolvedValue({ ...stalePlannerSnapshot, status: "needs-replan" }),
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
|
* FNXC:PlanningDependencyReseed 2026-08-04-08:04:
|
||||||
|
* Finalization may feature-detect the lifecycle method, but it must invoke
|
||||||
|
* that extracted method with TaskStore as its receiver. The production
|
||||||
|
* method reads instance state (`asyncLayer`); an arrow-function mock hid the
|
||||||
|
* unbound-call crash that stranded FN-8778 after every successful prompt write.
|
||||||
|
*/
|
||||||
|
store.withPlanningLifecycleLock = vi.fn(async function (
|
||||||
|
this: TaskStore,
|
||||||
|
_id: string,
|
||||||
|
callback: () => Promise<unknown>,
|
||||||
|
) {
|
||||||
|
expect(this).toBe(store);
|
||||||
|
return await callback();
|
||||||
|
}) as typeof store.withPlanningLifecycleLock;
|
||||||
const processor = new TriageProcessor(store, rootDir);
|
const processor = new TriageProcessor(store, rootDir);
|
||||||
|
|
||||||
await (processor as unknown as {
|
await (processor as unknown as {
|
||||||
|
|||||||
@@ -4138,7 +4138,7 @@ export class TriageProcessor {
|
|||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
return lifecycleLock
|
return lifecycleLock
|
||||||
? await lifecycleLock(task.id, finalizeUnderLock)
|
? await this.store.withPlanningLifecycleLock(task.id, finalizeUnderLock)
|
||||||
: await finalizeUnderLock();
|
: await finalizeUnderLock();
|
||||||
} finally {
|
} finally {
|
||||||
this.finalizing.delete(task.id);
|
this.finalizing.delete(task.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user