Files
fusion/docs/agent-tool-surface-full-loop.md
gsxdsm 38891bfd81 FN-8296: add chat-requested task verification
Enable chat agents to queue and monitor executor-owned verification runs.

- Persist task verification requests through a new PostgreSQL migration.
- Expose action-gated chat request and status tools with executor processing.
- Show verification status in task and Command Center views.
- Advance the schema baseline to migration 0024 and keep chat mocks complete.

Files changed:
 .changeset/fn-8296-feature.md                      |  7 ++
 docs/agent-tool-surface-full-loop.md               | 10 +--
 docs/dashboard-guide.md                            |  4 +
 packages/core/src/index.ts                         |  2 +
 .../core/src/postgres/migrations/0000_initial.sql  | 20 +++++
 .../migrations/0024_task_verification_request.sql  | 20 +++++
 packages/core/src/postgres/schema-applier.ts       | 13 ++-
 packages/core/src/postgres/schema/project.ts       | 25 ++++++
 packages/core/src/store.ts                         | 16 +++-
 packages/core/src/task-store/reads.ts              | 14 +++-
 packages/core/src/task-store/remaining-ops-6.ts    | 49 ++++++++++-
 packages/core/src/types.ts                         | 30 +++++++
 packages/dashboard/app/api/legacy.ts               |  1 +
 packages/dashboard/app/api/task-content.ts         | 10 +++
 .../dashboard/app/components/TaskDetailModal.tsx   | 17 +++-
 .../app/components/TaskVerificationStatus.css      | 94 ++++++++++++++++++++++
 .../app/components/TaskVerificationStatus.tsx      | 39 +++++++++
 .../__tests__/TaskVerificationStatus.test.tsx      | 28 +++++++
 .../components/command-center/CommandCenter.css    | 33 ++++++++
 .../components/command-center/CommandCenter.tsx    | 37 ++++++++-
 packages/dashboard/src/__tests__/chat.test.ts      |  1 +
 packages/dashboard/src/chat.ts                     | 55 +++++++++++++
 .../src/routes/register-command-center-routes.ts   | 20 +++++
 .../src/routes/register-task-workflow-routes.ts    | 17 ++++
 packages/engine/src/executor.ts                    | 51 +++++++++++-
 packages/engine/src/gating-classifications.ts      |  5 ++
 packages/engine/src/index.ts                       |  2 +-
 27 files changed, 605 insertions(+), 15 deletions(-)

Fusion-Task-Id: FN-8296

Fusion-Task-Lineage: f94647cf-c89f-4f0e-b25f-cbf5b56683bc

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-18 18:38:47 -07:00

22 KiB
Raw Blame History

Full-loop agent tool-surface audit and delivery plan

← Docs index

Decision summary

Fusion already has useful task, workflow, goal, research, execution, and verification tools. It does not yet give an engine agent or dashboard chat session a complete native route from an idea or research result into the execution-oriented mission hierarchy. In particular, packages/engine/src/agent-tools.ts has no fn_mission_*, fn_milestone_*, fn_slice_*, or fn_feature_* factory, and no ideation diverge/converge tool. Research can be run by qualifying sessions, but its current handoff ends at a task document/task action rather than an attributable roadmap feature.

The mission hierarchy is Mission → Milestone → Slice → Feature → Task (Missions); it is not the separate lightweight Roadmap → RoadmapMilestone → RoadmapFeature model. This document uses “roadmap” to mean the execution-oriented mission hierarchy unless it explicitly says otherwise.

Method and scope

This is a source-grounded audit of the runtime factories in packages/engine/src/agent-tools.ts, their wiring in executor/heartbeat/chat sessions, and the corresponding dashboard operations. “Agent-facing” means model-visible in an engine session or dashboard chat, not merely callable by an operator-facing pi extension. A tool listed as a gap may already exist in the extension or UI; that is evidence of a dual-access/wiring gap rather than a reason to invent a second business operation.

