Files
fusion/plugins/fusion-plugin-reports/README.md
Fusion 4a09924c56 feat(FN-4050): add one-click install support for reports plugin
- Add reports plugin to bundled plugin resolver so it can be installed from packaged assets
- Expose reports plugin in dashboard plugin manager and server routes for one-click install flows
- Add CLI and dashboard test coverage for bundled install behavior and plugin route availability
- Update reports/plugin management/settings docs and include a changeset for @runfusion/fusion
2026-05-11 21:48:26 -07:00

7.0 KiB

Reports Plugin for Fusion

Generates HTML system activity reports with multi-agent review.

Install (one-click)

  1. Open Settings → Plugins → Fusion Plugins.
  2. In Bundled Plugins, click Install on Reports.
  3. Enable the plugin if prompted.

Once installed and enabled, Fusion registers the Reports dashboard destination automatically.

Scaffold seams (interim)

The plugin currently exports four interim scaffold seams to unblock downstream implementation work:

  • resolveEnabledCadences / ReportsCadence (src/cadence.ts) — interim cadence-resolution seam; scheduled cadence registry + cron/sentinel wiring lands in FN-3779.
  • aggregateReportData + aggregation types (src/aggregation.ts) — interim aggregation seam; real aggregation orchestration lands in FN-3780.
  • startReportsPipeline + pipeline dependency interfaces (src/pipeline.ts) — interim orchestrator seam to keep call sites stable while FN-3779/FN-3780 wire real runtime components.
  • createInMemoryReportsRunsStore + run record/store types (src/runs-store.ts) — interim in-memory run state store; persistent store replacement lands in FN-3784.

Review Panel

The plugin exposes runReviewPanel() / runGeneratedReportReview() to fan out a generated report draft to multiple reviewer agents in parallel.

Panel member settings shape

Each reviewer uses this contract:

{
  id: string;
  name: string;
  perspective: string;
  promptTemplateId?: string;
  provider?: string;
  modelId?: string;
}
  • perspective is appended to the reviewer system prompt.
  • promptTemplateId selects a template from settings.reviewPromptTemplates[templateId] when present.
  • provider + modelId optionally override model selection per reviewer.

Prompt template contract

runReviewPanel resolves reviewer templates in this order:

  1. settings.reviewPromptTemplates[promptTemplateId ?? id]
  2. settings.reviewPrompt
  3. Built-in fallback (DEFAULT_REVIEW_PROMPT)

This is the temporary compatibility contract until FN-3782 lands shared review-template helpers.

Individual review shape

{
  memberId: string;
  memberName: string;
  perspective: string;
  verdict: "approve" | "revise" | "reject";
  summary: string;
  highlights: string[];
  lowlights: string[];
  suggestions: string[];
  rawText: string;
  durationMs: number;
}

Combined review shape

{
  overallVerdict: "approve" | "revise" | "reject";
  consensusSummary: string;
  mergedHighlights: string[];
  mergedLowlights: string[];
  mergedSuggestions: string[];
  individual: IndividualReview[];
  failures: ReviewFailure[];
}

Aggregation is deterministic:

  • verdict precedence: approve < revise < reject
  • merged arrays are case-insensitive de-duped, first-seen order, max 25 items each
  • consensus summary is generated locally from reviewer summaries (no second AI call)

Timeout and failure semantics

  • Each reviewer has a hard timeout (120_000ms).
  • A single reviewer failure never aborts the full panel.
  • Failures are returned as:
{
  memberId: string;
  reason: "timeout" | "parse_error" | "session_unavailable" | "exception";
  message: string;
}
  • If all reviewers fail, combined verdict is reject with an explicit consensus summary describing panel failure.

Report Archive

The plugin persists generated reports in SQLite via ensureReportSchema(db) and ReportStore.

Schema

Table: reports

  • identity/metadata: id, cadence, title, metadataJson
  • period window: periodStart, periodEnd
  • lifecycle/status: status, failureReason
  • payload references: draftMarkdown, renderedHtmlPath
  • review payload: combinedReviewJson
  • timestamps: generationStartedAt, generationCompletedAt, reviewStartedAt, reviewCompletedAt, approvedAt, publishedAt, archivedAt, createdAt, updatedAt
  • approval actor: approvedBy

Indexes:

  • idxReportsCadenceCreated on (cadence, createdAt DESC, id)
  • idxReportsStatusUpdated on (status, updatedAt DESC, id)
  • idxReportsPeriod on (periodStart, periodEnd, id)

Status lifecycle

generating → review_pending → review_in_progress → review_complete → approved → published

failed and archived are allowed from any non-terminal state. Idempotent transitions (from === to) are no-ops.

Approval + publish lifecycle (FN-3787)

A parallel approvalState gate now controls human/approver decisions before distribution:

review_complete entry:

  • approvalRequired=false, autoPublishOnApproval=falseapprovalState=approved, status=approved
  • approvalRequired=false, autoPublishOnApproval=trueapprovalState=published, status=published
  • approvalRequired=trueapprovalState=awaiting_approval, status=review_complete

Decision transitions:

  • awaiting_approval --approve--> approved (or directly published when autoPublishOnApproval=true)
  • awaiting_approval --reject--> rejected
  • approved --publish--> published

Backfilled legacy rows use approvalState=not_required and are non-actionable.

Authorization rules:

  • When approvalRequired=true and approverAgentIds is non-empty, only listed approver agent IDs may approve/reject/publish.
  • When approvalRequired=true and approverAgentIds=[], any human dashboard user is allowed; agents are not.
  • publishTargets records publish intent metadata when a report reaches published.

Share-ready summary blocks (FN-3787)

Approved/published reports can produce deterministic share artifacts via GET /reports/:id/share-blocks:

  • plainText: compact paste-ready summary
  • markdown: heading/bullets + report link
  • slack: mrkdwn-friendly summary
  • emailHtml: inline-styled HTML snippet for email clients

share-blocks is intentionally locked (409) until approvalState is approved or published.

Email HTML styling exemption: emailHtml deliberately uses inline style attributes and hardcoded hex colors for email-client compatibility; dashboard design-token CSS rules do not apply to this serialized output format.

ReportStore API

  • createReport(input)
  • getReport(id)
  • listReports(filter?)
  • updateReport(id, patch)
  • setStatus(id, next, opts?)
  • attachReview(id, combinedReview)
  • attachRenderedHtml(id, htmlPath)
  • deleteReport(id)

Emitted events:

  • report:created
  • report:updated
  • report:status-changed
  • report:review-attached
  • report:deleted

This archive is the source of truth for downstream report HTML rendering (FN-3785) and dashboard report list/detail flows (FN-3786).

Dashboard view

The plugin registers a primary dashboard view (Reports) via dashboardViews with componentPath: "./dashboard-view".

The view provides:

  • History list of reports with filters (cadence, status, period date range, title search, agent filter)
  • Embedded detail preview using sandboxed iframe + preview HTML endpoint
  • Section quick-jump navigation by stable data-section markers
  • Side-by-side comparison drawer for two reports with section-level diff summary
  • Standalone HTML download action wired to the export endpoint