Skip to content

Architecture Overview

Greentic is built around a small runtime core and a large pack ecosystem. The core runtime is responsible for loading bundles, enforcing tenant boundaries, routing ingress, coordinating the runtime routing layer, and executing WebAssembly components. Domain-specific behavior — messaging platforms, event sources, business workflows, reusable tools, state/session storage, OAuth, deployment targets, observability, and control surfaces — is delivered through runtime packs, capability providers, or deploy/designer extensions.

External users, systems, schedules, and APIs
├─ Messaging platforms
│ Slack, Teams, Telegram, WhatsApp, WebChat, Webex, Email
├─ Event sources
│ Webhooks, timers, SendGrid email events, Twilio SMS events
└─ Direct HTTP ingress
REST calls, webhooks, health checks, admin/control routes
┌────────────────────────────────────────────────────────────────────┐
│ HTTP ingress and route resolver │
│ Resolves env / tenant / team / channel and selects provider pack │
└────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────┐
│ Provider packs │
│ Messaging providers normalize messages; event providers normalize │
│ events; egress components send replies and downstream actions │
└────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────┐
│ gtc runtime │
│ Loads the bundle, validates packs, grants capabilities, manages │
│ tenant context, routes triggers, and executes flows │
│ │
│ Bundle │
│ ├─ App packs: digital worker flows, cards, templates, components │
│ ├─ Provider packs: messaging, events, state/session, OAuth │
│ ├─ Capability hooks: assets, OAuth, op hooks, access policies │
│ └─ Assets: WebChat skins, i18n, embed snippets, static files │
└────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────┐
│ Flow executor │
│ Runs .ygtc graphs: branches, prompts, tools, templates, replies, │
│ subflows, approval steps, retries, and event handlers │
└────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────┐
│ Wasmtime component model │
│ Calls sandboxed WASM components through WIT interfaces │
│ Node components, provider ingress/egress, MCP tools, state/session │
│ stores, OAuth providers, and other WIT-compatible components │
└────────────────────────────────────────────────────────────────────┘

The important design point is that gtc start ./my-bundle is not just starting a process. It is starting a packaged operating environment for digital workers: a bundle declares what can run, which providers are enabled, which runtime packs and capabilities are trusted, what capabilities are granted, and how every tenant/channel/session is routed.

gtc runtime

The CLI and runtime entry point used to create, set up, validate, and run bundles. At runtime it loads packs, registers providers, routes ingress, and executes flows.

greentic-flow

Flow schema definition, intermediate representation (IR), loader, and validator for .ygtc files.

greentic-pack

Pack builder CLI for creating signed .gtpack archives containing flows, components, and assets.

greentic-component

Component authoring CLI and runtime utilities for building WASM components.

Wasmtime

The component-model execution layer that runs provider, tool, app, and compatible extension components inside a sandbox.

A Greentic deployment is driven by a bundle. A bundle is the runtime contract for one digital-worker environment.

my-bundle/
├── bundle.yaml # Normalized bundle state and capability flags
├── greentic.demo.yaml # Bundle configuration used by setup/runtime docs
├── providers/
│ ├── messaging/
│ │ ├── messaging-webchat.gtpack
│ │ └── messaging-slack.gtpack
│ ├── events/
│ │ └── events-webhook.gtpack
│ └── state/
│ └── state-memory.gtpack
├── apps/
│ └── deep-research/
│ └── flows/
│ └── main.ygtc
├── tenants/
│ └── demo/
└── assets/
└── webchat-gui/

gtc wizard creates or materializes this structure. gtc setup writes provider configuration and secrets. gtc start loads the bundle, verifies packs, mounts assets, registers ingress routes, and starts the flow runtime.

LayerWhat it containsWhy it matters
App packsDigital-worker flows, custom WASM nodes, cards, templates, prompts, i18nThis is the business logic: the worker that answers, acts, plans, approves, or integrates.
Messaging provider packsSlack, Teams, Telegram, WhatsApp, WebChat, Webex, Email ingress/egress componentsThey decouple flows from platform-specific APIs so the same worker can run on many channels.
Events provider packsWebhook, timer, SendGrid email, Twilio SMS, and custom event ingressThey let workers start from business events, schedules, alerts, and system signals rather than only chat.
Capability providers and extensionsState/session providers, OAuth brokers, operation hooks, deploy extensions, admin/control surfaces, telemetry integrationsThey make the runtime portable: the same worker can use different infrastructure and operations surfaces without changing the flow.

Greentic uses two related extension mechanisms:

  • Runtime packs (.gtpack) run with the bundle. These include app packs, messaging providers, event providers, state/session providers, OAuth-capable packs, MCP tools, and reusable components.
  • Designer/deploy extensions (.gtxpack) are consumed by tools such as gtdx and greentic-deployer. Deploy extensions declare new deployment targets and can delegate to built-in deployer backends such as Terraform, cloud, or desktop targets.

