Verify what your agent actually changed.
Your application still calls the provider. Conseqa records the intended change before dispatch, then independently reads the system of record. The public packages and installation bundle require no access to the private source repository.
Start with one consequential action
Use Node.js 22.13 or newer, a TypeScript/JavaScript application, and Docker Compose for the published Linux amd64/arm64 runner. Choose an external state you can read independently: a refund, resource, shipment, inventory record, or provisioned account.
To see the idea first, open the public PostgreSQL demo, or sign in and select Run live verification to save the result in a dedicated Live demo environment. It writes synthetic store credit to a real demo database; it does not call an LLM, move money, or contact a customer system.
1. Install without a private checkout
Download and review install.mjs. It fetches only the curated public bundle, creates a new folder, and generates separate local keys. It never starts a service or overwrites an existing installation.
node install.mjs --directory ./conseqa-local
cd conseqa-local
npm install --save-dev @conseqa/cli@0.1.4
node node_modules/@conseqa/cli/dist/index.js init
node node_modules/@conseqa/cli/dist/index.js contracts build
node node_modules/@conseqa/cli/dist/index.js contracts testThe bundled README, Compose file, and blank configuration template are public. Keep the generated .env private. On Windows, review the new folder’s access permissions before adding real credentials.
2. Define the outcome in code
The CLI creates conseqa.contracts.json, client and runner TypeScript files, JSON schemas, and an offline fixture. The starter contract is acme.resource.ready. Its verifier deliberately returns Unknown until you implement a source-of-record probe; passing the example regression does not mean a real resource was verified.
The client derives a correlation key before execution, binds a returned resource ID, and classifies exceptions. The runner discovers an exact resource when supported, reads its state, and produces checks. Keep callbacks and read-only credentials local. The hosted registry accepts only the manifest and schemas, not executable bundles.
Customize the schemas, schedule, evidence allowlist and callbacks. Build after changes. A contract name/version cannot be republished with different bytes; bump its version. Each action pins the SHA-256 build hash, and required protection rejects an application/runner mismatch.
Verify the published runner before running it
The public Compose bundle pins the immutable 0.1.4 image, not a mutable latest tag:
ghcr.io/devrajsinh-jhala/conseqa-runner@sha256:37fe678130cbb12140e0388a7afc140f07fba072a0e8d5b1d77d4ee94e7350aaDownload container-release.mjs and runner-signing-key.pub. Independently pin the public key’s SPKI DER SHA-256 fingerprint:
68e5412daf00ef00c43c0e93b1e342add20e2e4239c6833bdc3d8a72fb79441dA fingerprint copied from the same untrusted download is not independent publisher authentication. The signed release descriptor binds the version, source commit, exact image digest and platforms. Use ORAS 1.3.4 or newer to retrieve the descriptor, and verify it with the pinned key before starting the image.
oras pull ghcr.io/devrajsinh-jhala/conseqa-runner:release-0.1.4 --output ./release-proof --keep-old-files
node container-release.mjs verify-public --envelope ./release-proof/signed-release.json --public-key ./runner-signing-key.pub --image ghcr.io/devrajsinh-jhala/conseqa-runner --version 0.1.4 --digest sha256:37fe678130cbb12140e0388a7afc140f07fba072a0e8d5b1d77d4ee94e7350aaStop if verification fails or either required platform is missing. This is a publisher-key signature, not a claim of a GitHub/SLSA attestation.
3. Start the private persistent runner
docker compose up -d conseqa
node --env-file=.env node_modules/@conseqa/cli/dist/index.js contracts install --runner http://127.0.0.1:4319
node --env-file=.env node_modules/@conseqa/cli/dist/index.js doctorThe host port is loopback-only. The admin token installs contracts; the different sidecar token authorizes application lifecycle traffic. Never put either token in browser code or a public URL. Persist the SQLite, contract and spool volumes, and run one runner per environment in v1.
Inject the credential names your trusted verifier needs into the runner’s private environment. PostgreSQL verifiers use parameterized SELECT queries and should have a least-privilege read-only role. HTTP verifiers allow GET only with explicit host/network restrictions. The runner never repeats the provider action.
4. Protect the application’s existing call
npm install @conseqa/sdk@0.1.4 @conseqa/contracts@0.1.4In your application, load the exact built contract package. This example assumes you have implemented createResource and the matching read-only verifier; the unmodified starter is intentionally incomplete.
import { Conseqa, loadClientContractPackage } from "@conseqa/sdk";
const contractRegistry = await loadClientContractPackage({ directory: "dist/conseqa" });
const conseqa = new Conseqa({
contractRegistry,
runnerUrl: "http://127.0.0.1:4319",
sidecarToken: process.env.CONSEQA_SIDECAR_TOKEN,
});
const contract = contractRegistry.get("acme.resource.ready", 1);
try {
const result = await conseqa.protect(contract, {
actionKey: "stable-business-operation-id",
protectionMode: "required",
intent: { name: "example" },
execute: ({ providerCorrelationKey }) =>
createResource({ name: "example", correlationKey: providerCorrelationKey }),
});
// Use the original provider result. Verification happens independently.
} finally {
await conseqa.close();
}Required actions do not execute without durable intent registration and the validated contract hash. The original provider result or exception remains the caller’s result. Without a configured shared SDK spool, runner outages fail closed. Best-effort protection may proceed when persistence fails, but must appear as an unprotected coverage gap.
A durable SDK spool requires the application and runner to share the same encrypted volume, key/key ID and service UID/GID. It is allowed only after that runner environment has validated the hash. Do not substitute a separate host directory for the shared volume.
5. Keep the trace and consequence connected
Use your application’s OpenTelemetry instrumentation for agent/model/tool spans. Configure its OTLP exporter for the local Collector at http://127.0.0.1:4318, or http://otel-collector:4318 inside the same Compose network. Run protected actions inside the relevant active tool span.
The official Collector filters content fields and has a persistent file-backed sending queue. Async verifier spans link to the originating action span; they do not modify an already-ended trace. Prompt, response and tool-body capture is off by default. Explicitly allowlist and redact custom metadata rather than assuming every attribute is safe.
6. Connect your hosted dashboard
Create a workspace, then create an environment key in Settings as an owner or administrator. The key is shown once; store it privately. Development is for your real integration; Sample is labelled representative data, and Live demo is reserved for the scripted workspace demonstration.
Set these two values in the private installation .env, leaving the local keys unchanged:
CONSEQA_INGEST_ENDPOINT=https://www.conseqa.dev
CONSEQA_ENVIRONMENT_KEY=<your-environment-key>docker compose --profile cloud up -d
node --env-file=.env node_modules/@conseqa/cli/dist/index.js contracts publish --cloud https://www.conseqa.devInspect Runners for heartbeats and loaded hashes; Contracts for runtime deployment drift; Actions for the intent, dispatch, binding/discovery and evidence; Coverage for observed eligible-action protection; Issues for grouped exceptions and triage. A configured webhook is not proof of delivery. Signed webhook delivery and optional sender-enabled email are separate.
7. Test failures offline
Contract Regression does not execute the agent, model, production action, or installed verifier callbacks. The CLI evaluates data-only predicate assertions and recorded lifecycle transitions. Manually author exact predicates when you own their original meaning; do not guess operators from dashboard display text.
node node_modules/@conseqa/cli/dist/index.js contracts test
node node_modules/@conseqa/cli/dist/index.js contracts test acme.resource.ready --json regression-results.json --junit regression-results.xmlA supported saved action offers a recorded lifecycle export. This uses its real retained redacted registration, complete immutable event sequence, pinned hash and recorded verdict. It does not reconstruct removed fields or re-evaluate the original provider predicates. Missing, incomplete, oversized or unsafe retained data disables export with a reason.
Use your original matching built contract package. After building, save the downloaded fixture as dist/conseqa/regressions.json and run the CLI test. Keep the build hash unchanged; rebuilding can overwrite fixtures. The current CLI accepts one fixture file at that path—review merging cases before replacing an existing one.
Only if you choose to publish result metadata, run:
node --env-file=.env node_modules/@conseqa/cli/dist/index.js contracts test --upload https://www.conseqa.devThe upload contains test names, hashes, verdicts and bounded diagnostics, not fixture bodies or executable code. Review those operator-authored names/diagnostics for identifiers before uploading.
Before protecting customer actions
Validate required-mode fail-closed behaviour, exact discovery, multiple-candidate Unknown, provider auth/schema errors, restart recovery, secret redaction and your source-of-record permissions. A verified outcome is an evaluation of observed state at recorded times, not bank-settlement proof or a guarantee against a later reversal.
Keep port 4319 private, persist the runner and Collector volumes, and back up the full stopped SQLite/spool/contracts state coherently with matching keys stored separately. Never run docker compose down -v against production volumes. High availability, SSO, automatic retries/remediation, and model replay are not provided by v1.
The hosted service is early access. Account verification/reset screens are implemented, but real email delivery and off-machine recovery need operator acceptance before production personal data. Optional issue-alert email stays disabled until its sender and actual delivery are verified. You can use the Vercel address for the technical trial.
Need help with your first contract? Contact Devraj Jhala. Send a description, never a password, token, connection string or raw customer record.