# Telos CLI

The Telos CLI is the command-line client for developers and agents. It uses
the same API as the Telos web UI and can run Goal Specifications locally or
manage them in Telos Cloud. In CLI commands, `Goal` is shorthand for a Goal
Specification, or Goal Spec.

## Quickstart

Install the CLI (macOS and Linux, amd64 and arm64):

```bash
curl -fsSL https://usetelos.ai/install.sh | sh
telos --version
```

Write a Goal Spec. A Goal Spec is a markdown file: YAML frontmatter for identity,
plain English for intent.

```markdown
---
version: 0.1.0
name: hello-service
platform: local
---

# Goal

Build a small HTTP service with `/healthz`, tests, and local run
instructions.
```

Run it as a bounded task:

```bash
telos run SPEC.md --workspace . --until 3
```

`--until 3` allows up to three review cycles; `--until 30m` bounds by wall
clock instead. Local runs execute through the open-source `pi` coding agent
(`npm install -g @earendil-works/pi-coding-agent`).

When you want the Goal to outlive the run, deploy it to Telos Cloud as a
durable controller:

```bash
telos login
telos apply SPEC.md
telos list
```

## Goal Specifications and skills

A `SPEC.md` file is the entrypoint: the one artifact you hand to `run` or
`apply`. Skills are the capabilities it declares — reusable, versioned
units of know-how and standards that the runtime loads on the Goal's
behalf. The Goal carries the intent; its skills carry the expertise and the
quality bar. You compose them in the Goal's frontmatter, and from then on
they travel together.

| field      | required | meaning                                                                     |
| ---------- | -------- | --------------------------------------------------------------------------- |
| `version`  | yes      | semver, no leading `v` (e.g. `0.1.0`); the published package version         |
| `name`     | yes      | lowercase DNS-style name: `^[a-z][a-z0-9-]{0,62}$`                           |
| `platform` | no       | `local` or `cloud` (default: `cloud`)                                        |
| `skills`   | no       | skill references; append `*` to make one a required grading rubric           |
| `interval` | no       | reconcile cadence for applied Goals: `30s`, `5m`, `1h`                       |
| `extends`  | no       | path to a parent Goal this one builds on                                     |
| `tags`     | no       | free-form labels                                                             |

The body must be non-empty; by convention it opens with a `# Goal` heading.
Write an outcome, not a task list: the runtime treats the body as a contract
to verify against, so the more checkable the statement, the more the
verifier can enforce. "The service answers `/healthz` within 200ms" has
teeth; "improve the service" does not.

**A skill is a directory** with a `SKILL.md` (name, description,
instructions) and optional `scripts/`. Goals reference skills by name, by
path, or by registry ref:

```yaml
skills:
  - k8s-deploy            # local directory or built-in catalogue name
  - "@acme/observability" # published skill from the registry
  - verify-slo*           # starred: a rubric the verifier must grade
```

References resolve in order: a path relative to `SPEC.md`, then
`skills/<name>` next to it, then the built-in catalogue (`@telos/...` names
always mean the platform catalogue; set `TELOS_SKILLS_DIR` to use your own).

**The `*` is enforcement.** An unstarred skill is guidance: the
implementation agent draws on it while it works. Starring a skill changes
its role: it becomes a mandatory grading rubric that the evaluation agent
must mark PASS or FAIL, with evidence, before the work can count as done —
and any FAIL blocks it. This is how a team encodes its real quality bar.
The Goal's body stays plain English; the star is where rigor attaches:
engineering standards, compliance requirements, SLOs. Two rubric skills,
`verify-quality` and `verify-engineering`, are included on every run by
default, and default rubrics are hidden from the implementation agent — it
has to build work that survives checks it hasn't seen.

**Publishing couples them.** `telos push` packages a Goal together with
every skill it references, pinned by digest:

```bash
telos push ./skills/k8s-deploy --scope acme   # publish a skill
telos push SPEC.md                            # publish a versioned Goal package
```

The result is a package: a locked closure of the Goal plus exactly the
skill versions it was written against. Nothing in a package floats — a
published Goal always runs with the skills it shipped with, and changing a
skill means publishing a new version.

Preview what a Goal compiles to without running anything:

```bash
telos plan SPEC.md
```

`plan` prints the target platform, content hash, and resolved skills, and
never mutates anything. Add `--json` for the machine-readable form.

## run and apply

One Goal, two lifecycles:

```bash
telos run SPEC.md      # meet the Goal once, report, exit
telos apply SPEC.md    # hold the Goal as desired state, indefinitely
```

`telos run` is bounded work. The Goal is executed as an adversarial game
between two agents: an implementation agent operates on the system, then an
independent evaluation agent attacks the result against the Goal and its
skill rubrics. They alternate until the evaluator concedes the world matches
the Goal, or the budget runs out. `--until` sets that budget as review
cycles (`--until 5`) or wall clock (`--until 30m`), and a run is allowed to
fail by exhausting it. Failure is loud, never silent.

`telos apply` is the control loop. It creates a durable controller session
that reconciles the Goal continuously: verify, repair drift, record
evidence, sleep, wake. To change what the controller holds, edit the Goal
file and re-apply it to the same session:

```bash
telos apply SPEC.md --session sess_9f2ka81
```

Observe and manage sessions with the rest of the surface:

```bash
telos list                  # sessions and their status
telos describe sess_9f2ka81 # lifecycle, cost, service URL, evidence paths
telos logs -f sess_9f2ka81  # progress, reviews, verdicts; -f follows
telos delete sess_9f2ka81   # stop and remove (local history is preserved)
```

## CLI reference

