TechFabricTechFabricHarness
CLI

fh doctor

Diagnose a workspace before you blame the agent, covering tool wiring, configuration and live model connectivity.

fabric-harness doctor [--target node|temporal-worker|databricks-app|databricks-serving|buzz] [--model provider/model] [--getting-started] [--tools] [--workspace] [--live] [--json]

fh doctor validates that your workspace is set up correctly and (optionally) that a real model can be invoked.

Options

FlagDescription
--target <node|temporal-worker|databricks-app|databricks-serving|buzz>Validate the chosen run, deployment, or first-party integration target.
--model <provider/model-id>Probe a specific model (combine with --live).
--getting-startedCheck Node version, ESM package setup, Fabric dependencies, npm scripts, and .fabricharness/agents discovery.
--toolsEnumerate built-in tools and required binaries (docker, gh, etc.).
--workspaceStatically validate the workspace: skill and role references, target-incompatible imports, and files in agent directories that export no definition.
--liveMake a bounded live model request, or run read-only relay and durable-state certification for --target buzz.
--jsonEmit a machine-readable report.

Examples

Local readiness

fh doctor --getting-started --tools

Live model check

cp .env.example .env.local
# edit .env.local and set OPENAI_API_KEY=...
fh doctor --live --model openai/gpt-5.5

Workspace validation

fh doctor --workspace
fh doctor --workspace --target cloudflare

Reads source without executing it, so it needs no credentials, no network, and doesn't import your agent modules. It reports:

CodeSeverityMeaning
skill-not-founderrorA session.skill('name') call whose name no skill defines, neither a .fabricharness/skills/ directory, a build-time SKILL.md import, nor a defineSkill() in the same file.
role-not-founderrorAn init({ role }) naming a role no file defines.
target-incompatible-importerrorA Node built-in the chosen target's runtime does not provide. Only reported when --target names such a runtime.
no-default-exportwarningA file in an agent directory exporting no default definition.

Errors exit non-zero, so this composes into CI. Warnings don't.

Without --target, target-specific checks are skipped, a workspace that only ever runs on Node should not be warned about its node:fs import.

Two checks are deliberately conservative, because a false positive on correct code is worse than a missed finding. A skill imported from a package cannot be resolved from source, so the skill check is suppressed for that file; and the role check is scoped to init({ ... }) options, since role: is also the LLM message discriminator.

Temporal target

fh doctor --target temporal-worker

The doctor checks Temporal connectivity using config/env defaults. Make sure FABRIC_TEMPORAL_ADDRESS and your task queue are correct.

Databricks App bindings

fh doctor --target databricks-app --json
fh doctor --target databricks-app --live --json

Every Databricks report includes a workspace-readiness section. It uses four intentionally narrow classifications:

ClassificationMeaning
contract-supportedThe installed Harness code has an offline-tested adapter. It says nothing about this workspace's grants or enrollment.
live-certified-hereThe installed package, declared cloud, and region exactly match retained public certification evidence.
preview-enabledA bounded read-only live probe reached that preview API in this workspace.
not-establishedThe command cannot prove the claim. Treat it as unknown, not as disabled.

Offline mode reports the configured host, inferred cloud/region, installed package version, exact public certification relationship, and contract support for Apps, Unity Catalog/OBO, SQL, Genie, Model Serving, AI Gateway, Lakebase, managed MCP, Supervisor Agents, and managed memory. --live adds bounded read-only identity and service discovery probes. A successful service probe proves reachability under the probing principal; it does not prove every end user's Unity Catalog grant. The command never prints tokens or connection strings.

Set FABRIC_DATABRICKS_APP_CAPABILITIES to the comma-separated capabilities the App claims. lakebase, genie, obo, and/or system-tables-cost. Doctor fails closed when a claim lacks its required endpoint, database, Genie space, OBO opt-in, warehouse, or cost-scope binding. It never prints credential values. The report also includes a redacted effective inventory:

  • identity kind and credential source;
  • enabled model-callable tools with effects and service names;
  • static or input-bound governed resources;
  • approval coverage;
  • persistence, scheduler identity, lease, and catch-up modes; and
  • unsupported or dynamically resolved capabilities.

Persistent-agent initializers are interaction-scoped, so doctor reports their tool inventory as dynamic instead of executing an initializer with a fabricated identity.

Buzz bridge

fh doctor --target buzz --json
fh doctor --target buzz --live

The offline preflight validates Node 22/native WebSocket support, the relay and forwarding URLs, redacted Nostr-key and HMAC-secret shape, the server-owned community/channel allowlist, durable PostgreSQL or Lakebase configuration, and the current v2 generated recipe. It specifically rejects the old process-memory tail and recipes that omit decision-receipt or dead-letter wiring.

--live is a read-only certification profile. It performs a bounded NIP-11 probe, requires NIP-01 and NIP-42, signs NIP-98 queries with the configured adapter identity, verifies the returned NIP-01 event integrity, and requires that identity in both the authoritative relay roster and every configured channel member list. It then connects to PostgreSQL or Databricks Lakebase with a single-connection pool and reads only content-free operational evidence. Relay cursor lag, cursor-update age, unresolved dead-letter depth, and prepared/published decision-card counts.

The default limits are 300 seconds of relay lag, 300 seconds since the cursor update, and zero unresolved dead letters. Set BUZZ_MAX_RELAY_LAG_SECONDS, BUZZ_MAX_CURSOR_AGE_SECONDS, and BUZZ_MAX_DEAD_LETTERS to explicit non-negative integers when the deployment SLO differs. The JSON report is safe for CI evidence. It never includes event content, private keys, forwarding secrets, database URLs, or database passwords. Relay and channel membership prove transport admission only; they do not grant Fabric action authority.

What it checks

  • Workspace root resolution.
  • Agents discovered.
  • Node/package/ESM/dependency setup (when --getting-started).
  • Built-in tool schemas and binaries on PATH (when --tools).
  • Model provider configuration.
  • Optional live model round-trip when --live.
  • Optional Temporal connectivity for --target temporal-worker.
  • Databricks CLI, authentication, and claimed App bindings for Databricks deployment targets.
  • Buzz bridge configuration, v2 durability wiring, and optional read-only relay/Lakebase certification.