Session boundaries that matter

  • Executor: packages/engine/src/executor.ts assembles task-bound tools. It is the only audited lane that adds fn_run_verification from packages/engine/src/run-verification-tool.ts, because that tool needs the task worktree.
  • Permanent/custom heartbeat: packages/engine/src/agent-heartbeat.ts adds task discovery, workflow authoring, research, goals, task creation/delegation, and coordination tools. No-task heartbeats deliberately have no task worktree.
  • Dashboard chat: packages/dashboard/src/chat.ts wires task creation/discovery, task assignment/delegation, goals, research, workflow authoring, documents, artifacts, and web fetch. It does not wire mission-hierarchy tools or executor-only verification.
  • Pi extension / operator tools: the mission tools documented in Missions and packages/cli/skill/fusion/references/extension-tools.md prove that mission operations already have a canonical store-backed implementation. They are not registered in agent-tools.ts or dashboard chat today.

Stage inventory

Loop stage Current engine-agent / chat route Status and concrete gap Human operation / dual-access parity
Ideation: diverge and converge No fn_ideation_* factory or registration exists in packages/engine/src/agent-tools.ts. Agents can use generic documents, memory, fn_ask_question, and chat prose, but none is a persisted ideation operation. GAP: add native, persisted fn_ideation_diverge and fn_ideation_converge (names provisional until the canonical ideation domain API is designed). The existing docs/ideation/2026-06-02-open-ideation.md is an artifact, not a callable pipeline. No audited Command Center ideation operation was found. Define the domain operation and expose the same operation to its UI and agent callers; do not create a chat-only document shortcut.
Research fn_research_run, fn_research_list, fn_research_get, fn_research_cancel, and fn_research_retry come from createResearchTools() in agent-tools.ts. Executor only registers them when the research surface is enabled; heartbeat/chat wiring uses the same factories. Partial: tools are gated by isResearchToolSurfaceEnabled() / experimentalFeatures.researchView in tool-availability.ts; disabled or unconfigured calls return setup guidance. Research results do not natively create/update mission hierarchy records. Research view creates/runs/cancels/retries and exports runs (Research); the same persisted ResearchStore run model is used. The dashboard can create/enrich a task from a finding, but has no research-to-feature/milestone handoff.
Roadmap read: goals and mission hierarchy fn_goal_list and fn_goal_show are created by createGoalRetrievalTools(). Task discovery (fn_task_list, fn_task_search, fn_task_show) can show linked task context. No mission-hierarchy reader is in agent-tools.ts. GAP: add fn_mission_list / fn_mission_show (and hierarchy-focused reads as needed) to the shared engine/chat tool surface. Goals View and Mission Manager expose their canonical read views. Pi extension fn_mission_list / fn_mission_show already use mission-store operations; reuse those operations and response shapes.
Roadmap write: Mission → Milestone → Slice → Feature No fn_mission_*, fn_milestone_*, fn_slice_*, or fn_feature_* is created or registered by agent-tools.ts. Confirmed GAP: expose canonical mission writes, including create/update/delete, slice activation, feature creation/update/delete, and fn_feature_link_task; do not duplicate store semantics in chat. Mission Manager owns mission/hierarchy editing, slice activation, and feature-to-task linkage. The pi extension already exposes the corresponding fn_mission_*, fn_milestone_*, fn_slice_*, and fn_feature_* operations. This is currently dual-access for UI ↔ extension, but not for engine/chat.
Task creation, planning, and assignment fn_task_create, fn_task_list, fn_task_search, fn_task_show, fn_delegate_task, and fn_task_assign are factory-backed in agent-tools.ts; dashboard chat wires the discovery/create/delegate/assign tools. Workflow tools cover selected workflow inspection/authoring; task planner and triage convert a task into executable scope. Present, with boundary: chat has no ambient task, so task documents/logs require explicit IDs. Planning-board tools intentionally provide board read parity. Mission-feature-to-task linkage remains unavailable to engine/chat because roadmap writes are missing. New Task / Planning Board, task-detail assignment, workflow UI, and Mission Manager feature triage are the human paths. Existing task operations use the same TaskStore; task create/assignment is not a weaker chat-only path.
Execution The executor owns worktree acquisition, task lifecycle, workflow-step execution, and task-bound file tools. Heartbeats can create/delegate/assign but are not a substitute for an execution worktree. Present, guarded: execution begins through scheduler/workflow dispatch rather than a generic chat “run arbitrary task now” shortcut. No new bypass should skip task state, leases, workflow holds, or action gates. Board/workflow release and task lifecycle controls invoke the same scheduler/store transitions. Command Center is an observability/control surface, not a separate executor.
E2E / verification Task-bound executor sessions expose fn_run_verification from packages/engine/src/run-verification-tool.ts; it runs bounded test/lint/build/typecheck commands with worktree containment and concurrency controls. Partial: dashboard chat and no-task heartbeat cannot safely call it because they lack an execution worktree. The missing chat control is a safe “request/observe verification on a selected task” operation, not exposing a raw command runner outside executor ownership. Dashboard task/workflow result surfaces and Command Center funnel show execution state; the same verification result must be surfaced there. A future chat entry point must dispatch the existing task-owned verification operation and return its persisted result, not fork subprocess handling.

