zigttp is the developer CLI. zigts is installed for tools that want the
analyzer directly; analyzer commands exposed by zigts are also reachable as
zigttp <command>.
Run command-specific help for exact flags:
zigttp --help
zigttp help --all
zigttp <command> --helpThe default help shows the day-to-day workflow:
zigttp init <name> [--template basic|api|htmx]
zigttp dev [handler.ts]
zigttp test [tests.jsonl]
zigttp expert
zigttp deployCore commands auto-detect zigttp.json from the current directory or a parent.
| Command | Purpose |
|---|---|
init |
Create a project scaffold. |
dev |
Run locally, watch files, and prove on save. |
test |
Run declarative handler tests. |
expert |
Start the compiler-in-the-loop coding agent. |
deploy |
Build, prove, attest, and emit a local binary. |
zigttp serve runs a handler without the proof-aware watch loop:
zigttp serve src/handler.ts -p 3000
zigttp serve -e "function handler(req) { return Response.json({ ok: true }) }"Common dev and serve flags:
| Flag | Purpose |
|---|---|
-p, --port <port> |
Listen port. |
-h, --host <host> |
Listen host. |
-e, --eval <code> |
Inline handler source. |
-m, --memory <size> |
Per-runtime JS memory ceiling. |
--max-body-size <size> |
Request body limit (default 1m); oversize returns 413. |
--max-websocket-connections <count> |
Live WebSocket limit (default 1024; 0 disables upgrades). |
-n, --pool <count> |
Runtime pool size. |
-q, --quiet |
Disable request access logging. |
--watch |
Watch handler files. |
--prove |
Diff contracts before hot-swap when watching. |
--trace <file> |
Record request/response traces. |
--incident-log <file> |
Append runtime soundness incidents as JSONL. Off by default. |
--replay <file> |
Replay recorded traces. |
--test <file> |
Run JSONL handler tests. |
--sqlite <file> |
SQLite database for zigttp:sql. |
--durable <dir> |
Durable workflow oplog directory. |
--system <file> |
Handler bundle manifest: the zigttp:service HTTP registry and the zigttp:workflow in-process sub-handler registry. An optional entry field names the bundle's single external HTTP entry point, validated by zigttp link. Workflow startup fails if a local handler path is unreadable. |
--workflow-queue |
Persist durable workflow call, follow, and fanout child dispatch through the workflow queue. Requires --durable <dir> and --system <file>. |
--actor-queue |
Enable process-local in-memory mailboxes for zigttp:queue. |
--outbound-http / --outbound-host <host> |
Enable outbound HTTP. The host allowlist matches on host only, not port. |
--outbound-timeout-ms <ms> |
Outbound connect timeout (default 10000). Implies --outbound-http. |
--outbound-max-response <size> |
Outbound response body cap (default 1m). Implies --outbound-http. |
--security-log <file> |
Append security events as JSONL: policy denials, arena audit failures, persistent-string escapes. |
--lifecycle <mode> |
Override the contract-derived runtime lifecycle: ephemeral, bounded, ttl, or reuse. |
--static <dir> |
Serve static files. |
--no-env-check |
Skip startup env validation. |
dev adds --no-prove (watch and reload without contract gating), --quest /
--no-quest (replay or skip the first-run proof tour), and --record-proof,
which captures the session's requests into a replayable proof capsule at
.zigttp/capsules/default/. serve --watch takes --prove and --force-swap
(apply a breaking swap anyway) instead. Both take --studio when the binary was
built with -Dstudio.
Without --lifecycle, the runtime derives the pool's recycling policy from the
proven contract: reuse when the handler is pure, deterministic, and
state-isolated; ttl when it is read-only and state-isolated; bounded
otherwise. bounded recycles a runtime after 64 requests, ttl after 30
seconds, and ephemeral gives each request a fresh runtime. A hot swap
re-derives the policy unless the override is set.
--security-log writes one JSON object per line. A capability denial from a new
gate site is {"event":"policy_denied","ts":...,"service":...,"action":...,"resource":{"kind":...,"id":...},"reason":...};
the per-module kinds (policy_denied_env, policy_denied_cache,
policy_denied_sql, arena_audit_failure, persistent_string_escape) are
{"kind":...,"ts":...,"module":...,"detail":...}. A background thread drains
the event queue and flushes it at shutdown.
Observability: per-request access logging is on by default (method, path,
status, duration, request id; disable with -q), and pool/latency metrics are
logged. There is no scrape-able /metrics endpoint yet; that is planned for a
later release.
zigttp deploy
./.zigttp/deploy/<project-name>
zigttp verify http://127.0.0.1:8080deploy verifies the current project, writes a local binary, appends a
kind=deploy row to .zigttp/proofs.jsonl, and signs an attestation by
default. --no-attest disables signing for that build.
Proof ledger commands:
zigttp proofs
zigttp proofs show HEAD
zigttp proofs diff HEAD~1 HEAD
zigttp proofs export --format md --ref HEAD
zigttp proofs badge
zigttp proofs gate --base origin/main --head HEADzigttp proof replay <capsule> replays a capsule recorded by zigttp dev --record-proof against the current handler: exit 0 reproduced, 1 regression. It
fails closed when the capsule's pinned handler, contract, or policy hash no
longer matches (--allow-version-mismatch overrides). zigttp verify <url>
verifies a live endpoint's attestation. zigttp proofs verify <bundle-dir>
re-hashes a local proof bundle.
zigttp verify --json includes durable workflow receipt fields when a build was
attested with a workflow contract: durableWorkflowProofLevel,
durableWorkflowRetrySafe, durableWorkflowIdempotent, and
durableWorkflowFaultCovered.
Workflow queue dead-letter commands:
zigttp workflow-queue list --durable <dir>
zigttp workflow-queue show --durable <dir> <item-id>
zigttp workflow-queue replay --durable <dir> <item-id>
zigttp workflow-queue discard --durable <dir> <item-id>These commands inspect the persisted queue used by --workflow-queue; they do
not operate on the in-memory actor queue from zigttp:queue.
Durable-run dead-letter commands (a sibling surface: these inspect runs that permanently failed crash recovery, not queued child dispatch):
zigttp durable dead-runs list --durable <dir>
zigttp durable dead-runs show --durable <dir> <id>
zigttp durable dead-runs replay --durable <dir> <id>
zigttp durable dead-runs discard --durable <dir> <id>See Durable Workflows for the quarantine/restart/replay/discard semantics.
These commands are listed by zigttp help --all from the shared zigts
command registry:
zigttp check [handler.ts] [--json] [--contract] [--types]
zigttp prove <old-contract.json> <new-contract.json>
zigttp prove-behavior <before.ts> <after.ts> [--json] [--sql-schema path]
zigttp mock <tests.jsonl> [--port <port>]
zigttp link <system.json>
zigttp rollout <old-system.json> <new-system.json>
zigttp edit-simulate [handler.ts] [--before old.ts]
zigttp review-patch <file> [--before old.ts] [--json]
zigttp gen-tests [handler.ts] [-o output.jsonl]
zigttp canonicalize <file> --json
zigttp normalize <file> [--write] [--check] [--json]
zigttp features [--json]
zigttp modules [--json]
zigttp restrictions [--json] [--by proof|class]
zigttp meta [--json]
zigttp describe-rule [name|code] [--json] [--hash]
zigttp search <keyword> [--json]
zigttp spec-check [--json]
zigttp spec-hash [--json]
zigttp spec-render [--out path] [--check path]
zigttp verify-paths <file>... [--json]
zigttp verify-modules <file>... [--strict] [--json]
zigttp verify-modules --builtins --strict --json
zigttp verify-module-manifest <manifest.json> [--json]
zigttp extension-status --module-manifest <path>... [--json]Use JSON mode for IDEs, CI, and review-bot integrations.
Exit codes for gating: check returns 0 (ok), 1 (errors), or 2 (warnings only, no errors). prove and prove-behavior return 0 (safe), 1 (breaking), or 2 (usage or error). spec-check validates the semantics registry against the IR/bytecode tables and returns 0 (conform), 1 (divergence, with a ZTS75x counterexample), or 2 (error); spec-hash prints the registry hash for CI assertions, the way describe-rule --hash prints the policy hash. spec-render --check <path> returns 0 when the committed readable spec matches the registry, or 1 when it is stale.
Configure a model key, then launch the interactive agent:
zigttp auth claude
zigttp auth openai
zigttp auth status
zigttp auth revoke claude
zigttp expertUseful modes:
zigttp expert --resume
zigttp expert --yes
zigttp expert --no-edit
zigttp expert --model claude-sonnet-4-6
zigttp expert --print "add a GET /health route"
zigttp expert --print "..." --mode json
zigttp expert --mode rpc
zigttp expert --handler src/handler.ts --goal no_secret_leakage| Flag | Purpose |
|---|---|
--resume |
Continue the last session for the current project. |
--yes |
Apply every verified edit without prompting. |
--no-edit |
Let the model read and analyze files but block all writes. |
--model <id> |
Start on a model registered for the configured provider. |
--print <text> |
Non-interactive: send one message, print the response, and exit. |
--mode json |
Emit JSON-encoded turn events to stdout (pairs with --print). |
--mode rpc |
Run in RPC mode for editor integrations. |
--handler <file> |
Override the handler file (default: auto-detected from zigttp.json). |
--goal <property> |
Restrict the session to edits that achieve a named proof property. |
Pi uses claude-sonnet-4-6 for Anthropic and gpt-4o-mini for OpenAI.
Anthropic remains the measured path; OpenAI support ships as an experimental
Responses API backend. If both credentials are configured, Anthropic takes
precedence.
--model <id> accepts an exact ID from the static registry, then checks it
against the provider selected from credentials. A model ID never switches the
provider. /model lists only models for the active provider, marks the current
one, and changes the current session when you select another. Selection also
applies that model's request budget: the Claude entries keep their existing
budgets, while gpt-4o-mini requests at most 8,192 output tokens despite its
16,384-token output capability. RPC clients get the same allowed set through
model.list and the same validation through model.set.
The stored provider file is ~/.zigttp/providers.json with mode 0600.
Environment variables ANTHROPIC_API_KEY and OPENAI_API_KEY override stored
values.
zigttp studioruns the browser proof workbench when built with-Dstudio.zigttp edge --config zigttp.edge.jsonruns the in-process multi-handler edge router when built with-Dedge.zigttp demo --scripted --out proof-demo --export proof-demo/passportcreates an offline Proof Passport demo.
See User Guide for the normal project flow.