DriftLedger
CLI Guide
Agent CLI quickstart

Install once. Let agents run DriftLedger.

install.sh
curl -fsSL https://driftledger.fatclaw.com/install.sh | bash

One command installs the public package, then prints the next auth and agent setup commands.

Install once with bash, then let Codex, Claude Code, OpenClaw, CI jobs, and local scripts upload ledgers, create checks, run rules, inspect incidents, and verify alert delivery through JSON-first commands.

Node.js 20+JSON outputCodex readyEmail / Webhook
4agent presets
35+API-backed commands
2Current upload formats
01

Install and connect

Use the hosted install when the npm package is live. During local validation, install from the local checkout and point the CLI at your backend.

Hosted install

Use once the public npm package and install script are published.

curl -fsSL https://driftledger.fatclaw.com/install.sh | bash
dl config set --api-url https://driftledger.fatclaw.com
dl auth login --email you@example.com --password "<password>"

Local checkout

Use the sibling dl-agent checkout while validating the CLI against local frontend/backend work.

npm install -g ../dl-agent/packages/cli
dl config set --api-url http://localhost:8088
dl doctor

Sandboxed agent

Use environment variables when the agent cannot write ~/.driftledger/config.json.

export DRIFTLEDGER_API_URL="https://driftledger.fatclaw.com"
export DRIFTLEDGER_TOKEN="<jwt>"
export DRIFTLEDGER_WORKSPACE_ID="Default"
01.1

Use flow after install

Agents should follow this exact order. If no workspace is specified, dl uses Default. Each step produces JSON or a reviewed body file that the next step can reuse.

01

Verify CLI and backend

Make sure the dl binary, API URL, token, and workspace context are visible before modifying data.

command -v dl >/dev/null || npm install -g @driftledger/cli
dl doctor
dl auth verify
02

Confirm workspace boundary

Default is the implicit workspace for metadata, data, models, rules, RuleForest, runs, incidents, and alerts.

dl workspace list
# Optional override for a non-default workspace:
dl workspace activate --workspace <spId>
03

Generate agent instructions and install skills

Write the project instruction file, then install optional DriftLedger skills into the local agent skill directory.

dl agent init codex --out AGENTS.md
mkdir -p ~/.codex/skills
cp -R skills/driftledger-cli ~/.codex/skills/
cp -R skills/driftledger-incident-review ~/.codex/skills/
04

Choose data path

Upload assembled JSONL directly when joins already exist, or upload raw CSV tables and run assembly first.

dl dataset create-assembled --display-name refund-payment-fund
dl dataset upload-assembled --dataset <datasetId> --file assembled.jsonl
# Or: metadata -> source binding -> raw CSV upload -> assembly
05

Create reconciliation model

Define the table relationships and parent object that rules attach to.

dl check-model create --body-file check-model.json
dl check-model deploy --id <riskModelId>
dl check-model enable --id <riskModelId>
06

Train or add reviewed rules

Mine candidate rules from samples or add a manually reviewed rule payload. Manual ruleType values must come from the algorithm rule type list.

dl infer-task submit --body-file infer-task.json
dl infer-task progress --task <inferTaskId>
dl rule types
dl rule add --body-file rule.json
07

Build RuleForest

Compile workspace rules before execution so runs load the rule tree first.

dl rule-forest build
dl rule-forest status
08

Configure alerts

Create email or webhook channels before production runs and send a test alert.

dl alerts upsert --body-file alert-email-channel.json
dl alerts test --channel <channelId>
09

Run, inspect, and hand off

Submit execution, inspect result indexes and incidents, then verify alert delivery logs.

dl run submit --body-file run.json
dl run run --task <taskId>
dl incidents task --task <taskId>
dl alerts deliveries --task <taskId>
02

Agent presets

Generate a short instruction block for the agent runtime. Secrets stay in environment variables, not in chats or repository docs.

Codex

Writes a project-local AGENTS.md block with the DriftLedger command contract.

dl agent init codex --out AGENTS.md

Claude Code

Writes a CLAUDE.md block for shell-first reconciliation workflows.

dl agent init claude --out CLAUDE.md

OpenClaw

