status: what is really running
status reads the worktree, its manifest and its runs, then returns the runtime facts as they are. It is the one command a session opens with, and it is allowed to say it cannot see.
Four facts, not one
The product keeps apart things a shell one-liner collapses. A live process, a bound port, a passing health check and an exit reason are four different facts, and none of them implies the next.
| Fact | The question it answers | Where it comes from |
|---|---|---|
| Process | Did the process stay alive? | The run record: pid, start, end, exit code. |
| Listener | Which address is actually bound? | The listener observation, with its own trust state. |
| Health | Does the service answer its health check? | The declared HTTP, TCP or command check. |
| Exit | If it ended, why? | The most recent exit reason and the log it points at. |
hello-worktree · main
api running :21730 health 200
worker running no port
2 services · manifest oberth.yaml
Read the table
The human table is ordered by project, service, dependencies, code and failure reason. Each service line carries both the declared port and the current runtime fact; the failure section shows only the most recent exit while it is still that service's current last_exit.
- A portless worker is printed as
no port. It is observed through its run record, not through a listener. port: autobefore assignment printsauto port unassigned; it is not a failure.- Only listeners the manifest did not declare are listed separately. A port that belongs to a service appears with that service.
code_changed_since_startsays the process is running older code than the checkout, with a restart hint. It is a code fact, not a runtime failure.
For agents: --brief and --json
oberth status --json --brief
--json's top-level object is worktree. --brief keeps only runtime facts, so it is the cheapest place to start; the full read adds the git summary, drafts, the change list and per-service manifest fields.
worktree.identityis thewt_…value used bydown --identityand by data paths.worktree.services[]carriesrunning,port_actual,health_status,pidandrun_id.exits[]carries the reason, the exit code and ahintthat points at evidence that really exists.observationappears only when the listener table is untrustworthy; its silence means the table was usable.
When observation fails
A sandbox, a permission wall or a platform change can break the listener scan. The engine then reports observation_empty, observation_unrecognized, observation_incomplete, observation_blind or observation_bind_denied. None of those codes means “nothing is listening”, and still less “not running”. The human table says listening unknown; a port: auto candidate is verified by binding rather than by trusting an empty table.
oberth doctor --only listener_observation
Run it in the same kind of process that failed. If the result is blind, retry from a normal terminal, or run oberth serve --detach there and retry; do not loop the same start inside the sandbox and read timeouts as failures.