Documentación
Runtime
The headless runtime and how commands reach it.
En esta página
Overview
The Runtime is the durable daemon that owns pipeline execution. Every
semantic command — tde task, tde project, tde share, tde chat — is a
client of it, and so are the desktop and the Control MCP server. It holds the
job store, the event journal and the leases that keep one machine from running
another machine's work twice.
You rarely need to start it by hand. The first semantic command you run installs
and starts the per-user Runtime service automatically, and later commands compare
the installed unit against the current executable, PATH, profile and log path,
replacing a stale one before the command proceeds. tde runtime is the explicit
admin surface for when that goes wrong, or when you want a second, isolated
profile.
tde runtime status
tde runtime logsCommands
tde runtime <start|run|detached-run|status|list|restart|stop|kill|cleanup|logs> [profile]
tde runtime jobs [profile] [list|get ID|cancel ID|status]
tde runtime exec [--idempotency-key KEY] [profile] -- <command> [args…]
tde runtime service <systemd|launchagent|install> [profile]| Verb | What it does |
|---|---|
start | Brings the profile up, preferring the managed service and falling back to a detached process. Prints the pid. |
run | Runs the Runtime in the foreground, in this terminal. |
detached-run | Detaches from the controlling terminal first, then runs in the foreground of the new session. |
status | Prints the profile's status as pretty JSON. This is the default with no verb. |
list | Prints that status object for every profile found on disk. |
restart | Stop, brief pause, start — through the same preferred path as start. |
stop | Stops it through the service manager when installed, otherwise directly. |
kill | Signals the verified process, waits, then removes its files. |
cleanup | Removes the profile's ownership files without signalling anything. |
logs | Prints runtime.log to stdout. |
jobs | Inspects and cancels durable jobs. |
exec | Enqueues a bounded process-exec job. |
service | Prints or installs the user service definition. |
The optional profile argument defaults to default. Unlike the semantic CLI —
which refuses any profile but default — tde runtime is where alternate
profiles are legitimate, for isolated process execution and for testing.
State on disk
Everything a profile owns lives under ~/.tde/runtime/<profile>/:
| Path | Contents |
|---|---|
semantic.sock | The semantic control socket every CLI client connects to. |
control.sock | The internal control socket. |
pid | Verified process identity of the running Runtime. |
status.json | Heartbeat the status commands read. |
runtime.lock | Start lock, so two launches cannot race. |
runtime.log | What tde runtime logs prints. |
jobs/ | Durable job store. |
Directories are created 0700 and the log 0600 before anything starts.
Managed service versus detached fallback
start, restart and stop all prefer a managed user service when one is
installed — a systemd user unit named tde-runtime-<profile>.service on Linux, a
LaunchAgent labelled dev.tde.runtime.<profile> on macOS. When the unit is not
installed, or the service manager is unavailable, or the managed start does not
become ready within 15 seconds, TDE reports the reason on stderr and falls back
to a detached process for the current login session.
That fallback is deliberate: a broken residual unit or a host with no usable user service manager degrades to a working Runtime instead of blocking every CLI command.
tde runtime service systemd # print the unit
tde runtime service launchagent # print the macOS plist
tde runtime service install # write it for this platformService installation is transactional. TDE keeps the previous definition, verifies the new Runtime through its semantic socket and version heartbeat, and restores the old definition if activation or readiness fails.
Stopping safely
stop is the ordinary path. kill is the forceful one, and it is deliberately
conservative:
- It signals only processes whose recorded identity — pid, start time and executable fingerprint — still matches.
- If no signalable identity remains but ownership files are still present, it
refuses and tells you to run
cleanuponce you have confirmed the profile is stopped, rather than deleting state that might belong to a live process. - If it signals but the process does not exit, it preserves the ownership files and reports the failure.
cleanup is the manual escape hatch for the refusal case. It removes files and
nothing else, so run it only after you have verified nothing is running.
Jobs
tde runtime jobs
tde runtime jobs list
tde runtime jobs get 42
tde runtime jobs cancel 42
tde runtime jobs statusAll four subcommands print pretty JSON with an ok flag, an optional code and
message, the payload, and a diagnostics array. list is the default when no
subcommand is given. The profile is optional and positional: tde runtime jobs scratch list reads the scratch profile, while tde runtime jobs list reads
default — the parser recognises the four subcommand names and treats anything
else in that position as a profile name.
A job that cannot be found returns job_not_found; a malformed id returns
invalid_input. Neither is a crash, and both come back inside the same envelope.
Executing a command as a durable job
tde runtime exec -- cargo test --workspace
tde runtime exec --idempotency-key nightly-2026-07-25 -- ./scripts/nightly.sh
tde runtime exec scratch -- ls -laexec enqueues a bounded process-exec job and prints the enqueued record
immediately — it does not wait for the command to finish or stream its output.
Poll the result with tde runtime jobs get <id>.
The -- separator is mandatory and everything after it is the argument vector,
so flags belonging to your command are never mistaken for TDE's. --idempotency-key,
when present, must come first; the optional profile sits between it and the --.
An empty argument vector is a usage error.
What keeps running without a desktop
The Runtime executes bounded process_exec jobs, complete pipeline_stage
snapshots and Bot connector_poll jobs with no desktop and no Web Share
session open. Jobs use SQLite leases, fencing, idempotency, cancellation, retry
and immutable execution snapshots; event cursors are durable, monotonic and
resumable across both client and daemon restarts. API keys are re-read from the
vault at execution time and never written into job payloads, event JSON or debug
output.