feat(07-02): wire sweepStaleReviews into heartbeat timer
- Import sweepStaleReviews, resolveApprovalDecision, dispatchAgentMessage - Insert stale review sweep into per-company heartbeat loop after budget reset - Sweep runs on every 15-second heartbeat cycle for each active company - Local callback stubs for handleTaskStatusChange and handleApprovalResolved - Error handling prevents sweep failures from crashing the heartbeat loop - Fix test type casts to use as-unknown-as for vi.fn mock compatibility - TypeScript compiles cleanly, 249/249 tests pass Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
0bfbdec09b
commit
c4eb4423db
2 files changed
+38
-7
No files matched your search
@@ -237,7 +237,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("escalates to manager's manager when task in_review for 35 minutes", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
|
||||
// Task in review for 35 min
|
||||
dbMock.queryAll.mockReturnValueOnce([
|
||||
@@ -265,7 +265,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("does not escalate when task in_review for only 25 minutes (under threshold)", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn> };
|
||||
|
||||
dbMock.queryAll.mockReturnValueOnce([
|
||||
{ id: "task-1", assigneeAgentId: "agent-1", updatedAt: TWENTY_FIVE_MIN_AGO, title: "Build login" },
|
||||
@@ -279,7 +279,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("notifies human when no higher manager (reviewer is CEO)", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
|
||||
dbMock.queryAll
|
||||
.mockReturnValueOnce([
|
||||
@@ -305,7 +305,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("auto-approves pending approval linked to stale review task", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
|
||||
// First queryAll: stale task
|
||||
dbMock.queryAll.mockReturnValueOnce([
|
||||
@@ -332,7 +332,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("catches resolveApprovalDecision error gracefully (race condition)", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn> };
|
||||
|
||||
dbMock.queryAll.mockReturnValueOnce([
|
||||
{ id: "task-1", assigneeAgentId: "agent-1", updatedAt: THIRTY_FIVE_MIN_AGO, title: "Build login" },
|
||||
@@ -352,7 +352,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("advances task status to done after escalation", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn>; advanceTaskStatus: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn>; getManagerForAgent: ReturnType<typeof vi.fn>; getChainOfCommand: ReturnType<typeof vi.fn>; advanceTaskStatus: ReturnType<typeof vi.fn> };
|
||||
|
||||
dbMock.queryAll.mockReturnValueOnce([
|
||||
{ id: "task-1", assigneeAgentId: "agent-1", updatedAt: THIRTY_FIVE_MIN_AGO, title: "Build login" },
|
||||
@@ -373,7 +373,7 @@ describe("sweepStaleReviews", () => {
|
||||
|
||||
it("skips task with no assigneeAgentId", () => {
|
||||
const deps = makeSweepDeps();
|
||||
const dbMock = deps.db as { queryAll: ReturnType<typeof vi.fn> };
|
||||
const dbMock = deps.db as unknown as { queryAll: ReturnType<typeof vi.fn> };
|
||||
|
||||
dbMock.queryAll.mockReturnValueOnce([
|
||||
{ id: "task-1", assigneeAgentId: null, updatedAt: THIRTY_FIVE_MIN_AGO, title: "Orphan task" },
|
||||
|
||||
Reference in new issue
Block a user