Writes an OPENCLAW.md block for OpenClaw agents and compatible runners.

dl agent init openclaw --out OPENCLAW.md

Generic agent

Prints a portable Markdown contract when the runtime has no named preset yet.

dl agent init generic
03

Command reference

Every command returns JSON. Pass complex payloads through --body-file so agents can create, review, and retry files deterministically.

01

Config, auth, and workspace

Check runtime state, persist API settings, log in, and select the workspace scope used by later commands.

Inspect runtime

Shows API URL, token presence, workspace, and config path.

dl doctor
dl version
dl config get

Configure and authenticate

Login captures the AUTH_TOKEN cookie into local config unless --no-save is used.

dl config set --api-url https://driftledger.fatclaw.com --workspace <spId>
dl auth login --email you@example.com --password "<password>"
dl auth verify
dl auth refresh

Create or activate workspaces

Workspaces isolate metadata, datasets, models, rules, runs, and incidents.

dl workspace list
dl workspace create --name "Demo workspace"
dl workspace get --workspace <spId>
dl workspace activate --workspace <spId>
02

Metadata, sources, and datasets

Define table metadata, bind source columns, upload raw exports, or skip assembly by uploading a joined ledger.

Metadata and source binding

Create a meta table with fields, then bind uploaded source columns to that schema. Field types are optional; use algorithm types only when constraining inference.

dl metadata col-types
dl metadata upsert --workspace <spId> --body-file meta.json
dl metadata tables --workspace <spId>
dl metadata fields --workspace <spId> --table <metaTableId>
dl data-source upsert --workspace <spId> --display-name "Orders export" --type CSV_UPLOAD
dl source-binding upsert --workspace <spId> --body-file binding.json

Raw dataset upload

Use when DriftLedger should preserve source-table identity before assembly or checking.

dl dataset create-raw --workspace <spId> --display-name orders --binding-id <bindingId>
dl dataset upload --workspace <spId> --dataset <datasetId> --file orders.csv
dl dataset list --workspace <spId>
dl dataset detail --workspace <spId> --dataset <datasetId>

Assembly task

Turn raw table datasets into assembled records for training and execution.

dl assembly submit --workspace <spId> --body-file assembly.json
dl assembly run --workspace <spId> --task <assemblyTaskId>

Assembled dataset upload

Use when your agent or data job already produced the joined ledger as JSONL or CSV.

dl dataset create-assembled --workspace <spId> --display-name assembled-ledger
dl dataset upload-assembled --workspace <spId> --dataset <datasetId> --file assembled.jsonl
dl dataset download --workspace <spId> --dataset <datasetId> --artifact <artifactId> --out evidence.jsonl
03

Reconciliation models and rules

Create a business reconciliation model, add human-reviewed rules, then deploy or enable the model for execution.

Reconciliation model lifecycle

A model groups related invariants such as payment-to-access or refund-to-settlement checks.

dl check-model create --workspace <spId> --body-file check-model.json
dl check-model update --workspace <spId> --body-file check-model.json
dl check-model deploy --workspace <spId> --id <riskModelId>
dl check-model enable --workspace <spId> --id <riskModelId>
dl check-model list --workspace <spId> --code <modelCode>

Rule lifecycle

Rules can be added from AI suggestions, manual review, or migration scripts. Query algorithm rule types before writing manual rule payloads.

dl rule types
dl rule add --workspace <spId> --body-file rule.json
dl rule list --workspace <spId> --page 0 --page-size 20
dl rule get --workspace <spId> --id <ruleId>
dl rule enable --workspace <spId> --id <ruleId>
dl rule disable --workspace <spId> --id <ruleId>

Compiled RuleForest

Build the workspace RuleForest after rule changes, or let the backend scheduler rebuild stale forests.

dl api request POST /api/v1/rule-forest/build/<spId>
dl api request GET /api/v1/rule-forest/status/<spId>
04

Runs, incidents, alerts, and escape hatch

Submit a run, execute it, inspect warning indexes, fetch incidents, and confirm alert delivery.

Run checks

Submit first to create a task record, then run it when the backend runner is available.