Confirmed gaps

  1. packages/engine/src/agent-tools.ts contains goal, task, workflow, research, memory, and coordination factories, but no mission/milestone/slice/feature factory or registration.
  2. No native persisted ideation diverge/converge operation is exposed from that registry.
  3. Research availability is intentionally feature-gated by isResearchToolSurfaceEnabled() in packages/engine/src/tool-availability.ts; this must remain an explicit capability/setup state, not an implicit fallback.
  4. Research currently lands in task context (finding-to-task/enrich-task UI), not in the execution roadmap hierarchy.
  5. Executor-only fn_run_verification is correct for task worktree safety, but chat lacks a first-class request/status route for task-owned E2E verification.

Dual-access parity contract

FR-07/FR-08 require one canonical operation beneath UI and tool callers. The parity target is not “every session gets every tool”: a tool requiring a task worktree remains executor-owned, and UI/chat must request the task-owned operation rather than recreate it.

Operation family Canonical backing operation today Human surface Agent/chat parity result
Research run lifecycle ResearchStore + engine dispatcher / ResearchOrchestrator Research view Parity for run lifecycle, gated by the same research feature/settings. Task conversion is present; roadmap conversion is missing.
Mission hierarchy MissionStore and mission routes Mission Manager Extension/UI parity exists; engine/chat gap. Reuse MissionStore operations and existing extension semantics.
Goals Goal store/retrieval tools Goals View and Mission Manager goal linkage Read parity only in agent-tools.ts; hierarchy linkage writes need the roadmap phase.
Tasks, delegation, assignment TaskStore / AgentStore Board, Planning Board, task detail Parity, subject to existing permission policy and explicit task_id in chat.
Workflow authoring Workflow store/IR validation Workflows UI Parity in heartbeat/chat, with action gates and approval-bypass stripping for prompt-injectable lanes.
Verification task-owned bounded runner + persisted task execution state Task/workflow state and Command Center observability Executor parity only. Add a safe request/status UI/chat bridge; do not expose a second raw runner.
Ideation No canonical persisted domain operation identified No audited dedicated Command Center operation identified Gap on both sides. Design the shared operation before exposing either surface.

Parallelism: current behavior and real gap

Fusion does not have a single-workflow-only scheduler by design. The scheduler can dispatch independent runnable tasks, but admission is bounded and serialized at specific safety gates:

  • packages/engine/src/scheduler.ts computes dispatch capacity from maxConcurrent, maxWorktrees, and the shared semaphore in computeConcurrencyGateDiagnostic(). The settings default to maxConcurrent 2 and maxWorktrees 4 when unspecified (scheduler dispatch path).
  • AgentSemaphore in packages/engine/src/concurrency.ts gates all top-level triage, execution, and merge agents. Its priority queue serves merge before execute before specification (PRIORITY_MERGE, PRIORITY_EXECUTE, PRIORITY_SPECIFY). A full semaphore can therefore make work appear serialized even with multiple runnable cards.
  • The workflow hold/release sweep in scheduler.ts reserves worktree and semaphore capacity with tryAcquire() before moving a task to in-progress, then transfers that pre-held slot to the executor. This prevents a race but means the available minimum of all gates is authoritative.
  • maxWorktrees counts only in-progress tasks; in-review worktrees do not consume that execution-worktree limit. maxConcurrent counts execution slots, while the global semaphore also accounts for planning and active review top-level holders.
  • Runnable candidates are additionally filtered for paused state, unmet dependencies, recovery backoff, workflow hold/release state, and file-scope overlap via isRunnableQueuedOverlapCandidate() / pathsOverlap() in scheduler.ts. This is coarse path-scope serialization, not FR-48 symbol locking.
  • packages/engine/src/workflow-work-scheduler.ts claims one due workflow work item per call with a lease. The surrounding scheduler’s repeated dispatch and capacity gates determine aggregate concurrency; this helper alone does not fan out a batch.
  • packages/engine/src/verification-concurrency.ts separately defaults expensive verification subprocesses to one concurrent project-wide slot. Task execution can be parallel while heavy E2E verification intentionally queues.