The architecture treats both as extension points because they let an organization replace operational behavior without rewriting the digital worker.

Extension pointCurrent shapeWhy it is important
Session manager / state providerRuntime provider pack such as state-memory or state-redisDigital workers need continuity across messages, approvals, retries, and long-running tasks. Swappable state storage lets local demos and production deployments use different backends.
Secrets managerRuntime secrets abstraction configured by environment or backing provider such as Vault, AWS, Azure, or GCPProvider tokens, API keys, OAuth credentials, and deploy credentials must not be embedded in flows. A scoped secrets layer keeps credentials environment-specific.
OAuth providerRuntime OAuth capabilities such as greentic.cap.oauth.broker.v1, greentic.cap.oauth.card.v1, and greentic.cap.oauth.token_validation.v1Many SaaS integrations require delegated user or workspace access. OAuth capabilities keep auth flows reusable instead of baking auth logic into every app.
Deployergreentic-deployer plus deploy extensions (.gtxpack) and built-in backends such as AWS, Azure, GCP, Terraform, Helm, single-VM, and desktopThe same bundle can be materialized locally, in one cloud, across clouds, or through a custom target while the app pack stays the same.
ObserverRuntime telemetry configuration and OpenTelemetry export; custom observer integrations can sit behind the same telemetry boundaryOperators need to know what a worker did, which component failed, how long each step took, and which tenant/channel was affected.
Controlgtc admin, runtime health/readiness endpoints, session/message APIs, and the secure admin API exposed by greentic-startProduction workers need operational control: inspect runtime state, stop a runtime, manage admin access, or disable access paths without changing app flows.
Policy and accessPack trust policies, capability grants, tenant access rules, and operation hooks such as greentic.cap.op_hook.pre / greentic.cap.op_hook.postThis prevents accidental overreach. A worker should only call the components, providers, secrets, and external systems it was granted.

Because these concerns sit behind explicit interfaces, an organization can replace memory state with Redis, local secrets with Vault, a manual deployment with Terraform, or console logging with OpenTelemetry without changing the application pack.

LayerTechnologyPurpose
WASM RuntimeWasmtime v41Component model execution
Async RuntimeTokio v1Async I/O, task scheduling
HTTP ServerAxum v0.8REST API, webhooks
IngressHTTP route resolverPublic webhook, WebChat, event, and control endpoints
Pack Runtime.gtpack / .gtbundle loaderSigned pack verification, capability grants, dependency registration
Flow Runtime.ygtc graphsTrigger routing, orchestration, branching, retries, node execution
Message Businternal runtime routingTenant-scoped message/event distribution and pub/sub
Capability ServicesRuntime packs, capability hooks, and deploy/designer extensionsState/session, secrets, OAuth, deploy, observe, control, policy
1. User sends a message in Slack, Teams, Telegram, WhatsApp, WebChat, Webex, or Email
2. HTTP ingress receives the webhook or WebChat request
3. Messaging provider ingress component validates and normalizes the payload
4. Runtime resolves env / tenant / team / channel and publishes a tenant-scoped normalized message through runtime routing
5. Flow router selects the app flow and loads session state
6. Flow executor calls WASM node components, tools, templates, and LLM components
7. Session manager persists updated state and observer records telemetry
8. Messaging provider egress component formats the reply for the platform
9. Platform API receives the reply, card, button, file, or follow-up action
1. External system posts a webhook, timer fires, email arrives, or SMS event arrives
2. HTTP ingress routes the request to an events provider pack
3. Events provider normalizes the event payload and metadata
4. Runtime resolves tenant context and publishes/routes the normalized event to an event trigger
5. Flow executor runs the worker flow and calls WASM components/tools
6. Worker may call APIs, create incidents, send messages, deploy infrastructure,
update state, or emit a report
1. `gtc start ./my-bundle`
2. Read bundle configuration, tenants, providers, assets, and pack references
3. Resolve packs from local files, release assets, or OCI registries
4. Verify hashes, signatures, trust policy, and declared capabilities
5. Register provider ingress/egress, app flows, extension services, and tools
6. Instantiate WASM components with WIT bindings and scoped capabilities
7. Start ingress routes and begin processing messages/events

Greentic implements tenant isolation at every layer:

Bundle workspace
└── Environment (dev, staging, prod)
└── Tenant
└── Team
└── Session / user / provider context

TenantCtx flows through component invocations and host capability calls. The current shared type is defined in greentic-types, with WIT equivalents in greentic:types-core@0.6.0 and compatibility surfaces in greentic:interfaces-types@0.1.0.

