feat(FN-1016): add comment-aware triage generation and stale approval invalidation
- Include user comments as context during AI triage spec generation and spec review - Invalidate stale spec approvals when new user comments are added after approval - Add lastApprovedAt tracking to task metadata for approval freshness detection - Add comprehensive tests for comment-aware triage, review, and stale approval logic - Add changeset for published package and update README with feature documentation
This commit is contained in:
@@ -2134,6 +2134,47 @@ Task with acceptance criteria
|
||||
const refinement = allTasksAfter.find((t) => t.id !== task.id && t.title?.includes("Refinement"));
|
||||
expect(refinement).toBeDefined();
|
||||
});
|
||||
|
||||
it("transitions awaiting-approval to needs-respecify when user comments on triage task", async () => {
|
||||
const task = await store.createTask({ description: "Task in triage" });
|
||||
// Keep in triage but set awaiting-approval status
|
||||
await store.updateTask(task.id, { status: "awaiting-approval" });
|
||||
|
||||
const result = await store.addComment(task.id, "I want to change the approach", "user");
|
||||
|
||||
// Re-read the task to get the Phase 3 status update
|
||||
const updated = await store.getTask(task.id);
|
||||
|
||||
// Task should remain in triage but status should change to needs-respecify
|
||||
expect(updated.column).toBe("triage");
|
||||
expect(updated.status).toBe("needs-respecify");
|
||||
// Comment should still be added
|
||||
expect(updated.comments).toHaveLength(1);
|
||||
expect(updated.comments![0].text).toBe("I want to change the approach");
|
||||
});
|
||||
|
||||
it("does NOT transition to needs-respecify when agent comments on awaiting-approval task", async () => {
|
||||
const task = await store.createTask({ description: "Task in triage" });
|
||||
await store.updateTask(task.id, { status: "awaiting-approval" });
|
||||
|
||||
const updated = await store.addComment(task.id, "Agent system note", "agent");
|
||||
|
||||
// Status should remain awaiting-approval for agent comments
|
||||
expect(updated.status).toBe("awaiting-approval");
|
||||
// Comment should still be added
|
||||
expect(updated.comments).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("does NOT transition to needs-respecify when user comments on non-awaiting-approval triage task", async () => {
|
||||
const task = await store.createTask({ description: "Task in triage" });
|
||||
// Task is in triage with no status (not awaiting-approval)
|
||||
expect(task.status).toBeUndefined();
|
||||
|
||||
const updated = await store.addComment(task.id, "User feedback", "user");
|
||||
|
||||
// Status should remain undefined
|
||||
expect(updated.status).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("task comments and merge details types", () => {
|
||||
|
||||
@@ -2388,6 +2388,30 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 3: Invalidate stale spec approval when a user comments on
|
||||
// a triage task that is awaiting manual approval. The new comment
|
||||
// means the spec is now stale and must be re-specified/re-reviewed.
|
||||
// Note: The `task` returned above reflects the state BEFORE this
|
||||
// transition. Callers that need the post-transition status should
|
||||
// re-read the task (e.g., via getTask).
|
||||
if (
|
||||
task.column === "triage"
|
||||
&& task.status === "awaiting-approval"
|
||||
&& author === "user"
|
||||
) {
|
||||
try {
|
||||
await this.updateTask(id, {
|
||||
status: "needs-respecify",
|
||||
});
|
||||
await this.logEntry(
|
||||
id,
|
||||
`User comment invalidated spec approval — task needs re-specification`,
|
||||
);
|
||||
} catch {
|
||||
// Best-effort: don't fail the comment if the status update fails
|
||||
}
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user