Orkestia
Blog
Guides

Typed decisions with TypeSafe

Put TypeSafe Jev in front of compositions, Staff actors, DGI designs, and cluster actions — closed-set answers, not chat

Use TypeSafe when the next step must be a closed set: allow / block / review, a risk score, a yes-no human gate. Do not use it to draft tickets, write code, or run a tool loop. Those stay on an LLM connection via ai.chat.

Connect the key first: TypeSafe. The only featured workflow is typesafe.systemone.evaluate.

Live today: the connection and typesafe.systemone.evaluate. Everything below is that same atomic, placed as a step. There is no separate TypeSafe app, and Staff does not auto-triage the inbox with Jev until you compose it.

What to use where

SurfaceWhat TypeSafe doesWhat still uses an LLM
CompositionsFirst layer: evaluate, then later layers map answers.*Optional later steps that draft or explain
Staff actorsAn allowed MCP call before a mutating workflowThe actor's model provider (OpenAI, Anthropic, …)
DGIClassify intent / domain / complexity as a compiled stepGoal prose and DAG assembly
Kaoitos / kubernetes.*Score or noul before a destructive cluster actionNone required for the gate
Ticketspage / priority / routine / deferred on an incoming envelopePlan and patch generation

The pattern is always: decide, then spend. Jev labels; chat models generate.

Compositions

A composition is layers of existing catalog types. Put evaluate in layer 1. Pin the question set as static so callers cannot widen it. Pass connection_uuid and state from the composition input.

{
  "name": "decide-then-act",
  "layers": [
    {
      "name": "decide",
      "steps": [
        {
          "name": "jev",
          "workflow_type": "typesafe.systemone.evaluate",
          "input_mapping": {
            "connection_uuid": { "source": "input", "field_name": "connection_uuid" },
            "state": { "source": "input", "field_name": "state" },
            "questions": {
              "source": "static",
              "value": {
                "action": {
                  "type": "choice",
                  "instructions": "What should we do?",
                  "criteria": {
                    "allow": "Safe to proceed",
                    "block": "Must not proceed",
                    "review": "Needs a human"
                  }
                },
                "needs_human": {
                  "type": "noul",
                  "instructions": "Does this need a human in the loop?"
                }
              }
            }
          }
        }
      ]
    }
  ]
}

Save with composition.validate then composition.save. Invoke virtual.<uuid>@<version> like any other type. To share it with app end-users, follow Compositions.

Next layers read answers.action and answers.needs_human from the jev step (source: "step"). Keep mutating workflows after the decide layer so a block never reaches them.

Authoring is the same whether you hand-write JSON, use the console DAG builder, DevKit, or DGI: all of them compile to this representation.

Staff

Staff actors reason with an LLM connection. TypeSafe is not one of those. Do not add the TypeSafe key as the actor's model provider.

What works today:

  1. Connect TypeSafe in the main app, not in Staff.
  2. Give the actor MCP / skill access to start typesafe.systemone.evaluate (same as any other catalog type). Staff RBAC still governs who may start it.
  3. In standing instructions, tell the actor when to call it (for example: before start_workflow on a mutating type, or when classifying an inbox envelope into page / priority / routine / deferred).

The actor still needs a real model provider and an agent-eligible runner group. Jev is a tool the session may call, not the brain.

Never put TYPESAFE_API_KEY in Staff or actor environment. The workflow decrypts the org connection in-process, the same rule as LLM keys.

DGI

Building with DGI turns a prompt into a composition. Ask it for a first step that is typesafe.systemone.evaluate with a fixed question set, then later steps that consume answers. DGI still writes the goal prose; TypeSafe only labels.

DGI is alpha. Treat the compiled composition as the artifact you review, not the chat that produced it.

Cluster and runner actions

For Kaoitos and runner mutations, the useful TypeSafe questions are a score (how risky) and a noul (needs a human). Put evaluate in the composition ahead of kubernetes.* or runner.* steps that create, scale, or delete. A block or needs_human: true should stop the composition before those steps run.

Tickets and software delivery

The ticket-to-PR path already has human gates. TypeSafe is a cheap prefilter on the incoming envelope (page this, batch that), not a replacement for acknowledged plans or PR review.

What not to do

  • Do not point TypeSafe at ai.chat or LiteLLM.
  • Do not use it as the Staff actor model.
  • Do not send secrets, kubeconfigs, or raw credentials in state.
  • Do not treat connect/test (empty /systemone probe) as an evaluation. That probe only checks the key.

Reference