Zum Hauptinhalt springen
Markdown anzeigen

Verification Checkpoints

"It compiles" and "it works" are different claims. This page splits verification into four checkpoints, each with its own expected outcome. A pass at one checkpoint says nothing about the next. Record which ones you actually ran.

CheckpointNeedsProvesDoes not prove
1. Local inspectionYour filesWell-formed XML, names checked against the reference, consistent manifestThat the native compiler accepts the code
2. Remote compilationLinked app, network, developer permissionThe instance's compiler accepts the checked filesAny runtime behavior
3. DeploymentSame, plus permission to change the instanceThe instance holds the reviewed change setThat the code works in its context
4. Runtime verificationA sandbox and the real entry pointObserved behavior for the inputs you triedOther inputs and production conditions

Checkpoint 1: local inspection​

Nothing leaves your machine at this checkpoint.

XML well-formedness. This check is partial. It finds broken XML and nothing else.

Bash
xmllint --noout --nonet resources/Greeting.ixml

Expected outcome: exit status 0. xmllint also prints Namespace prefix ... is not defined for commands such as rest:server, because iXML prefixes are not declared XML namespaces. These messages are expected. A parser error such as an unescaped < in an attribute is a real failure.

Failure caseResult
Raw < in an attributexmllint fails. Escape it as &lt;
<if condition="...">xmllint passes. The native parser rejects it, as logged on 6 February 2026. This is why the reference check below is required
Invented command such as array:countxmllint passes. The native parser rejects it, as logged on 6 February 2026

Reference lookup. Look up every changed command in ref/ixmldoc.xml, including attributes, children, and result bindings. Check database identifiers in ref/dbref.json and weblet views in ref/sdk/views.md. Coding Agents and Validation has the full checklist.

Manifest and asset consistency. For each manifest entry, confirm that:

  • The file exists at <class>/<key>.<extension>, and the extension fits its mimetype.
  • The type is on the SDK's list and uses the SDK's uppercase spelling.
  • Hook services have an entity, and TIMING services have a schedule and interval.
  • Each weblet's view exists in ref/sdk/views.md.
  • Every include target exists in the same manifest, with the right type selector.
  • Every rest:resource binds each global it reads with use as its first child. See Bind globals inside rest:resource.
  • No secret appears in defaultsettings.json or any tracked file.

What zeysdk checks offline. zeysdk --help, zeysdk <command> --help, and zeysdk version work without a link. Local arguments are validated before a remote call, so zeysdk add and zeysdk update reject unknown types and unsafe paths. No SDK command compiles code offline.

Checkpoint 2: remote compilation​

zeysdk compile and zeysdk lint send your source to the linked instance's compiler and report the result. They do not execute the code, but they are not offline. They need a linked app, a valid token, developer permission, and network access. Confirm the instance is the one you intend, and that you may send it this source.

Bash
zeysdk whoami
zeysdk compile services/api.ixml
zeysdk compile --ixml '<output>Hello</output>'
zeysdk compile --zy 'return 1;'
zeysdk lint
zeysdk lint --all

compile takes a path or one inline source. --zymba is the long form of --zy. lint compiles the eligible scripts the app knows about. By default it selects only locally present scripts that differ from the last synchronized state. --all selects every locally present script, skipping the server comparison, but it still sends source.

Expected outcome: compile reports success, and lint prints OK for each file you meant to check, with a summary count. Record the file list. On failure both commands print the compiler message and exit nonzero.

Failure caseMeaning
Lint prints No modified iXML or Zymba files to lint. or No iXML or Zymba files found.Not a pass. Zero files were checked, and the exit status is still 0
A script is missing from the lint listIt is not registered in the manifest. Register it, or compile it by path
requires the zeysdk.sync.json file or missing id/urlThe app is not linked. Run zeysdk link
401 or Lacking developer permissionFix the token or the user's permission. This is not a code result

What compile cannot prove. It checks the code you sent, on that instance's compiler. It does not show that database identifiers exist, that a handler's auth check cannot be forged, that an include target is deployed, that a settings key is present, that inputs are complete, that authorization is correct, or that the page renders. Runtime errors in dynamic values appear only at checkpoint 4.

Checkpoint 3: deployment​

push changes the instance. It does more than upload: a whole-project push makes the server match your working copy.