pub struct TenantCtx {
pub env: EnvId,
pub tenant: TenantId,
pub tenant_id: TenantId,
pub team: Option<TeamId>,
pub team_id: Option<TeamId>,
pub user: Option<UserId>,
pub user_id: Option<UserId>,
pub session_id: Option<String>,
pub flow_id: Option<String>,
pub node_id: Option<String>,
pub provider_id: Option<String>,
pub trace_id: Option<String>,
pub i18n_id: Option<String>,
pub correlation_id: Option<String>,
pub attempt: u32,
pub idempotency_key: Option<String>,
}

Bundle access is controlled by tenants/<tenant>/tenant.gmap and optional tenants/<tenant>/teams/<team>/team.gmap policy overlays. Those files contain pack/flow/node policy rules; tenant profiles, extension providers, app-pack mappings, and capabilities live in bundle.yaml and resolved manifests.

Greentic uses the WebAssembly Interface Types (WIT) specification for defining component interfaces:

// greentic-interfaces/wit/greentic/component@0.6.0/package.wit
package greentic:component@0.6.0;
interface control {
should-cancel: func() -> bool;
yield-now: func();
}
interface node {
use greentic:types-core/core@0.6.0.{capability-id, component-id, flow-id, node-error, step-id, tenant-ctx};
record invocation-envelope {
ctx: tenant-ctx,
flow-id: flow-id,
step-id: step-id,
component-id: component-id,
attempt: u32,
payload-cbor: list<u8>,
metadata-cbor: option<list<u8>>,
}
record invocation-result {
ok: bool,
output-cbor: list<u8>,
output-metadata-cbor: option<list<u8>>,
}
variant schema-source {
cbor-schema-id(string),
inline-cbor(list<u8>),
ref-pack-path(string),
ref-uri(string),
}
record io-schema {
schema: schema-source,
content-type: string,
schema-version: option<string>,
}
record example {
title: string,
input-cbor: list<u8>,
output-cbor: list<u8>,
}
record schema-ref {
id: string,
content-type: string,
blake3-hash: string,
version: string,
bytes: option<list<u8>>,
uri: option<string>,
}
record setup-example {
title: string,
answers-cbor: list<u8>,
}
record setup-template-scaffold {
template-ref: string,
output-layout: option<string>,
}
variant setup-output {
config-only,
template-scaffold(setup-template-scaffold),
}
record setup-contract {
qa-spec: schema-source,
answers-schema: schema-source,
examples: list<setup-example>,
outputs: list<setup-output>,
}
record op {
name: string,
summary: option<string>,
input: io-schema,
output: io-schema,
examples: list<example>,
}
record component-descriptor {
name: string,
version: string,
summary: option<string>,
capabilities: list<capability-id>,
ops: list<op>,
schemas: list<schema-ref>,
setup: option<setup-contract>,
}
describe: func() -> component-descriptor;
invoke: func(op: string, envelope: invocation-envelope) -> result<invocation-result, node-error>;
}
world component {
import control;
export node;
}
ResponsibilityRuntime ownerPack extension point
Bundle loadinggtc runtimeApp, provider, component, and capability packs
Ingress routingHTTP ingress resolverMessaging and events provider packs
Tenant isolationTenant context and capability grantsPack trust policy, access rules, and operation hooks
Flow executionFlow executorApp flows and WASM node components
Component executionWasmtime component modelAny WIT-compatible WASM component
State continuitySession/state abstractionState/session provider packs
Credential accessSecrets abstractionEnvironment or backing secrets providers
External authOAuth abstractionOAuth capability packs and WebChat/Teams OAuth configuration
Deploymentgreentic-deployerBuilt-in deployer backends and deploy extensions
OperationsRuntime/admin control surfacegtc admin, health/readiness endpoints, admin API
TelemetryTelemetry/observer boundaryOpenTelemetry or custom telemetry integrations

Greentic treats observability as a first-class extension point. The runtime emits structured execution data, and telemetry configuration or observer integrations decide where it goes:

  • Tracing - Correlate HTTP ingress, provider parsing, flow nodes, WASM calls, tool calls, and egress replies.
  • Metrics - Measure flow execution times, message throughput, event volume, retries, and error rates.
  • Logging - Attach tenant, channel, session, flow, component, and trace context to runtime logs.
  • Auditability - Preserve what ran, which pack version handled it, which tenant it belonged to, and which external action was taken.

In local development this can be simple console logging. In production it can be an OpenTelemetry pipeline, a cloud-native monitoring backend, or a custom observer integration required by your organization.

  • Flows - Learn about flow definitions
  • Packs - Understand pack structure
  • Components - Build custom WASM components