FabricFabricHarness
Reference

Build Manifest

Schema-v2 manifest emitted by fh build for jobs, persistent agents, files, and provenance.

Every fh build writes manifest.json at the artifact root. Schema v2 separates finite jobs from persistent agents and records every emitted file for verification.

Current shape

{
  "schemaVersion": 2,
  "createdAt": "2026-07-09T21:59:56.279Z",
  "target": "databricks-app",
  "workspaceRoot": "/source/analytics-agent",
  "outDir": "/source/analytics-agent/.fabricharness/build/databricks-app",
  "entrypoint": "dist/server.mjs",
  "agentsManifestSha256": "46df8f...",
  "config": {
    "source": ".fabricharness/config.ts",
    "agent": { "model": "databricks/analytics-model" },
    "sandbox": "local"
  },
  "jobs": [
    {
      "name": "analyst",
      "kind": "job",
      "source": ".fabricharness/jobs/analyst.mjs",
      "entry": "jobs/analyst.mjs",
      "sha256": "68d820...",
      "triggers": { "webhook": true, "manual": true }
    }
  ],
  "agents": [
    {
      "name": "copilot",
      "kind": "agent",
      "source": ".fabricharness/agents/copilot.mjs",
      "entry": "agents/copilot.mjs",
      "sha256": "bba012..."
    }
  ],
  "roles": [
    {
      "name": "data-analyst",
      "path": ".fabricharness/roles/data-analyst.md",
      "description": "Analyze governed data."
    }
  ],
  "skills": [
    {
      "name": "analyze-table",
      "path": ".fabricharness/skills/analyze-table/SKILL.md"
    }
  ],
  "files": [
    {
      "path": "dist/server.mjs",
      "bytes": 3874732,
      "sha256": "b5b8ab..."
    }
  ],
  "package": {
    "name": "analytics-agent",
    "version": "1.0.0",
    "type": "module",
    "dependencies": {}
  }
}

agentsManifestSha256 is retained as the compatibility field name, but its digest covers both jobs and agents in schema v2.

Inspect a build

jq '{schemaVersion, target, jobs, agents, entrypoint}' \
  .fabricharness/build/node/manifest.json

List every local build:

fh builds

The Node admin API can read manifests that remain under the active workspace build directory:

curl http://localhost:4317/builds/node/manifest

For a standalone artifact deployed elsewhere, read manifest.json from the artifact filesystem or publish it through your deployment platform. The shared v2 server does not expose a root GET /manifest route.

Schema-v1 compatibility

readBuildManifest() normalizes legacy manifests by treating the old agents collection as finite jobs and returning schema-v2 data:

import { readBuildManifest } from '@fabric-harness/node';

const manifest = await readBuildManifest(process.cwd(), 'node');
for (const job of manifest?.jobs ?? []) {
  console.log('job', job.name);
}
for (const agent of manifest?.agents ?? []) {
  console.log('persistent agent', agent.name);
}

External manifest consumers should migrate explicitly rather than assuming every definition is an agent.

Supply-chain verification

Build with metadata:

fh build --target docker \
  --provenance \
  --attestation \
  --sbom

Then verify:

fh verify-provenance .fabricharness/build/docker
fh verify-attestation .fabricharness/build/docker

Provenance and attestations include definition name, kind, source, and digest. The files list lets deployment tooling independently verify the emitted tree.

See also