Skip to main content

CLI

The active Liskov plugin is @proof-computer/proof-cli-liskov 0.14.0 and requires Node.js 22 or later. All commands begin with proof liskov. This release includes the retained V5 authoring, policy, and application source-binding verbs listed below.

npm install --global @proof-computer/proof-cli
proof plugins install @proof-computer/proof-cli-liskov@0.14.0
proof liskov --help

Over-cap refusal output​

The typed organization_over_plan_caps explanation described in Application cap refusals is verified in released plugin 0.17.0. Install that version for the feature, including --json output that preserves the received feature, used, and limit fields:

proof plugins install @proof-computer/proof-cli-liskov@0.17.0

A refused publish, Run, or resume exits nonzero. Earlier documented plugin 0.14.0 does not preserve this typed refusal envelope. Updating the plugin does not enable release-gated Run again, fixed-interval execution, or paid billing paths. Use the cap troubleshooting steps to reduce usage and verify it before retrying.

Session​

CommandEffect
loginStart browser-confirmed GitHub login. Use --no-browser to print the verification URL.
whoamiRead current identity, effective organization, and persistent session organization.
logoutRemove the local session.

Login stores a bearer token in an XDG-style local file with restricted permissions and never prints token material. --config PATH selects another session file.

Organizations and billing​

CommandEffect
organization listList readable organizations.
organization use [SELECTOR]Persistently select the organization for this session.
organization billing [SELECTOR]Read plan and billing projection.
organization service-credits [SELECTOR]Read available, reserved, and used Service Credits.
organization billing transactions [SELECTOR]Page through ledger transactions with --limit and --before.

These commands are read-only. Customer plan changes, terms acceptance, Stripe checkout, and new Service Credit issuance are release-gated; a Console control does not make them supported. organization use changes the persistent organization for the session.

Choose an organization for one command​

Network-backed organization-scoped commands accept an exact organization ID or slug without changing the session default:

proof liskov application list --organization proof
LISKOV_ORGANIZATION=proof proof liskov application status APPLICATION_UID
proof liskov whoami --organization proof

The precedence is an existing positional selector, then --organization, then LISKOV_ORGANIZATION, then the persistent session organization. A selector is required from one of those first three sources for billing and Runtime SSH integration routes. organization use [SELECTOR] accepts the same inputs but is persistently mutating by definition. organization list is always unscoped.

Selectors are trimmed and matched exactly, with an ID match before a slug match. Slugs are case-sensitive. Empty values and values longer than 255 UTF-8 bytes fail locally. The flag has no short alias. Login/logout, admin/access commands, local manifest validation, and local workflow generation do not accept it.

Under an override, human whoami labels both the effective organization and the persistent organization. JSON includes organizationContext.source, organizationContext.effective, and organizationContext.sessionDefault. The override is never written to the local session or an Application runtime environment.

Application reads​

CommandEffect
application listList readable Applications. Each row leads with its lifecycle — Current, Retiring, or Retired — and keeps the stored status beside it. Add --retired for retired Applications only.
application status APPLICATION_IDRead customer-facing Application state.
application activity APP_REFRead activity; accepts --limit and --before.
application logs APP_REFRead managed Application logs: recent by default, streamed live with --follow, or the full retained history with --from-start.
application action-plan APP_REFRead current blockers and supported actions.
application secrets APPLICATION_IDRead declared secret requirements, never values.
application vars list APP_REFRead the active policy's managed variables with their status, default, and value. Values are shown in the clear; put credentials in Secrets. Not yet in a released plugin; see below.
application plans APPLICATION_IDAdvanced effective-policy/plan inspection.
application deployment status APP_REFAdvanced deployment evidence.
application artifact-pin list APP_REFAdvanced artifact-version evidence.

An APP_REF can be the accepted Application UID, name, or ID. Prefer the UID for automation and support.

The application vars list, application vars set, and application vars unset commands are in source 497899feccd466ae10a819c4c86f55303d9bfe88, which is not a released package. Set managed values in the Console until a later plugin release contains that commit. See Variables.

Console Coverage already shows the server's execution-convergence document. The published plugin versions above do not include a CLI sibling for that read. Source 150b7c96d0caa23e757222dd1eb0288db48a368d is not a released package. Use Intended capacity versus remaining charges on Console until a later plugin release contains that commit.

