openTiger plugin support is standardized around a single contract: PluginManifestV1.
This document defines the platform contract and migration-safe behavior for:
- API route exposure
- planner/dispatcher/worker/judge/cycle hooks
- dashboard route/nav exposure
- plugin-scoped database migration
- compatibility and enable/disable behavior
TigerResearch is the reference implementation.
- Keep core orchestration stable while allowing plugin specialization.
- Use one manifest contract across all runtime agents.
- Let operators enable/disable plugins without code edits.
- Keep failure isolation explicit (
incompatible,error,disabled) and observable. - Preserve recoverability-first task lifecycle behavior.
Plugins are first-party monorepo packages under plugins/<plugin-id>/.
Each plugin package exports one manifest entrypoint:
plugins/<plugin-id>/index.ts
The core loader (packages/plugin-sdk) discovers, validates, and activates plugins according to ENABLED_PLUGINS.
Manifest fields:
- Required
id: string(stable plugin identifier)version: string(plugin package version)pluginApiVersion: string(platform contract version, e.g."1")taskKinds: string[](kinds owned/handled by the plugin)lanes: string[](dispatcher lanes contributed by the plugin)
- Optional
requires?: string[](plugin dependencies byid)api?planner?dispatcher?worker?judge?cycleManager?dashboard?db?
- Loader compares
pluginApiVersionwith core-supported version. - If incompatible:
- plugin status becomes
incompatible - plugin is skipped (not loaded)
- core runtime continues
- structured logs and
/pluginsresponse include reason
- plugin status becomes
ENABLED_PLUGINSis a CSV list (example:tiger-research,slack-triage).- Plugins not listed are treated as
disabled. - Activation changes are applied on process restart.
- Registers all plugin routes under
/plugins/<plugin-id>/*. - Legacy alias routes (for example
/research/*) are not part of the v1 contract.
Planner hook owns plugin-specific decomposition while preserving planner responsibility boundaries.
Canonical shape:
planPluginJob(input) -> { tasks, domainUpdates, warnings }
Expected behavior:
- Read plugin domain state
- Produce
taskswith validkind/laneregistered by manifest - Return deterministic domain updates (if any)
- Never embed cross-agent orchestration decisions in planner hook
- Registers additional lane semantics and lane selection metadata.
- Dispatcher keeps lease/idempotency ownership.
- Resolves plugin task handler by
task.kind. - Executes plugin path without forcing git pipeline usage.
Judge hook evaluates plugin outputs and returns verdict inputs to existing task transitions.
Canonical shape:
collectPendingTargets() -> Target[]evaluateTarget(target) -> EvaluationResultapplyVerdict(result) -> DomainUpdate
Judge remains the owner of judgement idempotency and rework transitions.
- Provides periodic plugin monitor/orchestration tick.
- Must be safe and idempotent across repeated loop executions.
- Provides plugin routes and nav entries.
- Discovery uses
import.meta.globat build time. - Enabling/disabling existing plugins can be toggled at runtime startup.
- Adding a new plugin package requires dashboard rebuild because route modules must exist at build time.
Plugin DB integration is migration-based, not schema hardcoding in core.
Expected manifest db metadata:
- plugin migration directory location
- optional schema exports used by plugin package
Global migration order:
- Core migrations
- Plugin migrations in topological order by
requires
Rules:
- Dependency cycle in
requiresis a hard failure. - Missing dependency plugin is a hard failure for dependent plugin.
- Migration execution is idempotent and persisted in migration state.
- Plugin migration failure does not silently continue; error is explicit and actionable.
GET /plugins returns plugin inventory including status:
enableddisabledincompatibleerror
Response includes at least:
idversionpluginApiVersionstatuscapabilitiesreason(for non-enabled states)
- Create
plugins/<id>/index.tswithPluginManifestV1. - Declare
taskKinds,lanes, and optionalrequires. - Implement required hooks for target behavior.
- Add plugin-scoped DB migrations if domain tables are needed.
- Register plugin in loader discovery map.
- Enable plugin via
ENABLED_PLUGINS. - Run
pnpm run plugin:validateandpnpm run check. - Add plugin docs and operational notes.
See:
- research
plugins/tiger-research/(manifest + hooks)