temporality
RUEdit this page↗
Operations

Harness Operations

How to deploy, configure and operate Temporality as a working harness — the stack, upgrades, providers, authentication, knowledge, skills, sandboxes, observability, backups and troubleshooting.

This guide is for whoever is responsible for a working deployment: rolling it out, upgrading it, configuring providers and access, observability, and troubleshooting typical failures. Day-to-day user work is covered in the neighboring sections; exact variable values — in the Reference.

#1. The stack: what runs where and where state lives

Compose brings up seven services:

Service Image Role
postgres pgvector/pgvector:pg17 The only persistent store: events, knowledge, users, configs, secrets, reviews
journal temporality/journal Event store API: event reads/search, SSE streams of runs
agent-kernel temporality/agent-kernel The kernel: a Temporal worker (long-lived runs), the :8090 API, sandboxes, MCP, channels
debugger temporality/debugger Web UI :3000, a proxy to the kernel and journal
temporal temporalio/auto-setup The durable execution engine (its own store)
searxng searxng Meta-search for the web_search tool
lightpanda lightpanda/browser Headless browser (CDP) for the browser tool

Where state lives — this matters for backups and migrations:

Nothing important lives inside the containers: they can be recreated freely.

#2. Deployment and upgrades

#Moving skills and agents between stands

The behavioral configuration set transfers in one JSON file in the internal temporality.transfer/v1 format:

curl -H "Authorization: Bearer $ADMIN_TOKEN" \
  "https://stand-a.example/kernel-api/v1/workspace/export?type=all" -o transfer.json
curl -H "Authorization: Bearer $ADMIN_TOKEN" -F [email protected] \
  "https://stand-b.example/kernel-api/v1/workspace/import?mode=merge"

Upgrading the stack to the latest release:

docker compose pull && docker compose up -d

For a controlled upgrade (or a rollback) pin the version explicitly:

TEMPORALITY_VERSION=2026.2.113 docker compose up -d

The upgrade procedure:

  1. Read the release notes (the tag annotation) — migrations and breaking changes are written there.
  2. docker compose pull journal debugger agent-kernel
  3. docker compose up -d — Postgres migrations apply automatically at kernel startup (migrations/workspace, quota migrations); the migration log is idempotent.
  4. Check health: docker compose ps (all healthy), the /dashboard page, one test run.

Rollback — bring up the previous TEMPORALITY_VERSION. Schema migrations do not roll back: take a dump before major upgrades (§9). Building locally from sources instead of GHCR:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build agent-kernel debugger

(docker-compose.dev.yml switches the images to builds from the repository; it overrides only the listed services.) A common hiccup: on the first simultaneous build of the two targets, buildx sometimes trips over a cache lock — rerunning the build goes through.

#3. Providers and models

Three default provider variables are the minimum to get going:

TEMPORALITY_MODEL_BASE_URL=https://api.provider.com/v1
TEMPORALITY_MODEL_ID=mimo-v2.6-flash
TEMPORALITY_MODEL_API_KEY=...

Full setup lives on the /providers page: several providers, model catalogs, assigning models to roles.

#Model roles and where each one lands

The model catalog is synced from the provider on a schedule (KERNEL_PROVIDER_MODELS_REFRESH, 24h by default, 0 disables the cycle) plus a manual refresh and a probe check in the UI.

The judge — a separate chat model for evaluations. It is used more widely than it seems: the quality loop, knowledge area normalization, supervisor passes and cases, the worth_skill verdict when mining skills, model selection in the draft wizards (agent/skill/team): env model → judge model → the first chat candidate in the catalog. Non-chat catalog entries (ASR, embedding, image) are filtered out of the candidates — if a wizard "picked the first ASR model it saw", refresh the catalog and assign the roles explicitly.

#Streaming and timeouts

Variable Default Meaning
TEMPORALITY_MODEL_FIRST_TOKEN_TIMEOUT 2m Waiting for the first token; adaptively +60s per MB of prompt
TEMPORALITY_MODEL_STREAM_IDLE_TIMEOUT 90s Silence in the stream between tokens
TEMPORALITY_MODEL_STREAM_NO_PROGRESS_TIMEOUT 4m The stream is alive, but overall progress has stalled
TEMPORALITY_MODEL_TIMEOUT 180s The base HTTP request timeout
TEMPORALITY_MODEL_ACTIVITY_TIMEOUT 20m Ceiling for one model activity
TEMPORALITY_MODEL_MAX_OUTPUT_TOKENS 16384 (code) / 1024 (compose) Generation limit. The compose stack deliberately sets 1024 — raise it consciously
TEMPORALITY_MODEL_TEMPERATURE / _REASONING — Overrides for request parameters

Buffering gateways (they return the whole response as one chunk) are not a malfunction. In the trace this shows up as the "provider does not stream (a single chunk)" verdict on long calls; stream retries follow a ladder with a growing interval ("↻ stream retry after N s"). The "token channel did not connect (transport, not model)" diagnostic means an SSE transport problem on the way to the provider, not a model choice. A hung call can be pushed manually — the ↻ button on the live model-call line cancels the request and restarts the turn.

#4. Authentication and access

Four modes, from simple to enterprise:

  1. No authentication — KERNEL_AUTH_TOKENS empty. For local experiments only.
  2. Bearer tokens — KERNEL_AUTH_TOKENS=token:user:role:projects,.... For service agents and scripts.
  3. Password + sessions — the main UI mode. Login is password-first, the "Password | API token" form. Sessions: KERNEL_SESSION_TTL (sliding, 12h), KERNEL_SESSION_ABSOLUTE_TTL (7d); KERNEL_COOKIE_SECURE=true behind HTTPS.
  4. OIDC SSO — federation (Keycloak/Entra/Authentik), JIT provisioning, group-to-role mappings, the deny role = "login succeeds, access denied" until a manual decision. The config lives on /users (admin-only); every change writes an audit event.

