New plnt v0.1 — the orchestration runtime for agentic workflows
00 / 09 — architecture

The CRD is the contract. The saga is the engine. The backend is a choice.

plnt is nine pieces: a CRD, an operator, a Temporal workflow, a workflow-spec pull path, a Helm chart template, a backend-registration resource, a router, a smoke harness, and a rollback path. Each piece is small enough to explain on one screen.

01 / 09 — STACK

Four layers. plnt is the third. Everything above it consumes; everything below it is Kubernetes.

PRODUCT

google-business (or any consumer). A SaaS surface that needs narrow, reliable AI features. Calls the workflow endpoint plnt exposes — same shape for every workflow.

REGISTRY

microagents. S3-backed store of workflow specs (steps, tool bindings, GPU requirements). Versioned, hash-verifiable, pullable. Publishing is a git push + a sync job.

RUNTIME

plnt. Watches a WorkflowRun CRD → runs a Temporal saga → Helm-installs a runner pod on the chosen backend → canary → promote or rollback.

BACKEND

Any Kubernetes + GPU node pool. plnt speaks to the K8s API; backends are declared once in a PlntBackend resource and referenced by name from every WorkflowRun.

02 / 09 — DIAGRAM

One K8s cluster. One operator. One workflow engine. N workflows.

plnt · single-cluster topology
    plnt CLI                    kubectl                    google-business
       │                          │                            │
       └──────────────┬───────────┘                            │
                      ▼                                        │
       ┌─────────────────────────────┐                         │
       │  WorkflowRun  (K8s CRD)     │                         │
       └──────────────┬──────────────┘                         │
                      │  watch                                 │
                      ▼                                        │
       ┌─────────────────────────────┐                         │
       │  plnt operator  (kopf)      │                         │
       └──────────────┬──────────────┘                         │
                      │  start_workflow(spec)                  │
                      ▼                                        │
    ┌──────────────────────────────────────────┐               │
    │  Temporal · OrchestrateWorkflow          │               │
    │  pull → resolve → helm → smoke → promote │               │
    │       └──────────────┴──────────▶ rollback               │
    └──────────────────────────────────────────┘               │
                      │  helm install                          │
                      ▼                                        │
    ┌──────────────────────────────────────────┐               │
    │  workflow runner pod                     │               │
    │  ─ pulls spec from microagents (S3)      │               │
    │  ─ mounts tools declared in spec         │               │
    │  ─ exposes /invoke on OpenAPI shape      │               │
    └──────────────────────────────────────────┘               │
                      │                                        │
                      ▼                                        │
              ┌──────────────┐                                 │
              │ envoy router │  (VirtualService weights)       │
              └──────┬───────┘                                 │
                     ▼                                         │
                  /invoke  ◀───────────────────────────────── consume
03 / 09 — CRD

The WorkflowRun resource is the entire deploy contract. Everything the operator, the saga, and the Helm chart need is on the spec.

examples/review-responder.yaml
apiVersion: plnt.work/v1
kind: WorkflowRun
metadata:
  name: review-responder
spec:
  workflow:
    ref: review-responder@1.2.0
    registry: s3://microagents           # or oci://ghcr.io/...
    integrityHash: sha256:9a1b...          # optional pin
  backend:
    cluster: gpu-cluster-01                # named plnt backend
    gpuClass: nvidia.com/h100
    gpuCount: 2
    nodeSelector:
      pool: agent-workflows
  replicas:
    min: 1
    max: 4
  autoscaling:
    targetInvocationsPerSecond: 25
  canary:
    trafficPercent: 5
    smokeTest:
      invocations: 10
      p95BudgetMs: 2500
      errorBudgetPercent: 1
04 / 09 — WORKFLOW SPEC

The thing plnt pulls from the registry. A workflow is a directed graph of steps + tool bindings + resource requirements.

microagents/review-responder/workflow.yaml
# microagents/review-responder/workflow.yaml
apiVersion: microagents.dev/v1
kind: Workflow
metadata:
  name: review-responder
  version: 1.2.0
spec:
  description: Draft an on-brand reply to a Google Business review.
  runtime:
    image: ghcr.io/microagents/runner:0.4.0
    entrypoint: python -m review_responder
  steps:
    - id: classify_intent      # sentiment + topic
      tool: llm.classify
    - id: retrieve_brand_voice # RAG from tenant KB
      tool: rag.query
      deps: [classify_intent]
    - id: draft_reply
      tool: llm.generate
      deps: [retrieve_brand_voice]
    - id: safety_check
      tool: policy.moderate
      deps: [draft_reply]
  requirements:
    gpuClass: nvidia.com/h100
    gpuCount: 2
    memoryGiB: 40
05 / 09 — OPERATOR

A Python kopf controller watches the CRD. Create / update / delete map directly to Temporal workflow starts, updates, and cancellations.