Therefore, “serializes silently” means either (a) one of the named capacity gates has no slack, (b) a candidate is dependency/hold/recovery/overlap blocked, (c) workflow work is only claimed one item per dispatch turn, or (d) verification is at its distinct verification cap. It does not mean missions or sprints themselves are scheduling pools with independent concurrency. Mission membership supplies delivery structure; it does not reserve capacity or create a parallel execution lane.

Guardrail contract

Widening the surface is safe only if these delivery invariants ship with it:

Guardrail Required contract Current audit evidence and dependency
FR-02: mission admission Before autonomous execution/claim, deterministically prove that the task traces to an approved mission/feature lineage. Unknown/unlinked work must wait, ask, or be explicitly admitted; it must not become idle-agent patrol work. Current no-task heartbeat prompts in agent-heartbeat-prompts.ts encourage one useful action and permit fn_task_create after duplicate checks. renderHeartbeatNoTaskSystemPrompt({ plannerHeartbeatPatrolEnabled: false }) can suppress patrol, but that is not a kernel mission-lineage admission gate. This phase must be independently tracked before the widened autonomous route is enabled.
FR-37: completion → roadmap reconciliation Completed, blocked, and changed task state must reconcile the linked feature/slice/milestone/mission status and expose the same result to UI/chat. scheduler.ts imports reconcileMissionFeatureState, showing existing feature-state reconciliation infrastructure, but this audit found no tool-level research/roadmap handoff contract. The roadmap-tool phase must preserve and extend canonical reconciliation rather than write parallel status.
FR-48: symbol-level locking Concurrent work must use a durable symbol-level lock/claim protocol where file-scope overlap is too coarse; lock acquisition/release and conflict reporting must be visible to scheduler and tools. Current scheduler has file-scope overlap filtering (pathsOverlap) and worktree/semaphore reservations, not symbol-level locks. Parallel admission must remain bounded by existing gates until a symbol-locking implementation lands.
Existing action/permission gates Every new mutating tool must be classified and action-gated; prompt-injectable lanes must not bypass approvals. Heartbeat wraps broad tools in action gates and strips workflow approval-bypass flags. Mission/ideation tools need the same classification and tests.
Research feature gate Research calls preserve explicit disabled/unconfigured outcomes. tool-availability.ts and Research define the experimental gate and setup behavior. Do not make roadmap writes silently invoke research.

Phased implementation plan

The following phases are intentionally independently shippable. Follow-up task IDs are added after duplicate reconciliation and task creation.

Phase A — Mission hierarchy tool surface and parity

  • Scope anchors: packages/engine/src/agent-tools.ts, packages/engine/src/index.ts, packages/dashboard/src/chat.ts, packages/cli/src/extension.ts or the existing mission extension factory, mission routes/store tests, Mission Manager API adapters, docs/missions.md.
  • Acceptance: engine/chat can list/show/create/update Mission → Milestone → Slice → Feature and link a feature to a task through the same MissionStore-backed operations used by Mission Manager/extension; action-gate policy, explicit chat context, and UI ↔ tool contract tests cover each mutation.
  • Dependency: none for read/write parity; it must not claim autonomous execution admission.
  • Tracking: FN-8294 — Phase A implementation task.

Phase B — Persisted ideation diverge/converge

  • Scope anchors: a new core ideation domain/store, packages/engine/src/agent-tools.ts, packages/dashboard/src/chat.ts, dedicated dashboard ideation UI/Command Center entry, docs/ideation/.
  • Acceptance: agents and humans can create a bounded ideation session, record divergent candidates with provenance, converge an explicitly selected candidate, and hand it to Phase A’s mission-hierarchy operation without copying prose between parallel stores.
  • Dependency: Phase A, because convergence must create/attach canonical roadmap records rather than an orphan document.
  • Tracking: FN-8295 — Phase B implementation task; depends on FN-8294.

