feat(FN-3002): add canonical research guide and update cross-linked docs

The merge introduces a canonical research guide (`docs/research.md`) as a central reference and updates cross-links across the documentation suite, including agents, architecture, dashboard-guide, settings-reference, and storage docs. The most significant addition is the 436-line research guide itse

Fusion-Task-Id: FN-3002
This commit is contained in:
Fusion
2026-05-03 14:50:16 -07:00
committed by gsxdsm
parent 3c3481f25e
commit 58e437babe
8 changed files with 470 additions and 1 deletions

View File

@@ -75,6 +75,7 @@ Every task shows its plan, its reviews, its diffs, and its file changes in real
| 🏢 **Agent companies** | Import pre-built teams — 440+ agents across 16 companies — and run them autonomously for weeks. |
| 📬 **Inter-agent messaging** | Built-in mailbox between agents. Delegate, clarify, coordinate. |
| 🗺️ **Missions** | Hierarchical planning (Mission → Milestone → Slice → Feature → Task) with autopilot and validation contracts. |
| 🔬 **Research** | Bounded research runs with web search, GitHub, local docs, and LLM synthesis. Turn findings into tasks. ([Docs](./docs/research.md)) |
| 🧪 **Self-improvement** | Agents reflect on their own output and update their prompts as they learn your codebase. |
| 🔓 **Open source. MIT.** | No vendor lock-in. Run it on your own hardware. Shipping weekly. |

View File