Self-service: a user changes their password via the account menu (POST /v1/auth/password). An account with a password confirms the current one; an SSO account without a local password sets its first one with an empty current field — minimum 8 characters, the bearer token survives the change. Break-glass: with SSO enabled, password login remains for the admin only (IdP unavailability does not block operations).

Project scoping: a role plus a project list in the token; for SSO — claim mappings; * means all projects. The org structure (/org) additionally restricts visibility by department.

#5. Secrets

#6. Knowledge, hints and embeddings

The semantic layer (knowledge similarity, hints drawn from similar experience, conflict prediction, semantic search) requires an embeddings model:

KERNEL_EMBEDDINGS_MODEL=intfloat/multilingual-e5-small

The model loads in-process (rembed) from Hugging Face. If it fails to load, the kernel keeps working, but with a "not all tools are configured" banner and without semantics — retries follow a growing interval; check reachability of huggingface.co. The model cache is on disk; for ownership problems see the log (there is a fallback to the OS user).

Operating knowledge:

#7. Skills and artifacts

Skills — versioned procedures with a contract. Creation paths: describing in the UI, import, manual, and mining — the supervisor looks for repeated tool-call trigrams across runs, a deterministic gate filters out read-only sequences, the judge issues a worth_skill verdict with a rationale; the candidate lands in the queue and is pre-filled as a draft on /skills. Versions: a draft is 0.x, applying/rejecting revisions is a human decision; the skill list shows draft and "↺ N" badges — pending draft revisions. Do not let unapplied revisions pile up: go through the queue by badge.

Artifacts — documents agents load on demand. Statuses: draft / in_review / rejected / approved / superseded (the lifecycle is per version: editing an approved document means a new revision and a repeated approval round). The review cycle: submit (idempotent per version) → reviewers are notified → the decision is human-only (self-approval is forbidden at the API level) → approved/rejected. Reviewers: the all mode (everyone must decide) or any (one is enough). The per-run submission quota is ARTIFACT_SUBMIT_PER_DAY. Artifact bodies render markdown with mermaid diagrams (typical LLM errors in erDiagram are fixed automatically).

#8. Agents, teams and the plan DAG

#9. Sandboxes, tools and limits

#Egress control (address allowlists)

A network-enabled sandbox lands not on a public bridge but on an internal network with no outbound route; the only way out is the egress proxy (squid), whose config the kernel generates from agent settings. Semantics: the public internet is allowed (NetworkAccess), private ranges (LAN, RFC1918, metadata) are denied by default, and only explicit entries in the agent's egress_allowlist open specific internal addresses:

egress_allowlist: ["api.github.com", "*.example.com", "gitlab.corp:8443", "10.20.30.0/24"]

Entry format: a domain, a glob, a CIDR, or host:port. The proxy resolves names itself — internal DNS works, and a denial comes back as a clear error. Non-HTTP traffic (ssh, arbitrary ports) does not leave — for agent workloads that is almost always irrelevant, and it is a feature. Only HTTP(S) is controlled: secret values remain protected by the leak scanner and canaries.

Deployed automatically with the stack (the egress-proxy service + the temporality-sandbox-internal/temporality-egress-out networks); without the egress stack sandboxes keep the legacy bridge behavior.

#The rest

#10. Operational observability

#11. Backup and restore

The minimum — nightly:

docker exec temporality-postgres-1 pg_dump -U temporality temporality | gzip > backup-$(date +%F).sql.gz
tar -C /srv/temporality/sandbox -czf sandbox-$(date +%F).tgz .

Restore: bring up an empty stack of the same version → restore the dump → put back the sandbox root → start the kernel. Active (unfinished) runs continue after a restore only if the Temporal DB was restored too — for most cases it is acceptable to accept that unfinished runs die and get restarted. Verify restores periodically on a separate deployment — a backup that has never been restored is not a backup.

#12. Troubleshooting typical failures

Symptom Where to look What to do
A run "hangs" on a model call the trace's live line: waiting for the first token if "the token channel did not connect" — transport to the provider (SSE/proxy), not the model; wait for the retry ladder or push ↻
"Provider does not stream (a single chunk)" model.completed details a gateway buffers the response; not an error — pick another provider/endpoint for streaming
Answers get cut off mid-way TEMPORALITY_MODEL_MAX_OUTPUT_TOKENS raise the limit (the compose default of 1024 is small for large turns)
A command's console shows "Output unavailable: 404" the console buffer the buffer was evicted (6h idle / kernel restart); output ≤1 KB is recovered from the event journal
The "not all tools are configured: embeddings" banner the kernel log reachability of huggingface.co, correctness of KERNEL_EMBEDDINGS_MODEL; retries are automatic
A run failed and nothing picks it up /supervisor check KERNEL_SUPERVISOR_TRIAGE_INTERVAL; contested operations — reconcile in the run panel
429 on launches quotas KERNEL_RUN_QUOTAS — raise the project's limit or the * default
A sandbox does not start the kernel log, docker compose ps the docker socket gid (TEMPORALITY_DOCKER_GID), presence of KERNEL_SANDBOX_IMAGE
The UI does not see everything (projects) scoping the token's role+projects / SSO mappings / org departments

Practice: the trace first (it shows both the transport and the retry verdicts), then the kernel logs, then the journal. Most "hangs" are transport to the provider, and the trace names it outright.

#13. Change discipline