plnt/operators/workflowrun_controller.py
# plnt/operators/workflowrun_controller.py
import kopf
from temporalio.client import Client
from plnt.workflows.orchestrate import OrchestrateWorkflow

@kopf.on.create('plnt.work', 'v1', 'workflowruns')
async def on_create(spec, name, namespace, **_):
    client = await Client.connect(TEMPORAL_ADDR)
    await client.start_workflow(
        OrchestrateWorkflow.run,
        args=[spec],
        id=f'orchestrate-{namespace}-{name}',
        task_queue='plnt-orchestrate',
    )

@kopf.on.update('plnt.work', 'v1', 'workflowruns')
async def on_update(spec, name, namespace, **_):
    # Any spec change triggers a fresh canary.
    ...

@kopf.on.delete('plnt.work', 'v1', 'workflowruns')
async def on_delete(name, namespace, **_):
    # helm uninstall + cancel any in-flight orchestration.
    ...
06 / 09 — SAGA

The orchestration saga is a Temporal workflow. Compensation on failure via helm rollback. Retries per activity, non-retryable error types short-circuit obvious dead-ends.

plnt/workflows/orchestrate.py
# plnt/workflows/orchestrate.py
from datetime import timedelta
from temporalio import workflow
from temporalio.common import RetryPolicy

@workflow.defn
class OrchestrateWorkflow:
    @workflow.run
    async def run(self, spec: dict) -> dict:
        retry = RetryPolicy(
            initial_interval=timedelta(seconds=2),
            maximum_attempts=3,
            backoff_coefficient=2.0,
            non_retryable_error_types=['SpecInvalid', 'BackendUnavailable'],
        )
        try:
            await workflow.execute_activity(
                pull_workflow_spec, spec, start_to_close_timeout=timedelta(minutes=5), retry_policy=retry)
            await workflow.execute_activity(
                resolve_backend, spec, start_to_close_timeout=timedelta(seconds=30), retry_policy=retry)
            release = await workflow.execute_activity(
                helm_install_canary, spec, start_to_close_timeout=timedelta(minutes=10), retry_policy=retry)
            smoke = await workflow.execute_activity(
                run_smoke_test, release, start_to_close_timeout=timedelta(minutes=5), retry_policy=retry)
            if not smoke['passed']:
                await workflow.execute_activity(helm_rollback, release)
                return {'status': 'rolled_back', 'reason': smoke['reason']}
            await workflow.execute_activity(
                promote_to_stable, release, start_to_close_timeout=timedelta(minutes=5))
            return {'status': 'ready', 'endpoint': release['endpoint']}
        except Exception:
            await workflow.execute_activity(helm_rollback, spec)  # compensation
            raise
07 / 09 — LIVE RUN

One orchestration. Captured from the Temporal event history for orchestrate-default-review-responder.

temporal · workflow history · r-9c4f218e0a
04:17:33 watch WorkflowRun/review-responder event=create
04:17:33 workflow start · orchestrate-default-review-responder
04:17:34 pull spec ref=review-responder@1.2.0 · source=s3://microagents · sha256 verified
04:17:35 resolve backend=gpu-cluster-01 · gpus=2 available · node pool=agent-workflows
04:17:41 helm install release=review-responder-canary · replicas=1 · vs.weight=5%
04:19:14 smoke n=10 · p50=1.1s p95=1.8s · errors=0 · pass
04:19:15 promote canary → stable · vs.weight=100% · replicas=1→3
04:19:15 ready endpoint=review-responder.plnt.svc/invoke
08 / 09 — METRICS

The numbers that prove the runtime works: p50/p95/p99 per-invocation latency, error rate, GPU utilization, queue depth. Scraped from each workflow's /metrics endpoint into Prometheus.

plnt bench --workflow review-responder --qps 10 --duration 60s
latency     p50 =   1.10 s   p95 =   1.82 s   p99 =   2.41 s
error rate                  =   0.00 %
throughput                  =   9.7  invocations/s
gpu utilization             =   68 %
step-cache hit rate         =   34 %
09 / 09 — GAPS

Where the current build is honest about what it isn't. Named upfront, not hidden.

Registry publishing UX

microagents ships a pull path; the push path is a manual S3 sync. A proper microagents publish CLI + signature verification is planned Q1 2026.

Multi-cluster

Single-cluster demo today. Multi-cluster is a design I understand (fan-out activities keyed by cluster context; per-cluster canary) but not yet code I've run at scale.

GPU scheduling policy

plnt respects nvidia.com/gpu limits and node selectors; it does not yet do capacity-aware placement across pools. The scheduler-plugin work is Phase 5.

Observability

Temporal history + Kubernetes events cover the deploy lane. Per-invocation tracing (OpenTelemetry span per workflow step) is stubbed but not wired to a collector yet.