The workflow engine

Grove

heartwood engine

A config-driven factory that turns DB-stored definitions into running, human-in-the-loop workflows.

Shared platform component. Domain applications are documented separately.

DB config (ConfigLoaderV2)
Driven by
v3 UI API · flows/forms/pages
Surface
on_enter.ui_form waiting states
HITL
data-driven tier limits
Governance

Grove (the heartwood engine) is where intent becomes execution. Workflows, forms, pages, and tools are defined as config in the database, not hardcoded. Grove loads them, runs them as state machines, pauses for human input when a step needs it, and enforces per-tier usage limits. New capabilities ship as feature packages, not new services.

What’s inside

Feature packages

A capability = manifest + tasks + workflow YAML. index_research and create_financial_goal are packages, not bespoke code.

Human-in-the-loop

A workflow state can pause on a UI form, collect a response, and resume; the engine bridges the event store and ORM so the pause and resume just work.

Config-sync factory

A generic model-driven sync for all Grove*Config types (nav, theme, pages, forms, flows, decisions) from YAML into the DB.

Tier governance

Per-tier usage caps (free/basic/premium/enterprise) enforced at one chokepoint; adding a capped workflow is three declarative map entries.

Enterprise isolation

Every client row is stamped with its owning tenant; reads are scoped to a tenant's visible set (its own data plus its parents') and config is overlaid per tenant: multi-tenant by construction, enforced at the query.

Domain routers

An installed domain mounts its own HTTP routes on the engine through a discovery hook at startup, so a new domain adds endpoints without changing core grove.

Personalized media

A generic image service plus a consent-gated reference-photo library: a user's own photo conditions AI image generation on their likeness, offered to any flow. The substrate does the storage and generation; the engine exposes it; a domain (goal images) just opts in.

Config, not code

Grove's thesis is that a workflow platform should be driven by data. A flow is a state machine described in YAML; a form is a field schema; a page is a widget layout; a tool is a declarative service call. ConfigLoaderV2 reads these from the database and the engine runs them, so shipping a capability means publishing config, not deploying a new service.

Human-in-the-loop, done right

When a state declares an on_enter.ui_form, the engine pauses and surfaces that form to the UI. The hard part, that the executor reads an event store while submissions land in ORM/human-task tables, is handled by emitting the right resume event and hydrating session state. The result: create_financial_goal walks a user from idea to budget to confirmation to generated images to calendar milestones, pausing for input exactly where it should, and advisor_portfolio_review routes an SLA-backed assignment to an advisor when a portfolio drifts from its target.

Governed by construction

Usage limits are data: a tier-limits map, a usage-query map, and a workflow-to-limit map. Enforcement is one shared chokepoint. Adding a new capped workflow is three lines, with no new control flow and no scattered checks.

Multi-tenant by construction

Grove receives the caller's tenant as a trusted, gateway-forwarded enterprise_id (never re-derived, never client-supplied). It enforces a two-layer model. Client data is isolated: every row is stamped with its owning tenant and every read is scoped to that tenant's visible set, its own data plus its parents', never a sibling's and never another tenant's. Config is reused: a tenant inherits shared defaults and stores only its own overrides. Isolation lives at the query, so it can't be forgotten per endpoint.

Connects to