dl run submit --workspace <spId> --body-file run.json
dl run run --workspace <spId> --task <taskId>
dl run indexes --workspace <spId> --task <taskId>

Inspect incidents

Use these after a run to let an agent summarize business drift with evidence rows.

dl incidents list --workspace <spId>
dl incidents task --workspace <spId> --task <taskId>
dl incidents get --workspace <spId> --incident <incidentId>
dl incidents actions --workspace <spId> --incident <incidentId>

Alert channels and delivery logs

Notify users through email or webhook, then verify test sends and incident notifications.

dl alerts upsert --workspace <spId> --body-file alert-email-channel.json
dl alerts list --workspace <spId>
dl alerts test --workspace <spId> --channel <channelId>
dl alerts deliveries --workspace <spId> --task <taskId>

Raw API request

Fallback for a new backend endpoint before a high-level CLI alias exists.

dl api request GET /api/v1/token/verify
dl api request POST /api/v1/custom/path --body '{"dryRun":true}'
04

Agent workflow examples

These examples are short enough for an agent to run, inspect JSON output, save IDs, and continue without manual browser steps.

Onboard Codex inside a repo

Give Codex an AGENTS.md contract, verify auth, and keep credentials out of the repository.

  1. Install CLI
  2. Set API URL and workspace
  3. Export token in the session
  4. Generate the agent block
npm install -g @driftledger/cli
export DRIFTLEDGER_TOKEN="<jwt>"
dl config set --api-url https://driftledger.fatclaw.com --workspace <spId>
dl agent init codex --out AGENTS.md
dl doctor

Upload one raw orders CSV

Create metadata, bind CSV columns, upload the file, then let the agent capture dataset IDs from JSON output.

  1. Write meta.json
  2. Create CSV data source
  3. Write binding.json
  4. Upload raw file
  5. Submit assembly task
dl metadata col-types
dl metadata upsert --workspace <spId> --body-file meta.json
dl data-source upsert --workspace <spId> --display-name "Orders CSV" --type CSV_UPLOAD
dl source-binding upsert --workspace <spId> --body-file binding.json
dl dataset create-raw --workspace <spId> --display-name orders --binding-id <bindingId>
dl dataset upload --workspace <spId> --dataset <datasetId> --file orders.csv
dl assembly submit --workspace <spId> --body-file assembly.json
dl assembly run --workspace <spId> --task <assemblyTaskId>

Run checks against an assembled ledger

Skip source assembly when another job already produced the joined payment/order/settlement rows.

  1. Create assembled dataset
  2. Upload JSONL
  3. Create model and rule
  4. Configure alerts
  5. Submit and run
dl dataset create-assembled --workspace <spId> --display-name payment-ledger
dl dataset upload-assembled --workspace <spId> --dataset <datasetId> --file payment-ledger.jsonl
dl check-model create --workspace <spId> --body-file check-model.json
dl rule types
dl rule add --workspace <spId> --body-file rule.json
dl alerts upsert --workspace <spId> --body-file alert-email-channel.json
dl run submit --workspace <spId> --body-file run.json
dl run run --workspace <spId> --task <taskId>
dl incidents task --workspace <spId> --task <taskId>
dl alerts deliveries --workspace <spId> --task <taskId>

Use CLI in CI or a hosted agent

Avoid local config writes and make every output parseable by the next automation step.

  1. Set env vars
  2. Run doctor
  3. Verify token
  4. Call high-level or raw API command
export DRIFTLEDGER_API_URL="https://driftledger.fatclaw.com"
export DRIFTLEDGER_TOKEN="${DRIFTLEDGER_CI_TOKEN}"
export DRIFTLEDGER_WORKSPACE_ID="sp_prod"
dl doctor
dl auth verify
dl api request GET /api/v1/token/verify
05

Demo samples

The companion dl-agent repository includes a sanitized refund/payment/fund consistency scenario that agents can use for training, validation, and incident smoke tests.

Semantic sample directory

Use the named scenario folder instead of a generic demo name when referencing public assets.

samples/refund-payment-fund-consistency

Training and validation data

Train from clean assembled records, validate with both clean and controlled-anomaly records.

datasets/train.jsonl
datasets/test.jsonl
datasets/test-with-anomaly.jsonl