The interval schedule line on application execution show, and the schedule key its --json output adds beside explanation and convergence, are in source 8a930c4, which is not in npm 0.15.0. Fixed-interval execution itself is release-gated; see Capabilities and limits.

Application log flags​

proof liskov application logs APP_REF \
--limit 100 \
--deployment DEPLOYMENT_ID \
--job JOB_ID \
--origin runtime-ssh
proof liskov application logs APP_REF --follow --event 'runtime.access.*'
proof liskov application logs APP_REF --from-start --ndjson

--limit accepts 1–500 and bounds one page. --deployment and --job can be combined. Origin is all, customer, or runtime-ssh (also accepted as runtime_ssh); Runtime SSH records are shown as Runtime SSH in human output.

--follow streams new records until interrupted: it attaches at the newest record, then polls forward every two seconds without losing records. --from-start pages through the full retained history oldest-first with cursor pagination. --event GLOB filters on the record event field; * matches any run of characters. --ndjson emits one raw record JSON object per line and works one-shot or with either streaming flag. A streaming read can return slightly more than --limit records per page because whole batches are kept together; no record is lost between pages.

--json emits the core Liskov /logs response verbatim and is mutually exclusive with --follow, --from-start, --ndjson, and --event. Human output prints the count, then TIMESTAMP LEVEL ORIGIN JOB_ID INSTANCE MESSAGE columns — INSTANCE is the record's runtimeInstanceId (- when absent), identifying which runtime instance wrote the record — and ends with an Origins: customer N, runtime_ssh M. footer from the response summary. Control and terminal escape characters in messages are escaped. An authenticated degraded response exits zero and reports its stable availability reason; authentication, transport, and malformed-response failures exit nonzero.

Authoring and publication​

CommandImportant flags and behavior
application manifest validate --file PATHStrict local V4 or retained V5 validation; read-only.
application create APPLICATION_ID --repository OWNER/REPOCreate an Application from identity alone: no draft, no spend. The retained V5 first step.
application source-binding set APP_REF --repository OWNER/REPO --allowed-ref REF --workflow-identity IDENTITY --manifest-path PATH --yesBind the exact GitHub source a retained V5 Application may publish from; organization admin only; the first binding is revision 1. Available in 0.12.0 and later.
application source-binding show APP_REF --json, application source-binding revoke APP_REF --expected-revision N --reason TEXT --yesRead the current binding, revision, and revocation epoch; withdraw it. Available in 0.12.0 and later.
application policy publish APP_REF --file PATH --artifact-digest DIGEST --source-commit SHA --source-ref REF --workflow-identity IDENTITY --binding-revision N --revocation-epoch N --expected-pointer-version N --yesPublish one retained V5 document through the registered policy-version writer, checked against the binding and the attested build; nothing is sent without --yes.
application policy explain APP_REFRead the canonical retained V5 publication, execution, spend-closeout, and managed-SSH explanation.
application import --file PATHClosed for Manifest V4: the server refuses new imports with v4_publication_disabled. Use Application creation and retained V5 source binding instead.
application import --github OWNER/REPO:PATH@REF --server-fetchClosed for Manifest V4 with the same refusal; fetching from GitHub does not bypass it.
application set-repository APP_REF OWNER/REPOPreview by default; --yes confirms. A confirmed change is refused with v4_publication_disabled, and nothing changes, for an Application whose draft is still a Manifest V4.
application rename APP_REF DISPLAY_NAMEPreview by default; --yes confirms.

The older application publish route is closed for Manifest V4, including its preflight. Use application policy publish for retained V5.

For the retained registered source path, application policy publish accepts --dry-run without --yes, or --paused --reason TEXT --yes to publish with an atomic setup hold (CLI 0.13.0 and a supporting server). Preview and confirmation are mutually exclusive. The existing source-evidence and expected-pointer flags remain required. See the release-gated encrypted JavaScript recipe.

Operations​

