Operate and move a host
Inspect, cancel, rotate, and relocate a process host while its authority, application state, and evidence stay together.
On this page
The end state is one durable process host state with one serving owner at a time. You inspect it while it runs, cancel or revoke work inside it, rotate its worker connections, and move it to a new path with its history intact.
The state directory is the source of authority: process identities, capability lineage, admissions, receipts, mailboxes, checkpoints, blobs, and run attempts. The examples use .chio from the report project; in a deployment, select the directory of the host you are inspecting.
Relocate one active lineage
Export retires the source process and seals its history before any file is copied. Import validates the sealed files and rebinds them on the destination host with the same runtime and process identities. Keep every other copy inaccessible: a second import would start a second lineage.
Drawn fromreport/exercise-state.py
1. Keep the state directory whole
Run one active host against the directory. These records live in it:
process.db identities, logical calls, checkpoints, blobs, credentials
runner.db bound plan, attempts, joins, worker/socket ownership
run-status.json derived observation; never a recovery input
run-logs/ bounded stdout/stderr for retained attempts
host authority signing material, policy/manifest bindings and kernel stores
export manifest relocation seal after source retirementRetain the complete directory, because SQLite sidecars and kernel stores belong to the live persistence unit, and move it only through export and import (step 7). Inventory what lives outside it, such as application graph databases, provider configuration, and absolute executable paths. Protect diagnostic output too: exact credential redaction leaves any secret that worker code prints.
2. Inspect a run before intervening
chio process status --state .chio
chio process logs --state .chio --process consumer --attempt 1
chio process state --state .chio --process consumerStatus combines the retained journal with a sampled host-lock observation, so it can be stale when you read it; reading it creates no second serving owner. Attempt logs are bounded and abrupt death can lose them. The offline state reader returns a checkpoint revision and value, or a verified immutable blob, without starting tools or renewing authority.
Check the application result and the original signed receipts separately; a successful worker exit shows neither.
3. Read a stopped host’s status and attempt log
The status below is the report project’s stopped host, and the attempt log comes from the same run.
chio process status --state .chio{
"schema": "chio.process.status.v1",
"abi": {
"serving": "chio.process.abi.v4",
"host": "chio.process.abi.v4",
"written_by": "chio-cli 0.1.0"
},
"host_lock_held": false,
"run": {
"schema": "chio.process.run-status.v1",
"run_id": "4d8d1c38-2e07-463e-9939-6f316f846357",
"observed_at_ms": 1790169816079,
"plan_binding": "fef9807c5d5902ad71c8966cb23d69f2b48b98304e069fa75808fcc426001530",
"max_parallel": 2,
"workers": [
{
"process": "consumer",
"state": "completed",
"attempts": 1,
"max_attempts": 2,
"suspensions": 0,
"max_suspensions": 64,
"outcome": "exit_0",
"waiting_on": [],
"peak_resident_bytes": 48365568,
"cpu_ms": 43
},
{
"process": "producer",
"state": "completed",
"attempts": 2,
"max_attempts": 2,
"suspensions": 0,
"max_suspensions": 64,
"outcome": "exit_0",
"waiting_on": [],
"peak_resident_bytes": 25448448,
"cpu_ms": 88
}
]
}
}chio process logs --state .chio --process producer --attempt 1{
"schema": "chio.process.logs.v1",
"process": "producer",
"attempt": 1,
"logs": {
"stdout": "",
"stderr": ""
}
}You should see host_lock_held false for the stopped host and two producer attempts ending in exit_0. The streams are empty because the producer writes its receipt to an application file and exits 77 silently; the log reader returns attempt 1 as asked, never the latest.
4. Work from observations to a recovery decision
Status reads neither reconcile a stale worker nor consume an attempt.
- Preserve. Record status and the selected attempt log. Leave the journals and
run-status.jsonuntouched. - Establish liveness. Compare
observed_at_ms,host_lock_held, and the operator’s process knowledge; a running snapshot with a free lock can be stale. - Inspect progress. Read process state and application-owned checkpoints, and identify original keys and unresolved phases.
- Inspect effects. Use the original receipts and the resource’s own outcome lookup to separate a known failure from an unknown effect.
- Resume deliberately. Run the same bound plan if its state permits recovery, keeping its ceilings instead of minting fresh authority.
- Validate. Check the final artifact, attempt counts, and signed evidence; exit zero alone is insufficient.
observed_at_ms timestamps the snapshot, run_id changes each time a run opens, plan_binding identifies the original plan and authority, and waiting_on names unmet dependencies. A missing attempt log leaves open whether the worker ran: ask for the exact attempt and record the absence.
5. Revoke a connection or cancel work
chio process revoke --state .chio --process producer
chio process cancel --state .chio --process producerRevocation is a connection decision: it removes the worker credentials of the selected process and its subtree, keeps identity and checkpoints, and allows a fresh connection later. Cancellation permanently stops new admissions, checkpoints, and blob access for the selected process tree, leaving its history readable. Both act on a live host through the host authority, which a worker cannot reach over its process connection.
Cancel the narrowest subtree that must stop taking new work. An already admitted call can still complete its effect, so retain the checkpoint and receipts, inspect downstream assignments, reassign a shared resource through its authorized mutation transaction, and test that the old caller's fresh write is refused. A new credential leaves a cancellation in force; before the task continues elsewhere, decide which original operations remain unresolved. Execution security covers admission and confinement.
6. Rotate a serve connection while stopped
Stop the serving host and wait for shutdown and draining to finish, then revoke, issue a new private socket and descriptor, and serve again.
chio process revoke --state .chio --process consumer
mkdir -m 700 socket-next connections-next
chio process credential --state .chio --process consumer \
--socket socket-next/process.sock --out connections-next/consumer.json
chio process serve --state .chio --socket socket-next/process.sockDeliver the new descriptor privately to the same worker. You should see the old credential fail to authenticate, with process ID, operation history, and capability expiry unchanged. Under chio process run, the runner rotates credentials at startup and each attempt and revokes them after shutdown; manual descriptors in that lifecycle obscure which connection is current.
7. Move the state, then prove continuity
Export seals the authority heads and a digest manifest, retires the source directory, and folds application write-ahead logs. Import checks the copied files and rebinds the host at the destination.
chio process export --state .chio
mkdir -m 700 ../destination
cp -a .chio ../destination/.chio
chio process import --state ../destination/.chio
chio process status --state ../destination/.chio- Stop and seal. Stop the host and workers, then export. Continue once export succeeds and retains the seal and manifest; the source authority is now retired.
- Copy and validate. Copy the complete sealed directory to a new destination and import it. Import accepts the ABI, the file digests, and the rebound filesystem identities before the host resumes.
- Check continuity. Compare runtime and process identities, checkpoints, and retained operations at the destination with the original state, then resume the original plan. Keep the source inaccessible: importing it again would start a second lineage from the same history.
You should see the destination status report the same identities. Import reanchors path and file identity after validating the sealed copy and leaves executable argv, working directories, graph database paths, and tool-policy dependencies as bound. Confirm the plan file, policy, executables, and inputs exist at those bound paths before retiring the source.
The state exercise’s checkpoint after export and import
{
"schema": "chio.process.application-state.v1",
"process": "a",
"data": {
"checkpoint": {
"revision": "1",
"value": {
"report.v1": {
"completed": [
"one"
]
}
}
}
}
}The ABI recorded in state decides which binary may serve it
The host records chio.process.abi.v4 in its state, covering the journal, worker connection, host configuration, run plan, status, logs, and relocation manifest. A host binary with another ABI refuses to serve or import the state, so finish old work with its compatible binary or a supported migration; relocation stays within one ABI. Keep the kernel public key and receipts available to independent verifiers.
History and validity are budgets that a restart never renews
Monitor process-call slots, process count, blob bytes, and blob records separately; cancellation refunds no allocated identities or shares. Blob quotas exclude database indexes and WAL overhead, and log caps bound only the logs. The host keeps orphaned blob history, so set a retention and lifecycle policy before a long-lived application reaches its limits; export preserves state and compacts nothing.
Credential expiry stays within the underlying capability. A worker restart, host restart, or move renews neither the authority nor an application wall-clock budget, so schedule maintenance with enough lifetime left to finish the task. After expiry, inspect results through offline state and receipt verification; a new connection revives no execution.
A stopped run names the record to read next
Completed worker, missing application output
Read the process checkpoint and validate the output contract.
Unknown tool outcome
Recover through the original logical key under its recovery policy; the kernel never re-dispatches an unknown outcome. Reconcile at the effect owner before any replacement work.
Lost launch or wait observation
Inspect the owned worker or container and the retained attempt. The runner holds uncertain work instead of charging and relaunching it.
Expired credential
Stop, decide whether the existing authority is still valid, and issue a fresh private connection when authorized.
An interrupted move resumes from the phase it reached
Retry on the same retained state and manifest; a replacement host initialized to reuse old operation keys starts a second lineage.
| Observed phase | Next step | Avoid |
|---|---|---|
| Host still active | Stop workers and drain admitted calls | Copying live SQLite files as a relocation artifact |
| Export interrupted | Retry export on the same source after diagnosis | Initializing another host with similar keys |
| Export sealed, copy incomplete | Preserve the source seal and make a complete copy | Importing a partial directory |
| Import interrupted | Retry on the same destination and manifest | Editing digests to force a match |
| Import complete | Keep the source retired, preserve bound paths, resume the plan | Activating another copied lineage |
| ABI differs | Use the compatible binary or a supported migration | Treating export and import as a format upgrade |
Import refuses a copied directory without a matching export seal. Abandoned socket ownership records or unconfirmed container identities can need reconciliation before export; never delete an object only because a journal mentions its path.