Sanitized reconciliation model

The model keeps join structure and rule context while replacing accounts, orders, payment IDs, names, and long identifiers with demo tokens.

models/demo_model.jsonl
manifest.json
npm run verify:samples

Refresh workflow

When backend sample assets change, sync them into dl-agent and run the privacy guard before publishing.

npm run sync:samples
npm run verify:samples
06

Repository layout

dl-agent is split by runtime, agent instructions, workflow docs, request templates, sanitized samples, scripts, skills, and future MCP packaging so each surface has a clear owner and verification path.

dl-agent/
  package.json
  package-lock.json
  .env.example
  .editorconfig
  .gitignore
  .github/
    workflows/ci.yml
    ISSUE_TEMPLATE/
      bug_report.md
      feature_request.md
    pull_request_template.md
  agents/
    AGENTS.md
    CLAUDE.md
    OPENCLAW.md
    AGENT.md
  assets/
    logo.svg
  docs/
    architecture.md
    commands.md
    publishing.md
    workflows.md
  examples/body-files/
    assembly.json
    binding.json
    check-model.json
    alert-email-channel.json
    alert-webhook-channel.json
    meta.json
    rule.json
    run.json
  packages/cli/
    package.json
    bin/driftledger.js
    src/cli.js
    src/core.js
    test/core.test.js
    README.md
  samples/refund-payment-fund-consistency/
    datasets/train.jsonl
    datasets/test.jsonl
    datasets/test-with-anomaly.jsonl
    models/demo_model.jsonl
    manifest.json
    README.md
  scripts/
    install.sh
    sync-demo-assets.mjs
    verify-demo-assets.mjs
    README.md
  skills/
    README.md
    driftledger-cli/
      SKILL.md
      examples/
      scripts/
    driftledger-incident-review/
      SKILL.md
      templates/
  mcp/
    README.md
  CHANGELOG.md
  CODE_OF_CONDUCT.md
  CONTRIBUTING.md
  LICENSE
  SECURITY.md
package.json / package-lock.json

npm workspace scripts, version metadata, and Node.js engine constraints.

.github

CI workflow, issue templates, and pull request template.

assets

Brand assets reused by the README and website.

packages/cli/bin

Executable entrypoint for dl and driftledger.

packages/cli/src

Argument parsing, config precedence, command mapping, and HTTP transport.

packages/cli/test

CLI command-contract tests.

scripts

Hosted install script plus sample sync and privacy verification utilities.

agents

Ready-to-copy instruction contracts for Codex, Claude Code, OpenClaw, and generic shell agents.

examples/body-files

Small request payloads for metadata, rules, runs, and alert channels that agents can copy, edit, diff, and pass with --body-file.

samples/refund-payment-fund-consistency

Sanitized model, training set, clean test set, anomaly test set, and manifest.

skills/driftledger-cli

CLI-first workflow skill for install, auth, workspace, data, model, rule, RuleForest, alerts, and run operations.

skills/driftledger-incident-review

Incident review skill for business drift summaries, alert delivery checks, and remediation handoffs.

mcp

Reserved surface for future MCP server or manifest packaging.

docs

Architecture and publishing notes for maintainers.

07

Body file templates

Start with these files and let the agent replace IDs from previous JSON responses. Keep payloads in files so retries are reviewable.

meta.json

Create metadata and fields

POST body for metadata upsert. Omit field types unless you need to constrain inference with values from dl metadata col-types.

{
  "table": {
    "spId": "<spId>",
    "nodeName": "payment_order",
    "nodeType": "TABLE",
    "riskLevel": "HIGH",
    "appName": "billing",
    "comment": "Payment order export"
  },
  "fields": [
    {"fieldName": "order_id", "primaryKey": true, "joinKey": true},
    {"fieldName": "paid_amount", "riskLevel": "HIGH"},
    {"fieldName": "paid_status"}
  ]
}
binding.json

Bind source columns

POST body for source binding upsert.

{
  "metaTableId": 1001,
  "dataSourceId": "<dataSourceId>",
  "sourceName": "orders.csv",
  "fieldMappings": {
    "Order ID": "order_id",
    "Paid Amount": "paid_amount",
    "Status": "paid_status"
  },
  "primaryKeyFields": ["order_id"]
}
assembly.json