```
telos plan SPEC.md       Preview a Goal without running it
telos push SPEC.md|DIR   Publish a versioned Goal or skill for reuse
telos run SPEC.md        Run a Goal as a bounded task
telos apply SPEC.md      Create or update a durable session from a Goal
telos list               List sessions
telos describe SESSION   Show session details
telos logs SESSION       Show session progress
telos delete SESSION     Delete a session
telos login              Log in to Telos Cloud
telos version            Show version
```

### telos plan

```bash
telos plan SPEC.md [--json]
```

Compiles the Goal and reports what would run: name, target platform,
namespace, content hash, resolved skills, and whether launching would create
a session. Read-only; requires no authentication for local Goals.

### telos run

```bash
telos run SPEC.md [--workspace DIR] [--until N|DURATION]
                  [--model MODEL] [--thinking LEVEL] [--max-cost-usd USD]
                  [--json]
```

Runs the Goal as a bounded task and reports the session it created.

- `--workspace DIR` seeds the working directory for a new session.
- `--until` bounds the run: an integer is review cycles, a duration
  (`90s`, `30m`, `2h`) is wall clock.
- `--thinking` sets reasoning effort (default `medium`).
- `--max-cost-usd` caps spend (default `20`).

### telos apply

```bash
telos apply SPEC.md [--session SESSION] [--workspace DIR]
                    [--model MODEL] [--thinking LEVEL] [--json]
```

Creates a durable controller session for the Goal, or updates an existing
one when `--session` is given. Cloud Goals are pushed as a versioned package
first; the receipt includes the package digest, service URL, and dashboard
URL. Runtime flags (`--workspace`, `--model`, `--thinking`) seed new
sessions only; an existing session keeps its configuration.

### telos push

```bash
telos push SPEC.md [--scope SCOPE] [--version VERSION] [--json]
telos push SKILL_DIR [--scope SCOPE] [--version VERSION] [--json]
```

Publishes a versioned Goal package or a skill directory (anything containing
a `SKILL.md`). The version comes from frontmatter unless `--version`
overrides it; referenced skills are published recursively and pinned by
digest. The receipt reports the ref, digest, and version.

### telos list

```bash
telos list [--limit N] [--wide] [--local] [--cloud] [--json]
```

Lists sessions: name, target, status, and session ID, plus the service URL
for cloud sessions. Defaults to cloud sessions when you are logged in;
`--local` forces the local store. Child sessions are hidden unless `--wide`.

### telos describe

```bash
telos describe SESSION [--json]
```

Shows a session's lifecycle in full: status, result, current turn, cost,
Goal version, evaluation disposition, service URL, and (for local sessions)
filesystem paths to the workspace, evidence log, and transcript.

### telos logs

```bash
telos logs [-f] [--verbose] SESSION
```

Prints session progress: numbered progress updates, review verdicts, and
summaries. `-f` follows until the session reaches a terminal state.
`--verbose` prints raw events instead of the parsed view.

### telos delete

```bash
telos delete SESSION [--json]
```

Stops and removes a session. Local session history is preserved on disk;
cloud deletion tears down the deployment.

### telos login

```bash
telos login [--endpoint URL] [--token TOKEN] [--no-prompt]
```

Authenticates against Telos Cloud (default endpoint
`https://api.usetelos.ai`) and writes `~/.telos/config.yaml`. The token is
read from `--token`, then `TELOS_AUTH_TOKEN`, then an interactive prompt.

## For agents

This section is the machine contract. If you are an agent driving the CLI,
these are the invariants to rely on.

**Output.** Every command above accepts `--json` and prints a single
pretty-printed JSON object to stdout (`logs` uses `--verbose` for raw event
lines instead). Human-readable receipts are not stable interfaces; the JSON
is.

**Exit codes.** `0` success. `1` any runtime or usage error, with a message
on stderr prefixed `error:`. `2` flag parse failure.

**Configuration.** File: `~/.telos/config.yaml` with `api_endpoint`,
`auth_token`, `org_id`. Environment overrides: `TELOS_CONFIG` (config path),
`TELOS_API_ENDPOINT`, `TELOS_AUTH_TOKEN`, `TELOS_ORG_ID`. Flag fallbacks:
`TELOS_WORKSPACE`, `TELOS_MODEL`, `TELOS_THINKING`, `TELOS_MAX_COST_USD`.
Skill catalogue: `TELOS_SKILLS_DIR`. Local session store: `TELOS_SESSION_DIR`.

**Session routing.** Session IDs are prefixed: `sess_` is a cloud session,
`local_` is a local controller. Local sessions are workspace-scoped: run
commands from the directory where the session was created, or point
`TELOS_SESSION_DIR` at its store.

**Doneness.** Poll `telos describe SESSION --json`. For bounded runs, the
evaluation disposition resolves to `accepted`, `pending`,
`review budget exhausted`, or `not accepted`. Cloud sessions move through
`provisioning`, `deploying`, `healthy`, `failed`, `deleted`; `healthy` and
`failed` are terminal for a deploy. `telos logs -f` exits when the session
reaches a terminal state.

**Evidence.** Every session writes an append-only transcript and a
structured evidence log: verdicts, findings, costs, and workspace
checkpoints. `telos describe` reports their paths for local sessions. Treat
the evidence log, not the model's summary, as the record of what happened.

**Goal Spec authoring.** When writing `SPEC.md` for a user: `version` must be
bare semver (`1.0.0`, never `v1.0.0`), `name` must match
`^[a-z][a-z0-9-]{0,62}$`, the body must be non-empty, and skills you star
with `*` become mandatory rubrics that block completion when they fail.
Prefer verifiable clauses; every checkable sentence you write becomes
something the verifier can enforce.
