dibbla apps checks
List, run, and review an app's application checks from the CLI — with JSON output and exit codes a CI pipeline can gate on without scraping text.
dibbla apps checks drives an app’s application checks — the dibbla-checks.yaml a deployment ships — from the terminal. Every console-visible definition, result and action has a CLI equivalent, and every command has a JSON form.
The alias is always positional and the check id is always a --check flag, matching dibbla apps restart <alias> --service <name>.
These commands ship in every dibbla build, but the capability behind them is
enabled organization by organization. A 404 with APPLICATION_CHECKS_DISABLED
(exit 4) from any of them means your organization is not switched on yet — the
command is correct, the capability is not there. Ask us to enable it.
dibbla apps checks list
Show the checks configured for one app — kind, schedule, classification, enabled state — plus whether the app’s checks runtime is on.
| Flag | Purpose |
|---|---|
<alias> (positional, required) | The app to inspect. |
--json | Print the raw API document (one JSON document). |
An app whose organization has checks enabled but that ships no dibbla-checks.yaml lists as configured: false with zero definitions. That is an answer, not an error — the exit code is 0.
The Runtime: line appears only once the app’s checks have been enabled. Until then it is absent, and --json carries no settings object at all. Do not read the per-definition enabled: true as “this check is running”: that field describes the definition, the runtime switch is app-level and is turned on by enable. Neither field means a check has executed — run is what executes one.
Classification is derived from the definition, never declared. read_only_deterministic is an http_sequence, or a browser_journey that only navigates and asserts. isolated_fixture_mutation is a journey that carries an identity_grant, a secret_ref, or any click/fill step — it can change state, so it acts as an isolated fixture. semantic is the judged kind. You cannot label a mutating journey read-only.
$dibbla apps checks list myapp 🔍 application checks for myapp Runtime: enabled (settings version 1) Revision: sha256:9f21a… 2 check(s): ID KIND SCHEDULE CLASSIFICATION ENABLED NAME ---------------------- -------------- -------- ---------------------- ------ ---- home-page http_sequence nightly read_only_deterministic yes Home page is usable api-health http_sequence nightly read_only_deterministic yes The status API answers
$dibbla apps checks list myapp --json | jq '.definitions[].id' dibbla apps checks run
Trigger one manual execution of all checks, or of one check, and wait for the outcome.
| Flag | Purpose |
|---|---|
<alias> (positional, required) | The app to run checks against. |
--check <id> | Run only this check (default: all). |
--async | --follow | Return once accepted, or poll and stream progress. Mutually exclusive. |
-q, --quiet | --json | Script-friendly or machine output. Mutually exclusive. |
By default the command polls the execution until it is terminal and exits with the product outcome:
| Exit code | Meaning |
|---|---|
0 | pass |
8 | fail |
9 | error |
10 | indeterminate |
12 | canceled |
13 | skipped_concurrent — another run already holds the app’s lease |
run exits 8 when a check finds a problem — that is the check doing its
job. Gate CI on the code: dibbla apps checks run myapp --check smoke fails
the pipeline only when the app actually fails the assertion, not when the
transport hiccups. Transport failures use the CLI-wide ladder: 3 auth,
4 not found, 5 bad request, 6 conflict, 7 timeout, 1 other.
--async returns as soon as the execution is accepted (exit 0) and prints the execution id — with --json it prints the parent execution object, which you poll.
--follow --json is documented NDJSON on stdout: one execution_created line, one execution_status line per status change, and exactly one terminal summary line carrying outcome and the implied exit_code:
{"type":"execution_created","status":"running","execution_id":"acx_…","execution":{…}}
{"type":"execution_status","status":"fail","execution_id":"acx_…","execution":{…}}
{"type":"summary","outcome":"fail","exit_code":8,"execution_id":"acx_…","execution":{…}}
Sync --json prints exactly one JSON document with outcome and exit_code next to the final execution, so a caller never parses prose.
$dibbla apps checks run myapp --check home-page ⏳ running 1 check(s) — execution acx_8f31 (running) ✅ pass — execution acx_8f31 (1 check(s)) took: 9s history: dibbla apps checks history myapp
# Accept the run, print the execution id, keep going $dibbla apps checks run myapp --async --quiet acx_8f31
# Exit 8 = the check failed; exit 0 = pass $dibbla apps checks run myapp --check smoke --json | jq -e '.exit_code == 0'
dibbla apps checks history
Show past runs with their typed result documents — outcome, stable code, bounded summary — newest first.
| Flag | Purpose |
|---|---|
<alias> (positional, required) | The app to inspect. |
--check <id> | History for one check (default: every configured check, merged). |
--since <duration> | Only runs that started within this window, e.g. 24h. Applied client-side. |
--limit <N> | Max runs to show; also sent as the server-side page size. |
--json | Print one JSON document. |
With --check, --json prints the server’s page document verbatim (runs plus the opaque next_cursor). Without --check there is no app-wide history endpoint, so the CLI fetches one page per check and merges them into a single runs array under its own envelope — schema_version, deployment_alias, runs. The envelope differs because N pages cannot share one next_cursor; the run documents inside it are the server’s own, key for key and in the server’s order.
That last sentence describes the CLI from the first release after v1.2.65. On v1.2.65 and earlier — which is what dibbla update installs today — the merged path re-serialises each run through a smaller internal struct, so it silently drops execution_id, transport_status, assertion_status, check_fingerprint, evidence_refs and evidence_gaps, and invents values the server never sent, including finished_at: 0001-01-01 and duration_ms: 0 for a run that has not finished. Run dibbla --version to see which you have. On the older behaviour, pass --check and iterate the checks yourself when you need everything the server knows about a run.
$dibbla apps checks history myapp --since 24h 🕓 check run history for myapp STARTED CHECK OUTCOME CODE SUMMARY 2026-08-25 14:02 home-page pass 200 OK, citation present 2026-08-25 11:47 home-page fail ASSERTION_FAILED Expected citations, received none
$dibbla apps checks history myapp --check home-page --json | jq '.runs[0]' dibbla apps checks enable / disable
Start or stop the app’s checks runtime. Disabling preserves definitions and history. Both require the owner or admin role, and enabling requires configured checks.
| Flag | Purpose |
|---|---|
<alias> (positional, required) | The app to toggle. |
--check <id> | Rejected today — enablement is app-wide until the API grows per-check enablement. |
-y, --yes | Skip the confirmation prompt. |
$dibbla apps checks enable myapp --yes ✓ application checks enabled for myapp (settings version 3)
$dibbla apps checks disable myapp --yes ✓ application checks disabled for myapp (settings version 4)
Machine contract
- One document, one answer.
listandhistory --checkprint the server document verbatim;historywithout--checkprints one merged document; syncrun --jsonprints one terminal document. Onlyrun --follow --jsonis a stream (NDJSON, one terminal line). - A run document is a run document, whichever way you asked for it.
history --check --jsonreturns the server’s page verbatim;history --jsonreturns the CLI’s own envelope around the same server run documents. The envelope differs by design, the runs do not differ at all — so a consumer can read a run the same way in both. (Before the first release afterv1.2.65the merged form was lossy; see the note above.) - Stable
code, prosedetail. Errors print the server’s machine code (APPLICATION_CHECKS_DISABLED,ASSERTION_FAILED) alongside the human message. - Every JSON terminal object carries the outcome and the implied exit code.
- Human output never requires colour. Icons have ASCII fallbacks and status is always conveyed as text too.
Checking the file before you deploy
dibbla manifest validate validates a dibbla-checks.yaml sitting at the same
root, so a mistake surfaces in a second instead of at the end of a deploy. It
needs no network and no login.
Run dibbla --version. On v1.2.66 and earlier the command validates only
dibbla.yaml and ignores the checks file entirely — no error, no mention.
That looks like a green answer about something that was never examined, so on an
older build the only real check is a deploy.
The checks file is validated even when there is no dibbla.yaml — it is
independent input, exactly as deploy-api treats it, so an app on the plain
single-Dockerfile path gets the same scrutiny.
✓ dibbla.yaml is valid
1 services: app (public)
✓ dibbla-checks.yaml is valid against the schema copied from app-hosting-service d7793a7
2 checks: home-page, status-board-renders
the server is authoritative. Not verified locally:
- route names are matched against the deployment's real routes only on the server
- secret_ref names are resolved against the app's secrets only on the server
- referenced files (a semantic check's judge rubric) are read and size-bounded only on the server
- the org's Application Checks capability and the app's own enable switch are server state
A failure names the check and carries the same code the server would give:
✗ dibbla-checks.yaml is invalid
check "home-page": description is required — … (APPLICATION_CHECKS_DESCRIPTION_REQUIRED)
the deploy would refuse this file before the build
Exit 1 when the checks file is invalid, even if dibbla.yaml is fine. No
checks file at all is not a finding — that exits 0.
A green answer is about the shape, not the outcome
This is the part worth reading twice. Everything in findings will stop a
deploy. An empty findings does not mean the deploy will pass. The implication
runs one way only, which is why the command prints what it could not decide
instead of stopping at a tick.
The distinction the output is built around: findings are statements about
your file; unverified is a statement about the tool. Route names, secret_ref
resolution, referenced rubric files and the two enablement switches are server
state, and a local copy of the schema cannot see any of them. The command
deliberately never calls a file invalid on a rule it could not check.
Two loader rules are mirrored locally, with the server’s own codes — a
click/fill journey without identity_grant (APPLICATION_CHECKS_INVALID)
and a literal supplied to a credential-shaped control
(APPLICATION_CHECKS_INLINE_SECRET). Everything else semantic belongs to the
server.
--json carries all of it under a checks key: present, path, valid,
check_ids, findings[{code, detail}], unverified[] and
schema_source_commit — the commit the bundled schema was copied from, so a
green answer says which version of the rules it was green against.
Error codes
Every failure carries a stable machine code beside the human message, so a script matches on the code and never on prose. Two families, and the distinction matters when you are deciding whether the app is broken or the instrument is:
Refusals — the file or the request was rejected. These come from the API, and the first two happen at deploy time, before the build, so a bad checks file stops the deploy rather than shipping a broken check.
| Code | What it means |
|---|---|
APPLICATION_CHECKS_DESCRIPTION_REQUIRED | A check has no description. The message names the check. |
APPLICATION_CHECKS_INVALID | The file does not match the schema — an unknown key, a missing required one, or a rule like a click/fill journey without identity_grant. |
APPLICATION_CHECKS_INLINE_SECRET | A fill supplies a literal to a control whose id looks like a credential. Use secret_ref. |
APPLICATION_CHECKS_UNSAFE_REFERENCE | A referenced file (a semantic check’s rubric) escapes the app root. |
APPLICATION_CHECKS_VERSION_UNSUPPORTED | version: is not 1. |
APPLICATION_CHECKS_DISABLED | The organization’s checks capability is off. A 404, CLI exit 4. |
APPLICATION_CHECK_NOT_FOUND | No check with that id in the promoted snapshot. |
APPLICATION_CHECKS_VERSION_CONFLICT | Someone changed the settings between your read and your write. |
APPLICATION_CHECKS_REVISION_STALE | The definitions moved on since the request was formed — deploy again. |
APPLICATION_CHECKS_UNAVAILABLE | The checks runtime could not take the request. Nothing is wrong with your file. |
Results — a check ran and reached a verdict. These appear on a run in
history, never as a command failure.
| Code | What it means |
|---|---|
ASSERTION_FAILED | The app answered and the assertion did not hold. This is the check working. |
ROUTE_UNRESOLVED | The logical route does not resolve for this deployment — usually a name that is not in the manifest. |
STEP_METHOD_UNSUPPORTED | A step used a method outside GET/HEAD/OPTIONS. |
CHECK_NOT_IN_BUNDLE | The definition is not in the promoted snapshot. Deploy first. |
PROBE_EXECUTOR_FAILED | The runner itself failed. That is an error, not a failing app — and it never counts toward the failure threshold. |
CHECK_KIND_UNSUPPORTED | The check’s kind is not one the runtime executes — today that is anything other than http_sequence. The outcome is indeterminate (exit 10), so it is neither a pass nor a failure: you have no answer about your app. See the kind that runs today. |
See also
dibbla deploy & apps—dibbla apps get <alias>shows the deployment record the checks run against.- Reading logs — runtime logs for the same app when a check fails.