Submit an assembly task

POST body for turning raw tables into assembled data.

{
  "displayName": "payment settlement assembly",
  "inputDatasetIds": ["<rawDatasetId>"],
  "riskModelId": "<riskModelId>",
  "outputDatasetName": "payment-settlement-assembled",
  "assemblyOptions": {
    "anchor": "payment_order",
    "joinMode": "LEFT_PRESERVE"
  }
}
check-model.json

Create a reconciliation model

POST body for reconciliation model create.

{
  "spId": "<spId>",
  "title": "Paid orders reconcile to access",
  "version": "v1",
  "riskLevel": "P1",
  "modelType": "TM",
  "checkerType": "DEFAULT",
  "description": "Paid orders must unlock the matching entitlement and settlement row."
}
rule.json

Add a reviewed rule

POST body for rule add. ruleType must be one of the values returned by dl rule types.

{
  "spId": "<spId>",
  "title": "paid order unlocks entitlement",
  "modelId": "<modelCode-or-id>",
  "modelVersion": "v1",
  "ruleType": "LOGIC",
  "ruleContent": "paid_status == PAID -> entitlement_status == ACTIVE",
  "state": "ONLINE",
  "generateType": "CUSTOM",
  "ruleTables": ["payment_order", "entitlement"]
}
run.json

Submit an execution run

POST body for run submit.

{
  "displayName": "payment ledger smoke",
  "datasetId": "<assembledDatasetId>",
  "riskModelId": 101,
  "ruleScope": "PUBLISHED",
  "selectedRuleIds": [],
  "executionOptions": {"mode": "smoke"}
}
alert-email-channel.json

Configure email alerts

POST body for alert channel upsert.

{
  "displayName": "Finance incident inbox",
  "channelType": "EMAIL",
  "enabled": true,
  "minSeverity": "HIGH",
  "recipients": ["finance-ops@example.com"]
}
alert-webhook-channel.json

Configure webhook alerts

POST body for webhook-based delivery.

{
  "displayName": "Incident webhook",
  "channelType": "WEBHOOK",
  "enabled": true,
  "minSeverity": "MEDIUM",
  "webhookUrl": "https://example.com/driftledger-alerts",
  "webhookSecret": "replace-with-shared-secret"
}
08

Troubleshooting

Most failures are config, token, payload, or backend availability problems. The CLI prints JSON errors so an agent can branch on ok:false.

The CLI is using localhost when you expected production.

Inspect config and env precedence. Flags win over env, env wins over stored config.

dl doctor
dl config get
echo "$DRIFTLEDGER_API_URL"

A command is running in the wrong workspace.

dl uses Default when no workspace is specified. Inspect stored config and override only for a non-default workspace.

dl workspace list
dl config get
dl config set --workspace <spId>
export DRIFTLEDGER_WORKSPACE_ID="<spId>"

--body-file fails with a JSON parse error.

Validate the file before retrying; keep generated payloads in files for review.

node -e "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'))" meta.json
dl metadata upsert --body-file meta.json

The backend endpoint exists but the CLI has no friendly alias yet.

Use api request as a temporary escape hatch, then add a high-level command to the CLI.

dl api request GET /api/v1/token/verify
dl api request POST /api/v1/new-endpoint --body @payload.json

Incidents are created but nobody receives a notification.

List channels, send a test alert, and then inspect delivery logs filtered by the execution task.

dl alerts list
dl alerts test --channel <channelId>
dl alerts deliveries --task <taskId>

Operating rules

  • All normal command responses are JSON; errors are JSON on stderr with ok:false.
  • Use --body-file for metadata, rules, models, and run payloads so the agent can diff and retry.
  • Omit metadata field types by default; if needed, constrain with values from dl metadata col-types rather than SQL types.
  • Use CSV for raw table uploads and JSONL for assembled ledgers in the current version.
  • Use demo recipients and webhook URLs in examples; never commit real notification secrets.
  • Never paste tokens into chats or committed docs; use DRIFTLEDGER_TOKEN or local config.