CommandBehavior
application action-plan retry APP_REF --decision-id ID --reason TEXT --yesPerform the supported bounded retry for one current decision.
application pause APP_REF --reason TEXTRead preview; add --yes to stop future planning.
application resume APP_REF --reason TEXTRead preview; add --yes to resume future planning.
application retire APP_REFRead retirement preview/state; add --reason and --yes to start.
application retire cancel APP_REFRead cancellation preview; add --yes to cancel while allowed. If the retirement finalized first, this exits zero and prints the immutable receipt: the outcome was reached, so there is nothing left to cancel.
application hold release APP_REFRead the held job and what releasing it would do; add --reason TEXT --yes to request the release. --hold-id ID names the job when more than one is held. Available in 0.14.0 and later.
application vars set APP_REF NAME VALUERead preview of the current and new value; add --yes to apply. An empty string is a value. The name must be a managed variable the active policy declares. Not yet in a released plugin.
application vars unset APP_REF NAMERead preview of what clearing leaves: the declared default, or no value. Add --yes to apply. Not yet in a released plugin.
application run APP_REFRead the dry run of one more occurrence; add --reason TEXT --yes to authorize it. A settled once Application only. It authorizes exactly one more occurrence against the Application's current published revision and does not promise a launch. Available in 0.14.0 and later.

Pause and retirement do not force-stop existing Acurast jobs.

Releasing a hold is not the same as resuming a paused Application. A hold stops one job's next generation after proof-standard signed failure evidence; a bootstrap-stage hold occurs before workload code starts. A release lets that job launch again under the policy version you already published. Asking twice is one release, not two. See Diagnose and retry.

Release-gated v1: read Capabilities and limits before you rely on application run. Without --yes the server answers with a dry run that names the settled generation the new occurrence would follow, how many jobs it would create and over what window, the reserve that would be opened, and the Service Credit available to your organization. --yes authorizes the run, --reason TEXT is recorded on the request, and --json returns the server's body unchanged. Authorizing is not a recovery retry and not a policy change: the executor's admission checks still decide whether the occurrence launches. Asking twice is one authorization, not two — a run already authorized and unspent answers noop: true, exits zero, and queues nothing further. A refusal exits 1 and carries a refusal.code: application_run_not_admitted (resume the Application first; one that is retired or deleted is never re-runnable), application_run_not_supported (only a once policy can run again), and application_run_not_terminal (wait until the current occurrence settles). Key automation on refusal.code rather than on the message text: the CLI passes through any code it does not recognize, and the set of codes is not guaranteed to be append-only.

Runtime SSH​

CommandBehavior
ssh APPOpen a shell in one of your running jobs.
ssh APP --print-command --jsonResolve and verify the connection without opening a session or consuming an access ticket.
runtime-ssh operator-key add --name NAME --identity FILERegister the public half of an ssh-ed25519 key in your organization's operator-key registry under a name. Only the public key is sent. --public-key-file FILE (or - for stdin) registers a public-key file instead.
runtime-ssh operator-key list --jsonList the organization's registered operator keys with their fingerprints.
runtime-ssh operator-key remove KEY_IDRemove a key from the registry and withdraw its access in one step. New connection requests and tickets for the key are refused at once and its unused tickets are revoked; a session already open drains. The response carries the withdrawal, the revokedTicketCount, and a note saying so.
runtime-ssh withdrawn-key add --fingerprint SHA256:... --reason TEXTWithdraw one key's access by fingerprint, with nothing republished. Use it for a key that has no registry row, such as a key listed only in a Manifest V4 policy. --identity FILE names the key by its private-key path instead; only the derived public half is used. --reason is recorded on the withdrawal and in the activity feed. Repeating a withdrawal is safe: it reports newlyWithdrawn: false and changes nothing.
runtime-ssh withdrawn-key list --jsonList the fingerprints whose access is withdrawn, each with its withdrawal ID, source key, reason, and time.
runtime-ssh withdrawn-key remove WITHDRAWAL_IDLift a withdrawal so the key can be authorized again. It does not re-register the key or add it to any manifest.
runtime-ssh attachment list [--include-terminal] [--json]List the organization's Runtime SSH attachments, newest first: id, readiness, provider, application, job, and the reason when one is not usable. --include-terminal includes attachments that have already stopped.
runtime-ssh attachment revoke ATTACHMENT_IDCut access to one attachment on purpose, without ending the job. No new connection request, ticket or relay registration is granted for it and its unused tickets are revoked; the response carries revokedTicketCount, newlyRevoked, and a note. A session already open drains. Repeating a revocation is safe: it reports newlyRevoked: false and changes nothing. Compare with withdrawn-key add, which denies one person across every attachment rather than ending one job's access for everyone.