@@ -29,6 +29,7 @@ For a full walkthrough (installation, onboarding, first task, and daily workflow
|---|---|
| [Task Management](./task-management.md) | Task creation modes, lifecycle, prompt specs, comments, archiving, and GitHub integration |
| [Missions](./missions.md) | Mission hierarchy, planning flow, activation, progress tracking, and autopilot behavior |
| [Research](./research.md) | Research runs, provider setup, dashboard/CLI usage, findings, exports, and task integration |
| [Workflow Steps](./workflow-steps.md) | Reusable quality gates, templates, pre/post-merge phases, and workflow execution results |
| [Multi-Project](./multi-project.md) | Central registry architecture, project management, isolation modes, and migration paths |

View File

@@ -163,6 +163,9 @@ Expected behavior and boundaries:
- Queries should stay narrow and task-scoped; avoid open-ended exploration
- If research is disabled or provider setup is incomplete, tools return actionable `setup` responses instead of crashing
- Durable conclusions should be persisted with `fn_task_document_write` (for example, `key="research"`)
- Research runs require the project engine to be running for processing; `fn_research_run` creates the run but does not block for completion unless `wait_for_completion` is set
For the full research workflow, provider setup, CLI commands, and API reference, see the [Research guide](./research.md).
## Built-In Agent Prompt Templates

View File

@@ -170,9 +170,11 @@ Concrete references:
### Research Runs
- `ResearchStore` (`research-store.ts`, `research-types.ts`, `research-settings.ts`) persists bounded research runs, sources/events, and exports
- Backed by `research_runs` and `research_exports`
- Backed by `research_runs`, `research_exports`, and `research_run_events`
- Engine orchestration is implemented in `packages/engine/src/research-orchestrator.ts` + `research-step-runner.ts`
- Dashboard/API surface is implemented under `/api/research` (`packages/dashboard/src/research-routes.ts`) with `ResearchView.tsx` in the app
- CLI surface is implemented in `packages/cli/src/commands/research.ts` with six subcommands (create, list, show, export, cancel, retry)
- Agent tool surface is exposed via `packages/cli/src/extension.ts` (fn_research_run, fn_research_list, fn_research_get, fn_research_cancel)
- **Boundary note:** research and insights are parallel subsystems sharing host infrastructure, not one table/store family
### Plugin System

View File

@@ -135,6 +135,8 @@ Navigation:
- Mobile: **More** sheet in `MobileNavBar`
- Research is intentionally not shown in the primary board/list/agents/missions/chat toggle row
For the full research workflow, provider setup, CLI commands, API reference, and agent integration, see the canonical [Research guide](./research.md).
## Memory View
Memory view provides a multi-file editor for project and daily memory files.

436
docs/research.md Normal file
View File

@@ -0,0 +1,436 @@
# Research
[← Docs index](./README.md)
Fusion Research lets you create bounded research runs that search, fetch, and synthesize information from configured providers, then turn structured findings into actionable tasks — all from the dashboard, CLI, or agent sessions.
---
## Overview
A **research run** is a persisted workflow that moves through orchestration phases:
```
planning → searching → fetching → synthesizing → finalizing
```
Each run produces:
- **Findings** — structured results with headings, content, and source citations
- **Citations** — referenced URLs and sources
- **Summary** — synthesized output combining all discovered information
- **Events** — timestamped lifecycle log for auditability
Runs are persisted in the project database and can be listed, searched, exported, and converted into tasks.
## When to use Research
- Explore a technology, library, or API before writing implementation tasks
- Compare approaches (e.g., "SQLite WAL vs rollback journal") with cited sources
- Gather context from web search, GitHub, and local docs in a single structured run
- Let AI agents supplement task planning with real-time information
Research is **not** a replacement for reading source code or local docs — use it when repository-local context is insufficient for the question at hand.
---
## Prerequisites
Research requires provider configuration before runs can execute. If setup is incomplete, the dashboard shows a setup prompt and CLI/agent tools return actionable error codes.
### 1. Enable the feature flag
The Research view is gated behind an experimental feature flag. Set in global settings:
```json
{
"experimentalFeatures": {
"researchView": true
}
}
```
This also reveals the **Research Defaults** and **Research** settings sections in the dashboard Settings modal.
### 2. Configure a web search provider
Set `researchWebSearchProvider` in global settings to one of the supported backends:
| Provider | Required settings |
|---|---|
| `"searxng"` | `researchSearxngUrl` — URL of your SearXNG instance |
| `"brave"` | `researchBraveApiKey` — Brave Search API key |
| `"google"` | `researchGoogleSearchApiKey` + `researchGoogleSearchCx` — Google Custom Search credentials |
| `"tavily"` | `researchTavilyApiKey` — Tavily API key |
| `"none"` | Disables web search (other sources still work) |
API keys are stored through Fusion's auth credential pipeline (`/api/auth/api-key`), not in settings JSON directly.
### 3. (Optional) Configure synthesis model
If LLM synthesis is enabled (default: on), set a synthesis provider and model:
```json
{
"researchGlobalDefaults": {
"synthesisProvider": "anthropic",
"synthesisModelId": "claude-sonnet-4-5"
}
}
```
If no synthesis model is configured, the synthesis phase may fail with a `PROVIDER_UNAVAILABLE` error.
### Settings hierarchy
Research settings resolve through `resolveResearchSettings()` with this precedence:
1. **Project override** (`researchSettings.*`)
2. **Global default** (`researchGlobalDefaults.*`)
3. **Hardcoded fallback defaults**
See [Settings Reference → Research](./settings-reference.md) for the complete key listing.
---
## Dashboard Usage
### Navigation
The Research view is accessible from:
- **Desktop:** Header → **More views** overflow menu → Research
- **Mobile:** **More** sheet in the mobile navigation bar
Research is intentionally not shown in the primary board/list/agents/missions/chat toggle row.
### Creating a run
1. Open the Research view
2. Enter your query in the text area
3. Select which providers to use (Web Search, Page Fetch, GitHub, Local Docs, LLM Synthesis)
4. Click **Create Run**
The run enters the `queued` status and progresses through orchestration phases as the engine processes it.
### Viewing results
Select a run from the history sidebar to see:
- **Status dot and label** — current run status
- **Summary** — synthesized overview
- **Findings** — individual structured results, each with a heading and content
- **Citations** — linked source URLs
- **Run history** — expandable event log (click "Run history")
### Run lifecycle controls
| Action | Description |
|---|---|
| **Cancel** | Requests cancellation for an active run |
| **Retry** | Creates a new retry run from a failed/cancelled/timed-out run |
| **Refresh** | Reloads run data from the server |
| **Export MD** | Downloads results as a Markdown file |
| **Export JSON** | Downloads results as a JSON file |
| **Export HTML** | Downloads results as an HTML file |
### Converting findings to tasks
Each finding has two task-facing actions:
- **Create Task** — Opens a modal to create a new task from the finding, with pre-populated title, description, and priority. The finding content is attached as a task document (key: `research-{runId}`) and optionally as a Markdown attachment.
- **Enrich Task** — Attaches the finding content to an existing task as a document and/or attachment.
### Status indicators
| Status | Meaning |
|---|---|
| `queued` | Run created, waiting for engine pickup |
| `running` | Actively executing orchestration phases |
| `cancelling` | Cancellation requested, waiting for graceful shutdown |
| `retry_waiting` | Retry run created, waiting to re-enter the queue |
| `completed` | Run finished successfully with results |
| `failed` | Run encountered an unrecoverable error |
| `cancelled` | Run was cancelled by user |
| `timed_out` | Run exceeded the configured duration limit |
| `retry_exhausted` | All retry attempts exhausted |
---
## CLI Usage
The `fn research` command provides full research run management from the terminal.
### Commands
```bash
# Create a research run
fn research create --query "Compare sqlite WAL vs rollback journal"
# Create and wait for completion (up to 90 seconds)
fn research create --query "Rust async runtime trade-offs" --wait --max-wait-ms 120000
# List recent runs
fn research list
fn research list --status failed --limit 20
# Show run details
fn research show RR-001
# Export run results
fn research export RR-001 --format json --output ./artifacts/research-RR-001.json
fn research export RR-001 --format markdown
# Cancel an active run
fn research cancel RR-001
# Retry a failed run
fn research retry RR-001 --json
```
All commands support `--json` for machine-readable output.
### Error codes
| Code | Meaning | Recovery |
|---|---|---|
| `FEATURE_DISABLED` | Research is disabled in settings | Enable project or global research settings |
| `MISSING_CREDENTIALS` | No API key for the configured provider | Add provider credentials in Settings |
| `PROVIDER_UNAVAILABLE` | No configured provider or provider down | Configure a search provider |
| `RATE_LIMITED` | Provider rate limit hit | Retry after cooldown period |
| `PROVIDER_TIMEOUT` | Provider request timed out | Increase timeout or retry |
| `RUN_CANCELLED` | Run was cancelled by user | Retry if needed |
| `RETRY_EXHAUSTED` | All retry attempts used | Create a new run |
| `INVALID_TRANSITION` | Illegal status change | Check current run status |
| `NON_RETRYABLE_PROVIDER_ERROR` | Provider returned a permanent error | Check provider configuration |
| `INTERNAL_ERROR` | Unexpected internal error | Check engine logs |
See [CLI Reference → `fn research`](./cli-reference.md) for the full command reference.
---
## API Reference
All research endpoints are under `/api/research`. The router is registered in `packages/dashboard/src/routes/register-integrated-routers.ts`.
### Runs
| Method | Path | Description |
|---|---|---|
| `GET` | `/research/runs` | List runs (query params: `status`, `q`, `limit`) |
| `POST` | `/research/runs` | Create a new run (body: `query`, `providers`, etc.) |
| `GET` | `/research/runs/:id` | Get run details with findings and citations |
| `PATCH` | `/research/runs/:id` | Update run fields |
| `DELETE` | `/research/runs/:id` | Delete a run |
| `POST` | `/research/runs/:id/cancel` | Request cancellation |
| `POST` | `/research/runs/:id/retry` | Create a retry run |
| `PATCH` | `/research/runs/:id/status` | Update run status |
| `POST` | `/research/runs/:id/events` | Append an event |
| `POST` | `/research/runs/:id/sources` | Add a source |
| `PATCH` | `/research/runs/:id/sources/:sourceId` | Update a source |
| `PUT` | `/research/runs/:id/results` | Set run results |
### Exports
| Method | Path | Description |
|---|---|---|
| `GET` | `/research/runs/:id/export` | Export run (query param: `format` = `markdown`, `json`, `html`) |
| `POST` | `/research/runs/:id/exports` | Create an export record |
| `GET` | `/research/runs/:id/exports` | List exports for a run |
| `GET` | `/research/exports/:exportId` | Get a specific export |
### Task Integration
| Method | Path | Description |
|---|---|---|
| `POST` | `/research/runs/:runId/findings/:findingId/task` | Create a task from a finding |
| `POST` | `/research/runs/:runId/findings/:findingId/tasks/:taskId/enrich` | Attach finding to existing task |
Both endpoints support `attachExport: boolean` in the request body to include a Markdown attachment.
### Search & Stats
| Method | Path | Description |
|---|---|---|
| `GET` | `/research/search?q=<text>` | Full-text search across runs |
| `GET` | `/research/stats` | Aggregate run counts by status |
### Availability
List and detail endpoints include an `availability` object:
```json
{
"available": true,
"supportedProviders": ["web-search", "page-fetch", "github", "local-docs", "llm-synthesis"],
"supportedExportFormats": ["markdown", "json", "html"]
}
```
When `available` is `false`, the response includes `reason` and `setupInstructions` fields for graceful degradation.
---
## Agent Integration
AI agents (triage, executor, and custom roles) can use research tools during planning and execution sessions. These tools are registered in the pi extension (`packages/cli/src/extension.ts`).
### Available tools
| Tool | Description |
|---|---|
| `fn_research_run` | Start a bounded research run. Parameters: `query`, `wait_for_completion`, `max_wait_ms` |
| `fn_research_list` | List recent runs. Parameters: `status`, `limit` |
| `fn_research_get` | Get a run's structured findings. Parameters: `id` |
| `fn_research_cancel` | Cancel an active run. Parameters: `id` |
### Tool responses
All tools return:
- **Text content** — concise human-readable summary
- **Structured details** — machine-readable metadata (`runId`, `status`, `summary`, `findings`, `citations`, `error`, `setup`)
### Availability checks
Before creating runs, `fn_research_run` checks:
1. Research is enabled in settings
2. At least one search provider is configured
3. Required API keys are present
If any check fails, the tool returns an actionable error with setup guidance instead of crashing.
### Best practices for agents
- Use research **only when repository/local context is insufficient** for the question
- Keep queries **narrow and task-scoped** — avoid open-ended exploration
- Persist durable conclusions with `fn_task_document_write` (e.g., `key="research"`)
- Check tool availability before relying on research in automated flows
See [Agents → Research Tools](./agents.md) for more details.
---
## Storage
Research data is persisted in the project SQLite database (`.fusion/fusion.db`) using three tables:
### `research_runs`
Primary table for research run state.
| Column | Type | Description |
|---|---|---|
| `id` | TEXT PK | Run identifier (format: `RR-{timestamp}-{random}`) |
| `query` | TEXT NOT NULL | Research query text |
| `topic` | TEXT | Optional topic/label |
| `status` | TEXT | Current run status |
| `projectId` | TEXT | Optional project scope |
| `trigger` | TEXT | Optional trigger source |
| `providerConfig` | TEXT (JSON) | Provider configuration used |
| `sources` | TEXT (JSON) | Array of research sources |
| `events` | TEXT (JSON) | Array of run events |
| `results` | TEXT (JSON) | Research results (findings, summary, citations) |
| `error` | TEXT | Error message if failed |
| `tokenUsage` | TEXT (JSON) | Token usage metrics |
| `tags` | TEXT (JSON) | String array of tags |
| `metadata` | TEXT (JSON) | Arbitrary metadata |
| `lifecycle` | TEXT (JSON) | Lifecycle details (attempts, retry info, failure class) |
| `createdAt` | TEXT | ISO timestamp |
| `updatedAt` | TEXT | ISO timestamp |
| `startedAt` | TEXT | When execution began |
| `completedAt` | TEXT | When execution ended |
| `cancelledAt` | TEXT | When cancellation took effect |
Indexes: `status`, `createdAt`, `updatedAt`, `(projectId, trigger, status)`
### `research_exports`
Persisted export records.
| Column | Type | Description |
|---|---|---|
| `id` | TEXT PK | Export identifier |
| `runId` | TEXT FK → `research_runs(id)` | Parent run |
| `format` | TEXT NOT NULL | Export format (`json`, `markdown`, `pdf`) |
| `content` | TEXT NOT NULL | Export content |
| `filePath` | TEXT | Optional file path if saved to disk |
| `createdAt` | TEXT NOT NULL | ISO timestamp |
### `research_run_events`
Append-only event log for run lifecycle tracking.
| Column | Type | Description |
|---|---|---|
| `id` | TEXT PK | Event identifier |
| `runId` | TEXT FK → `research_runs(id)` | Parent run |
| `seq` | INTEGER NOT NULL | Sequence number within run |
| `type` | TEXT | Event type (info, warning, error, progress, etc.) |
| `message` | TEXT | Human-readable message |
| `status` | TEXT | Run status at event time |
| `classification` | TEXT | Failure classification if applicable |
| `metadata` | TEXT (JSON) | Arbitrary metadata |
| `createdAt` | TEXT NOT NULL | ISO timestamp |
Index: `(runId, seq)` for ordered retrieval.
See [Storage](./storage.md) for the full storage architecture.
---
## Architecture
The research subsystem spans four packages:
| Package | Module | Responsibility |
|---|---|---|
| `@fusion/core` | `research-store.ts` | Run CRUD, status transitions, event/source management, exports |
| `@fusion/core` | `research-types.ts` | Type definitions: statuses, events, sources, findings, orchestration |
| `@fusion/core` | `research-settings.ts` | Settings resolution with project/global/fallback hierarchy |
| `@fusion/engine` | `research-orchestrator.ts` | Phase lifecycle management, concurrency control, cancellation |
| `@fusion/engine` | `research-step-runner.ts` | Provider execution: search, fetch, synthesis with timeout/abort |
| `@fusion/engine` | `research/` | Provider implementations and registry |
| `@fusion/dashboard` | `research-routes.ts` | Express router for `/api/research` endpoints |
| `@fusion/dashboard` | `ResearchView.tsx` | Dashboard UI for research runs |
| `@fusion/dashboard` | `ResearchTaskActionModal.tsx` | Create/enrich task modal for findings |
| `@runfusion/fusion` | `commands/research.ts` | CLI subcommands for research management |
| `@runfusion/fusion` | `extension.ts` | Agent tool definitions for research |
### Orchestration phases
```
planning → searching → fetching → synthesizing → finalizing → completed
```
1. **Planning** — Validates configuration and creates an execution plan
2. **Searching** — Queries configured providers for relevant sources
3. **Fetching** — Retrieves full content for discovered sources
4. **Synthesizing** — Runs LLM synthesis over fetched content (configurable rounds)
5. **Finalizing** — Writes structured results (findings, summary, citations)
Each phase emits events (`phase-changed`, `step-started`, `step-completed`, `step-failed`) for real-time progress tracking.
### Concurrency
Runs are processed through an `AgentSemaphore` with configurable `maxConcurrentRuns` (default: 3). The engine processes pending runs from the queue as slots become available.
### Retry behavior
Failed or timed-out runs can be retried. The system tracks:
- **Attempt count** and **max attempts** (default: 3)
- **Root run ID** — chains retries back to the original run
- **Failure class** — determines retryability (`retryable_transient` vs `non_retryable`)
When all retries are exhausted, the run transitions to `retry_exhausted`.
---
## Troubleshooting
| Symptom | Cause | Resolution |
|---|---|---|
| "Research is disabled in settings" | `researchGlobalEnabled` or `researchSettings.enabled` is `false` | Enable in Settings → Research |
| "Research provider is not configured" | No search provider credentials set | Add API key for your chosen provider in Settings |
| "Missing API key for {provider}" | Auth credential not found | Configure provider credentials in Settings → Authentication |
| Run stuck in `queued` | Engine not running or no available concurrency slots | Start the project engine; check `maxConcurrentRuns` |
| Run times out | Provider slow or `maxDurationMs` too low | Increase timeout in project research settings |
| All retries exhausted | Persistent provider error | Check provider status; create a fresh run |
| Research view not visible in dashboard | Feature flag disabled | Set `experimentalFeatures.researchView` to `true` |
| Settings modal missing Research sections | Feature flag disabled | Enable `researchView` feature flag first |

View File

@@ -78,6 +78,22 @@ Defaults from `DEFAULT_GLOBAL_SETTINGS`; key scope from `GLOBAL_SETTINGS_KEYS`.
| `dashboardCurrentProjectIdByNode` | `Record<string, string>` | `undefined` | Map of node ID to last-selected project ID. Use key `"local"` for the local node. Persists project context across browser restarts and PWA sessions. |
| `persistAgentToolOutput` | `boolean` | `true` | Controls whether detailed `detail` payloads are persisted for `tool`, `tool_result`, and `tool_error` agent log entries. When disabled, tool timeline rows are still recorded, but verbose payloads are omitted. |
| `researchGlobalDefaults` | `ResearchGlobalDefaults` | `{ searchProvider: undefined, synthesisProvider: undefined, synthesisModelId: undefined, enabledSources: { webSearch: true, pageFetch: true, github: false, localDocs: true, llmSynthesis: true }, maxSourcesPerRun: 20, defaultExportFormat: "markdown" }` | Global Research defaults shared by all projects. Project overrides come from `researchSettings`. |
| `researchGlobalEnabled` | `boolean` | `true` | Enable or disable the research subsystem globally. When false, dashboard/API/CLI/agent entrypoints reject new runs. |
| `researchGlobalMaxConcurrentRuns` | `number` | `3` | Maximum concurrent research runs across all projects. |
| `researchGlobalDefaultTimeout` | `number` | `300000` | Default timeout for end-to-end research runs in milliseconds (5 minutes). |
| `researchGlobalMaxSourcesPerRun` | `number` | `20` | Maximum number of sources per research run. |
| `researchGlobalMaxSynthesisRounds` | `number` | `2` | Maximum synthesis rounds per research run. |
| `researchWebSearchProvider` | `"searxng" \| "brave" \| "google" \| "tavily" \| "none"` | `"none"` | Web search backend for research. Default: `"none"` (disabled). |
| `researchSearxngUrl` | `string` | `undefined` | SearXNG instance URL (required when provider is `"searxng"`). |
| `researchBraveApiKey` | `string` | `undefined` | Brave Search API key (required when provider is `"brave"`). |
| `researchGoogleSearchApiKey` | `string` | `undefined` | Google Custom Search API key (required when provider is `"google"`). |
| `researchGoogleSearchCx` | `string` | `undefined` | Google Custom Search engine ID (required when provider is `"google"`). |
| `researchTavilyApiKey` | `string` | `undefined` | Tavily API key (required when provider is `"tavily"`). |
| `researchGitHubEnabled` | `boolean` | `undefined` | Enable GitHub as a research source. |
| `researchLocalDocsEnabled` | `boolean` | `undefined` | Enable local docs as a research source. |
| `researchMaxSearchResults` | `number` | `undefined` | Maximum search results per provider query. |
| `researchFetchTimeoutMs` | `number` | `30000` | Timeout for individual HTTP fetches in milliseconds. |
| `researchUserAgent` | `string` | `"FusionResearchBot/1.0"` | User-Agent header for HTTP requests made by research providers. |
| `experimentalFeatures` | `Record<string, boolean>` | `{}` | Global-scoped experimental feature flags. Includes `experimentalFeatures.researchView` for standalone Research route visibility. |
| `remoteAccess` | `RemoteAccessSettings` | `{ activeProvider: null, providers: {...}, tokenStrategy: {...}, lifecycle: {...} }` | Global-scoped remote access provider + token strategy configuration used by Remote Access routes and tunnel lifecycle controls. |
@@ -246,6 +262,11 @@ Defaults from `DEFAULT_PROJECT_SETTINGS`; key scope from `PROJECT_SETTINGS_KEYS`
| `reviewHandoffPolicy` | `"disabled" \| "comment-triggered" \| "always"` | `"disabled"` | Policy for agent-to-user review handoff detection. |
| `showQuickChatFAB` | `boolean` | `false` | Show floating quick-chat button (chat remains available via More menu). |
| `researchSettings` | `ResearchProjectSettings` | `{ enabled: true, searchProvider: undefined, synthesisProvider: undefined, synthesisModelId: undefined, enabledSources: { webSearch: true, pageFetch: true, github: false, localDocs: true, llmSynthesis: true }, limits: { maxConcurrentRuns: 3, maxSourcesPerRun: 20, maxDurationMs: 300000, requestTimeoutMs: 30000 } }` | Project-specific Research enablement/overrides. Resolved together with `researchGlobalDefaults` via `resolveResearchSettings()`. |
| `researchEnabled` | `boolean` | `undefined` | Enable or disable research for this project. **Deprecated:** prefer `researchSettings.enabled`. |
| `researchMaxConcurrentRuns` | `number` | `undefined` | Project-level max concurrent research runs. |
| `researchDefaultTimeout` | `number` | `undefined` | Project-level default run timeout in milliseconds. |
| `researchMaxSourcesPerRun` | `number` | `undefined` | Project-level max sources per run. |
| `researchMaxSynthesisRounds` | `number` | `undefined` | Project-level max synthesis rounds. |
### Research settings hierarchy and credentials

View File

@@ -206,6 +206,9 @@ Additional backend notes:
| `mission_validator_runs` *(migration-created)* | Validator run records for mission feature loop execution. |
| `mission_validator_failures` *(migration-created)* | Assertion failure records captured during validator runs. |
| `mission_fix_feature_lineage` *(migration-created)* | Source↔fix feature lineage for auto-generated mission fix features. |
| `research_runs` | Research run state (query, topic, status, lifecycle, sources, results, citations, events, exports, token usage). Supports project-scoped active-run uniqueness via `(projectId, trigger, status)` index. Terminal runs are immutable. |
| `research_exports` | Persisted export records for research runs (`runId` FK cascade). Stores format, content, and optional file path. |
| `research_run_events` | Append-only event log for research run lifecycle tracking (`runId` FK cascade, ordered by `seq`). Records status transitions, phase changes, step lifecycle, and failure classifications. |
---