feat(FN-2956): merge fusion/fn-2956

- **FN-2956: Node routing policy guard** — `scheduler.ts` and `agent-heartbeat.ts` now enforce unavailable-node dispatch prevention; adds policy-matrix unit tests (`node-routing-policy.test.ts`) and integration tests (`scheduler-node-routing.test.ts`)
- **Agent delegation tools** — `agent-tools.ts` gains delegation functionality; `agent-heartbeat.ts` updated with monitoring hooks; 37 new lines of test coverage in `agent-tools.test.ts`
- **Dashboard route registration** — New routes added for git/github registration (`register-git-github.ts`), planning subtasks, and task workflows; test coverage in `routes.test.ts`
- **CLI task planning** — `task.ts` and `extension.ts` updated to support task planning flow; task-plan test extended
- **Engine integrations** — `cron-runner.ts`, `pr-comment-handler.ts`, `triage.ts`, `mission-execution-loop.ts`, `project-engine.ts`, and `routine-runner.ts` all updated with expanded tests and feature hooks
- **Dashboard UI/hooks** — `useTaskHandlers.ts` and related tests updated; `ModelOnboardingModal.tsx` and `TodoView.tsx` refined; CSS adjustments in `AgentsView.css`
- Includes merged work from `fusion/fn-2923` and `fusion/fn-2945`

Commits merged:
- test(FN-2956): complete Step 4 — align scheduler routing policy integration tests
- test(FN-2956): complete Step 3 — expand policy matrix unit coverage
- feat(FN-2956): complete Step 2 — enforce unavailable-node policy dispatch guard
- feat(FN-2923): merge fusion/fn-2923
- feat(FN-2945): merge fusion/fn-2945

Files changed:
packages/cli/src/__tests__/task-plan.test.ts       |  1 +
 packages/cli/src/commands/__tests__/task.test.ts   | 15 +++++++--
 packages/cli/src/commands/task.ts                  | 15 ++++++++-
 packages/cli/src/extension.ts                      |  9 ++++++
 .../app/__tests__/agent-css-classes.test.ts        |  3 +-
 packages/dashboard/app/__tests__/api.test.ts       | 13 ++++++++
 packages/dashboard/app/api/legacy.ts               |  2 ++
 packages/dashboard/app/components/AgentsView.css   | 22 ++++++-------
 .../app/components/ModelOnboardingModal.tsx        |  5 ++-
 packages/dashboard/app/components/TodoView.tsx     |  2 ++
 .../__tests__/ModelOnboardingModal.test.tsx        |  4 +--
 .../app/components/__tests__/QuickChatFAB.test.tsx | 14 ++------
 .../app/components/__tests__/TodoView.test.tsx     |  4 +--
 .../__tests__/agents-view-mobile.test.tsx          |  5 ++-
 .../components/__tests__/onboarding-flow.test.tsx  |  2 +-
 .../app/hooks/__tests__/useTaskHandlers.test.ts    |  4 +--
 packages/dashboard/app/hooks/useTaskHandlers.ts    |  4 +--
 packages/dashboard/src/__tests__/routes.test.ts    | 14 ++++++++
 packages/dashboard/src/routes.ts                   |  4 +++
 .../dashboard/src/routes/register-git-github.ts    | 12 +++++++
 .../src/routes/register-planning-subtask-routes.ts |  3 ++
 .../src/routes/register-task-workflow-routes.ts    |  7 ++++
 .../engine/src/__tests__/agent-heartbeat.test.ts   | 10 ++++++
 .../src/__tests__/agent-tools-delegation.test.ts   |  2 ++
 packages/engine/src/__tests__/agent-tools.test.ts  | 37 ++++++++++++++++++++++
 packages/engine/src/__tests__/cron-runner.test.ts  |  4 +++
 .../src/__tests__/node-routing-policy.test.ts      | 25 +++++++++++++--
 .../src/__tests__/pr-comment-handler.test.ts       |  8 +++++
 .../src/__tests__/scheduler-node-routing.test.ts   | 18 +++++------
 packages/engine/src/__tests__/triage.test.ts       |  2 ++
 packages/engine/src/agent-heartbeat.ts             | 13 ++++++--
 packages/engine/src/agent-tools.ts                 | 13 ++++++--
 packages/engine/src/cron-runner.ts                 |  7 +++-
 packages/engine/src/executor.ts                    |  2 +-
 packages/engine/src/mission-execution-loop.ts      |  8 +++++
 packages/engine/src/pr-comment-handler.ts          |  5 +++
 packages/engine/src/project-engine.ts              |  8 +++++
 packages/engine/src/routine-runner.ts              |  4 +++
 packages/engine/src/scheduler.ts                   |  8 +++--
 packages/engine/src/triage.ts                      |  4 +++
 40 files changed, 280 insertions(+), 62 deletions(-)

Fusion-Task-Id: FN-2956
This commit is contained in:
Fusion
2026-04-29 17:28:22 -07:00
committed by gsxdsm
parent b0cda2398b
commit 8a92042fc5
3 changed files with 36 additions and 15 deletions

View File

@@ -762,7 +762,7 @@ export class Scheduler {
schedulerLog.log(`Task ${task.id} routed to node=${effectiveNode.nodeId ?? "local"} (source=${effectiveNode.source})`);
// Enforce unavailable-node policy
if (effectiveNode.nodeId && this.options.nodeHealthMonitor) {
if (effectiveNode.nodeId !== undefined && this.options.nodeHealthMonitor) {
const nodeHealth = this.options.nodeHealthMonitor.getNodeHealth(effectiveNode.nodeId);
const decision = applyUnavailableNodePolicy({
effectiveNode,
@@ -773,14 +773,16 @@ export class Scheduler {
if (!decision.allowed) {
if (!this.wasNodeBlocked.has(task.id)) {
this.wasNodeBlocked.add(task.id);
schedulerLog.warn(`Task ${task.id} blocked: ${decision.reason}`);
schedulerLog.log(`Task ${task.id} dispatch blocked ${decision.reason}`);
await this.store.logEntry(task.id, decision.reason);
}
continue;
}
this.wasNodeBlocked.delete(task.id);
if (decision.fallbackToLocal) {
schedulerLog.log(`Task ${task.id} falling back to local: ${decision.reason}`);
schedulerLog.log(`Task ${task.id} falling back to local ${decision.reason}`);
await this.store.logEntry(task.id, decision.reason);
effectiveNode = { nodeId: undefined, source: "local" };
}