stella cloud
Read and set the org and workspace identity that scopes replicated telemetry, and send that telemetry to an org intake you configure.
Every row stella usage copies to the hub carries an identity: which organization it reports to, which workspace it came from, and which repository that workspace maps to. stella cloud is where you read that identity, set it, and, if you configure an endpoint, upload data under it.
Login is still a work in progress: register saves ids locally and creates a durable workspace id, and the login step that will attach a token will write to the same file later. Registration alone doesn't upload anything and doesn't change what telemetry is collected, only which ids get stamped on it.
Synopsis
stella cloud status
stella cloud register --org <ORG_ID> [--workspace-id <ID>]
stella cloud sync
stella cloud logout
stella cloud deregisterA subcommand is required. None of them needs a provider or an API key.
What it does
Four ids describe an installation, and each answers a different question:
org_idThe organization this installation reports to. NULL until you register.
STELLA_ORG_ID wins if set; otherwise it comes from the org_id in
~/.stella/cloud.json, written by stella cloud register.
workspace_idA durable id at <root>/.stella/workspace.json, written only by registration
and never created automatically. An unregistered workspace reports NULL. It lives
outside .stella/private/, so committing it gives every clone and every
machine one shared workspace identity.
repo_idA workspace is only usually a repository. repo_id is built from the normalized origin
remote URL (the SSH and HTTPS forms of the same repo count as the same one), and
falls back to the folder path when there is no git remote. Rows carry it separately so a multi-repo
workspace still reports per repository.
project_idA hash of the workspace's own path. Always present, registration or not, and it
is the key replication runs on. This is what makes stella usage work on a machine
that has never heard of a cloud org.
Resolving these ids never fails: telemetry scoping must never break a turn, so unregistered ids resolve to NULL, and a missing git remote falls back to the path-based id instead of erroring.
stella cloud status
Print this installation's identity for the current workspace, and, once an org is set, any rows the cloud intake permanently rejected.
stella cloud statusUnregistered:
org_id: (not registered)
workspace: (not registered)
repo_id: 9f2c1ad4e7b03518
project: 4b81c0e2f39a77de
register with `stella cloud register --org <org-id>` — telemetry replicates locally either way; org scoping gates what a future cloud sync would shipRegistered:
org_id: acme
workspace: 6f1d8a20-4c3e-4a71-9a55-2d0be1c7f5aa
repo_id: 9f2c1ad4e7b03518
project: 4b81c0e2f39a77deQuarantined rows
Once an org is registered, status also reports rows the cloud intake rejected permanently. This is the only place they show up. The drain sets these rows aside and moves past them so newer rows keep flowing, which means everything downstream can look healthy while a rejected row sits in the hub unnoticed.
quarantined: 3 row(s) the cloud intake permanently rejected
2 x HTTP 422: model slug not in the intake catalog
1 x HTTP 413: payload too large
retained in the hub for inspection; the cursor advanced past themAt most three reason groups are listed before the rest fold into a +N more reason(s) line. The rows themselves stay in place; nothing is deleted. Since status answers about identity first, this check does its best: if the hub can't be opened, it prints a one-line note instead of failing the command.
stella cloud register
Save an org id and register this workspace.
--org <ORG_ID>RequiredThe cloud organization id telemetry reports under. Saved to ~/.stella/cloud.json,
the same file that will hold your login token later, so registration and
login stay in one file. Cannot be empty.
--workspace-id <ID>Use a workspace id issued elsewhere instead of creating a new one. Ignored if this workspace is already registered. Registration only runs once, and an existing id always wins, because one workspace must never end up with two identities.
stella cloud register --org acmeregistered to org acme (stub — OAuth login lands later)
workspace id 6f1d8a20-4c3e-4a71-9a55-2d0be1c7f5aa written to .stella/workspace.json
commit .stella/workspace.json so every clone reports as this workspaceCommit .stella/workspace.json. It lives outside .stella/private/ for exactly that
reason. Without it, a clone has no workspace id until someone registers there,
and if they do, the same project ends up reporting under two identities.
The file it writes is small and easy to read:
{"workspace_id": "6f1d8a20-4c3e-4a71-9a55-2d0be1c7f5aa"}stella cloud sync
Send staged hub telemetry to the org intake set in ~/.stella/cloud.json's
drain block. This is the one command in this group that uses the network.
stella cloud syncIt does nothing unless both an org_id (from register) and a drain block are
present. No block, no network traffic. The block also carries the intake credential, which is
why cloud.json is saved so only you can read it:
{
"org_id": "acme",
"drain": {
"url": "https://intake.example.com/v1/telemetry",
"format": "stella",
"token": "…",
"batch_size": 200
}
}| Field | Default | Meaning |
|---|---|---|
url | required | The HTTPS org intake batches are sent to |
format | stella | Wire format: stella (the native schema-versioned batch) or otel (OTLP). An unknown value fails and stops |
token | none | Bearer credential for the intake. oauth_token wins when both exist |
batch_size | 200 | Rows per request |
Rows the intake rejects permanently are set aside, and the cursor moves past them so
newer rows keep flowing. They show up under status. A temporary
failure is reported as something you can retry, so just re-run the command.
This is a second, separate export path from the
Oxagen Enterprise managed export.
It has its own wire format, its own endpoint, and its own opt-in: a drain block in
a file you write yourself, pointed at an intake you run. Enterprise enrollment does
not turn this on, and this does not turn on enterprise enrollment.
stella cloud logout
Delete the stored credentials and remove the drain block, which stops uploads. Registration
and local hub telemetry stay in place.
stella cloud deregister
Does what logout does, plus clears the org id, returning the installation to unregistered. Hub rows
keep the org they were captured under; unsent rows for the old org stop sending and
stay local. Delete them with stella usage prune --force if that's what you want.
What registration alone does not do
- It does not upload anything by itself.
registerwrites two local files. Uploading needs adrainblock and runningstella cloud sync. Telemetry is copied into~/.stella/usage.dbwhether you register or not. - It does not change what is collected. Only the ids stamped onto each row change, from
NULLorg and workspace to yours. - It does not relabel history. Rows written before registration keep their
NULLorg, which is whystella usage report --org <id>leaves them out.
It does change one thing worth knowing about: once rows carry an org, stella usage prune will not drop rows a cloud drain hasn't acknowledged yet, unless you pass --force.
Examples
Check what identity this workspace reports under before wiring up CI:
stella cloud statusRegister a machine to an org and use a workspace id issued elsewhere:
stella cloud register --org acme --workspace-id 6f1d8a20-4c3e-4a71-9a55-2d0be1c7f5aaScope an org to one shell session without touching cloud.json. The environment variable
wins over the file:
STELLA_ORG_ID=acme-staging stella cloud statusRegister, then confirm the hub is stamping rows the way you expect:
stella cloud register --org acme
stella usage sync
stella usage report --org acme