Phase C — Research-to-roadmap bridge and reconciliation

  • Scope anchors: packages/engine/src/research-orchestrator.ts, research routes/UI, packages/engine/src/agent-tools.ts, mission store/reconciliation, dashboard chat, docs/research.md, docs/missions.md.
  • Acceptance: a cited research run/finding can create or enrich a canonical mission feature with persisted source/run provenance; feature/task completion reconciles back to the hierarchy without manual board repair; disabled research still returns setup guidance.
  • Dependency: Phase A; may consume Phase B convergence output but should remain usable directly from research.
  • Tracking: FN-8297 — Phase C implementation task; depends on FN-8294.

Phase D — Mission admission and safe parallel delivery

  • Scope anchors: scheduler admission/hold-release paths, packages/engine/src/agent-heartbeat.ts, packages/engine/src/agent-heartbeat-prompts.ts, mission lineage queries, action-gate classifications, packages/engine/src/concurrency.ts, packages/engine/src/verification-concurrency.ts, and new symbol-locking components/tests.
  • Acceptance: autonomous claims execute only tasks with approved mission lineage; no-task idle patrol cannot invent off-mission implementation; independent approved tasks use available maxConcurrent, maxWorktrees, semaphore, and verification capacity while conflicting symbols serialize through durable locks; diagnostics identify the binding gate/lock; completion reconciles roadmap state.
  • Dependency: Phase A for lineage data, and the tracked FR-02/FR-37/FR-48 work if those tasks already cover portions of this phase.
  • Tracking: FN-8298 — Phase D implementation task; depends on FN-8294 and FN-8297.

Phase E — Chat-owned verification request/status — delivered (FN-8296)

  • Shipped tools: fn_task_request_verification queues only the server-resolved verify:fast or configured test-command profile; fn_task_verification_status returns the latest bounded persisted result. Neither accepts raw command text.
  • Execution contract: the request is project-scoped and CAS-claimed by the in-progress task executor, which reuses its live worktree and runVerificationCommand/withVerificationSlot bounds. fn_task_request_verification is classified as command_execution; status is read-only.
  • Parity: chat can request/observe the same executor-owned verification outcome. Duplicate in-flight requests retain their original request ID rather than replacing work in progress.
  • Dependency: remains independently shippable from A–D; Phase D diagnostics can be added to records later without changing the ownership contract.

Follow-up reconciliation record

Step 0 attempted the available task-board discovery tools to search the cited FR themes. The hosted TaskStore timed out during fn_task_show and repeated fn_task_list calls, and this task environment does not expose the specified fn_task_search tool. Repository-local tracked documentation/spec search found no existing task IDs for FR-02, FR-07, FR-08, FR-14, FR-15, FR-37, or FR-48. After that reconciliation, Step 3 created the non-duplicate implementation tasks: FN-8294 (Phase A), FN-8295 (Phase B, depends on FN-8294), FN-8297 (Phase C, depends on FN-8294), FN-8298 (Phase D, depends on FN-8294 and FN-8297), and FN-8296 (Phase E, independent).

Source references

  • packages/engine/src/agent-tools.ts — shared engine tool factories and absent mission/ideation factories.
  • packages/engine/src/tool-availability.ts — research experimental gate and guidance.
  • packages/engine/src/executor.ts and packages/engine/src/run-verification-tool.ts — task-bound execution and verification tool registration.
  • packages/engine/src/agent-heartbeat.ts and packages/engine/src/agent-heartbeat-prompts.ts — ambient tool exposure and no-task patrol behavior.
  • packages/dashboard/src/chat.ts and packages/dashboard/src/planning-board-tools.ts — dashboard model-loop and planning-board wiring.
  • packages/engine/src/scheduler.ts, packages/engine/src/concurrency.ts, packages/engine/src/workflow-work-scheduler.ts, and packages/engine/src/verification-concurrency.ts — actual concurrency gates and work-item lease behavior.
  • Research, Missions, and docs/ideation/ — human-facing workflow and current ideation artifact.