Menú de documentación

Documentación

Runtime daemon

The per-user service that keeps work running with no desktop open.

En esta página

Work that does not need you watching

The TDE Runtime is a per-user background service that owns durable execution. It runs pipeline stages, Bot polls and bounded shell commands with no desktop open, no terminal attached and nobody logged into a UI. Close every TDE window on a VPS and your tasks keep moving.

It is not the same thing as a session. A session keeps a desktop alive so a person can come back to it. The Runtime keeps work alive so it finishes whether or not anybody comes back.

bash
tde runtime status
tde runtime jobs

This page explains the model. The verbs, flags and JSON shapes are in the tde runtime reference.

It installs itself

You do not normally start the Runtime. The first semantic command you run — tde task, tde project, tde pipeline, tde share, tde ask, tde chat — installs and starts the per-user service before it does anything else.

Later commands re-render the service definition from the current executable path, the resolved PATH, the profile name and the log path, then compare it byte-for-byte with the installed file. Missing or drifted means the service is replaced and reloaded before the command proceeds. Upgrade TDE and the very next CLI invocation quietly repoints the unit at the new binary.

PlatformWhat gets installed
LinuxA systemd user unit, ~/.config/systemd/user/tde-runtime-<profile>.service
macOSA LaunchAgent, ~/Library/LaunchAgents/dev.tde.runtime.<profile>.plist, in the gui/<uid> domain

Installation is transactional. TDE keeps the previous definition, writes the new one atomically, activates it, and then requires a real readiness proof — a heartbeat whose version matches the running binary, a live pid, an existing socket, and a successful ping/pong over the semantic socket — within 15 seconds. If any of that fails it restores the previous definition and its previous enabled state. On Linux it also refuses to manage a unit that systemd resolves to a file path TDE did not write.

When there is no service manager

Some hosts have no usable user service manager, or a broken residual unit. Rather than block every CLI command, TDE announces the reason on stderr and falls back to a detached Unix session: it spawns tde runtime detached-run, whose first act is to call setsid(). Closing the terminal that started it does not deliver a hangup to the daemon.

The fallback lasts for the current login or boot, not across reboots. It is entered when the service manager preflight fails, when a managed start does not become ready in 15 seconds, or when an activation rolled back.

What it executes

Jobs are typed. Three kinds have production executors:

Job kindWhat it does
process_execRuns one bounded command with a cleared environment and a fixed safe PATH. Enqueued by tde runtime exec.
pipeline_stageRuns a complete My Loop pipeline from a frozen execution snapshot.
connector_pollRuns an Bot cron or webhook trigger.

Concurrency is modest and worth knowing: one process job and one business job per profile at a time. The Runtime is a reliability mechanism, not a build farm.

How a job survives everything

The job store is a SQLite database under ~/.tde/runtime/<profile>/jobs/. Five mechanisms stack on top of it.

Leases. A worker claims a job by writing an owner and a lease deadline (30 seconds by default), then heartbeats it every 10 seconds. Nothing else may touch a claimed job while its lease is live.

Fencing. Each lease carries a monotonic generation. Every completion, failure, cancellation and journal append re-checks owner and generation, so a worker that was presumed dead and came back cannot commit a result over its successor.

Idempotency. A job may carry an idempotency key, unique per kind. Re-enqueuing returns the existing record instead of duplicating work — a pipeline run is keyed on the task and the run intent, an Bot on its id and trigger, so a retried CLI call or a replayed webhook is a no-op.

Recovery, not backoff. A job whose lease expired is examined, never blindly retried: if a cancel was requested it becomes cancelled; if it has already used its attempts (three by default) it becomes failed; otherwise it goes back to queued. A process_exec job that still has a recorded live child is left alone until that child is reaped. There is no exponential backoff — requeues are immediate, paced only by the 50 ms poll.

Cancellation. Cancels are cooperative and are recorded even without a lease. Executors observe the request at checkpoints. Shutdown-induced interruption is distinguished from a user cancel so external leases stay recoverable.

Frozen snapshots

A pipeline job does not read live configuration when it eventually runs. At dispatch time TDE freezes an immutable execution snapshot into the job payload: the pipeline definition, the agent chosen for each stage, and the run config — model routing, budgets, cycle limits, verification commands and timeouts.

Editing a pipeline afterwards does not mutate a run that is already queued. It also means a queued run cannot be surprised by a stage whose agent was deleted: the snapshot is validated on the way in and on the way out.

Durable, resumable events

Two journals back the "watch a task from anywhere" experience.

Each pipeline run appends a JSON-lines journal, one line per event, flushed and fsync-ed before the call returns; a torn tail from a crash is repaired on open and the sequence resumes. A crash can lose at most the in-flight line.

Separately, a SQLite event store holds control events keyed by a monotonic event_id. Readers pass the last id they saw and get everything after it, up to 1000 at a time. That cursor is the whole trick behind tde task watch and tde task logs surviving both client and daemon restarts — the reader is stateless and the store is authoritative. A durable intent outbox does the same job in the write direction, reconciling any pending task create, retry, cancel or gate decision at daemon boot.

Where it keeps things

PathContents
~/.tde/runtime/<profile>/semantic.sockThe control socket every CLI client connects to.
~/.tde/runtime/<profile>/jobs/The job store and the per-run event journals.
~/.tde/runtime/<profile>/runtime.logWhat tde runtime logs prints.
~/.tde/runtime/<profile>/status.jsonThe heartbeat the status commands read.

Directories are created 0700 and the log 0600 before anything starts. The socket is a 0600 Unix domain socket and is never bound to a TCP port on any interface — anything that can talk to it is already running as you.

The desktop and Web Share are peers, not clients-of-a-proxy: they read the same durable board, project, pipeline and job stores the Runtime writes. There is no separate "CLI board", and no rendered frames travel over the semantic socket.