Bash
zeysdk whoami
zeysdk compare
zeysdk snapshot create "Before push"
zeysdk push --dry-run
zeysdk push

Expected outcome: the dry run names the application, instance, and URL, and lists every upload and every server deletion. You can explain each line. The real push then applies that plan, and a following zeysdk compare shows no unexpected drift.

  • Scope. zeysdk push services/api.ixml plans only the named paths. Without paths the plan covers the whole project, including deletions.
  • Deletions. A service, weblet, resource, or asset that exists on the server but not locally is deleted, even if this checkout never synchronized it.
  • --keep-remote protects remote-only assets that have no sync baseline in this checkout. It does not protect every missing local asset. If this checkout synchronized an asset and you then removed it locally, a push still deletes it from the server.
  • --force skips the confirmation prompt. It does not grant authorization, and it does not make the plan safer. Use it only after reviewing the same change set.
  • Dry run limits. A dry run reads the server and may make read-only requests. The server does not lock, so a change made after the preview is not part of what you reviewed.
  • Snapshots are local ZIP archives of project files. They restore your working copy, not the instance.
warning

Neither a snapshot nor a sync.json backup rolls back the server. Plan recovery before you push to a shared instance.

Failure caseMeaning
The plan deletes something you did not touchAnother developer's work, or a stale checkout. Stop and run zeysdk compare. Consider --keep-remote or a targeted push
The plan targets the wrong instanceStop. Run zeysdk use <instance>
A push fails partwayLocal recovery restores sync state only. Compare before retrying

Checkpoint 4: runtime verification​

Test through the real entry point, on a sandbox, with bounded inputs. See Execution Contexts for why zeysdk run does not substitute for these.

ContextHow to testExpected outcomeFailure cases to try
WebletOpen the target view in a signed-in browser. Inspect the frame request in developer toolsFrame status 200 and the expected contentSigned-out user gets 401. User without access to a restricted app gets 403. Empty and hostile $REQUEST values stay safe
REMOTECALLSend HTTP requests with curlValid access token gets 200 and the expected bodyNo token, an invalid token, an SDK token, and no token with a forged ?AUTH[user]=1 must all be rejected by your handler. A real token with forged arguments must keep its real identity. A 200 on any rejected case is a security failure
TIMINGLet the schedule fire on a sandbox, then inspect the data and logOne run, with expected effectsA rerun does not repeat completed work. A failed run is logged and the next run recovers
Entity hookCreate, change, or delete a real record through the UI or APIThe expected change, and only for the intended recordsA thrown error aborts the save. Non-matching records are untouched

The three HTTP checks every protected service needs:

Bash
# Expected: 200
curl -i -H "Authorization: Bearer $ZEYOS_ACCESS_TOKEN" \
"https://cloud.zeyos.com/<instance>/remotecall/example.minimal.api/greeting/Ada"

# Expected: 401 from your handler
curl -i \
"https://cloud.zeyos.com/<instance>/remotecall/example.minimal.api/greeting/Ada"

# Expected: 401. A 200 means a request can forge AUTH.
curl -i -g \
"https://cloud.zeyos.com/<instance>/remotecall/example.minimal.api/greeting/Ada?AUTH[user]=1"

-g stops curl from treating the brackets as a pattern. For a POST route, send the same field in the form body.

Timeouts and uncertain completion​

SDK requests time out after 30 seconds by default. Set ZEYSDK_REQUEST_TIMEOUT_MS to a positive integer to change this. The limit applies to the client's wait.

A disconnected client does not prove the server stopped. The script may still be running, or may already have finished. The SDK's request layer does not automatically resend a run, compile, or push request, and retries only reads. zeysdk watch is the exception: it keeps a failed batch and pushes it again with backoff, so stop it before you investigate. Outside watch, any repeat comes from you.

Before you retry after a timeout:

  1. Treat the outcome as unknown, not failed.
  2. Check the effects: records, sent mail, external calls, and the platform log.
  3. Retry only what did not happen, and only if the operation is safe to repeat.

For work that may take longer, use a TIMING service with a resumable, time-bounded batch instead of raising the timeout.

Record what you ran​

Keep the date, revision, instance, checked file list, and result for each checkpoint. Mark any checkpoint you skipped as not performed. Never describe compiled code as runtime-validated.