--identity names the private key file; it is read locally and never sent.

Named keys and automatic selection (next CLI release)​

These additions are prepared for the next CLI release and are not included in the published version described above. Until that release, use --identity FILE.

Managed ssh APP will match the control plane's attachment-authorized SHA256 fingerprints to Ed25519 private-key files directly in ~/.ssh. ssh APP --key NAME will select the exact operator-key name registered in the effective organization with runtime-ssh operator-key add --name NAME. The named key must also be authorized by the selected attachment. --identity FILE will select an explicit path, or supply a named key stored outside ~/.ssh when combined with --key NAME.

Discovery uses the actual private file's public key, including the public envelope of passphrase-protected OpenSSH keys. OpenSSH asks for the passphrase when connecting. A .pub file alone is insufficient. SSH config aliases, subdirectories, and agent-only keys are not searched. Encrypted keys in other formats should be converted to OpenSSH format first. Multiple distinct matches require --key or --identity; copies of one key use the first sorted path.

--print-command --json will include selectedIdentity (the local path), selectedIdentityFingerprint, and selectedKeyName when --key was used. Discovery failures happen before a ticket is issued:

ErrorAction
RUNTIME_SSH_IDENTITY_MISSINGRestore a private key matching a listed fingerprint, or provide its path with --identity FILE.
RUNTIME_SSH_IDENTITY_AMBIGUOUSSelect one match with --key NAME or --identity FILE.
RUNTIME_SSH_KEY_NOT_FOUNDCheck runtime-ssh operator-key list in the effective organization.
RUNTIME_SSH_IDENTITY_NOT_AUTHORIZEDSelect a key authorized by this attachment. A newly registered key is included in new attachments.

--key applies to managed Runtime SSH. Tailscale SSH uses the Tailscale identity.

Target and host verification​

--deployment and --job select an exact target when an Application has more than one running job. --accept-host-key trusts a job's key on first use without prompting, for automation; a mismatch on a job you already trusted is always refused rather than re-prompted.

The first connection to a job prints its host key for confirmation and pins it. Each connection consumes a one-time ticket, so a replayed ticket is rejected; reconnecting issues a new one.

Every grant, session open, and session close is recorded in the Application activity feed with the duration and bytes transferred. See Open a shell in a running job. For the V5 operator-key snapshot and revocation boundary, see Use retained V5 Managed Runtime SSH.

Registering a key does not grant access on its own. On a Manifest V4 Application, who may connect is exactly the ingress.ssh.provider.authorizedKeys list in the published manifest, and the registry is a named inventory beside it. On a retained V5 Application the registry is snapshotted into each attachment when the attachment is created, so a registered key reaches the next job, never a job already running.

Removing a key withdraws its access. The moment operator-key remove or withdrawn-key add returns, no new connection request or ticket is granted for that fingerprint and its unused tickets are revoked, on every Application in the organization, with nothing republished. A session that is already open is not cut: it drains, ending when the operator disconnects, when the job ends, or at the relay's two-hour maximum session duration, whichever comes first, and a connection that stops answering the relay's heartbeat is closed after 60 seconds. Every withdrawal and reinstatement is recorded in the activity feed with the number of tickets it revoked. Use withdrawn-key add for a key that has no registry row; for a registered key, operator-key remove withdraws it as part of removing it. withdrawn-key remove lifts a withdrawal but does not re-register the key. Keys are ssh-ed25519 only, names are unique within an organization, and the registry holds at most 50 keys. All six commands take an optional ORGANIZATION_ID argument and honour --organization and LISKOV_ORGANIZATION like every organization-scoped command.

Common flags and automation​

  • --json emits machine-readable output and never token material.
  • --help shows generated help for the installed version.
  • --config PATH selects a session file.
  • --organization SELECTOR selects an exact ID or slug for one scoped command; LISKOV_ORGANIZATION is its lower-precedence environment input.
  • Mutations either preview/read by default or require an explicit --yes.

In automation, parse stable IDs, codes, booleans, and timestamps from --json; do not scrape human labels. Stop on a nonzero exit. Never repeat a mutation until you have read the resulting state.

The installed plugin also contains platform, compatibility, and recovery commands. Their presence is not a supported customer contract; they are intentionally omitted here.