Configuration
config.ts, environment variables, and precedence.
Most agents work with zero configuration. When you need defaults across agents — a model, a Temporal address, a session-store backend, a capability policy, a sandbox profile — put them in .fabricharness/config.ts.
.fabricharness/config.ts
import type { FabricHarnessConfig } from '@fabric-harness/node';
const config: FabricHarnessConfig = {
agent: {
model: 'openai/gpt-5.5',
// Optional capability policy applied to every agent unless overridden by init():
policy: {
commandPolicy: {
allow: ['git status*', 'git log*', 'gh issue view*'],
requireApproval: ['gh issue comment*', 'psql*'],
deny: ['git push*', 'rm -rf*'],
},
maxCommandTimeoutMs: 30_000,
approvals: { requiredApprovals: 1, defaultTimeoutMs: 60_000, risk: 'medium' },
},
},
run: {
target: 'node', // 'node' | 'temporal-worker' | 'cloudflare'
model: 'openai/gpt-5.5',
idPrefix: 'fab',
cwd: 'project', // default sandbox/session cwd for fh run
},
temporal: {
address: 'localhost:7233',
taskQueue: 'fabric-harness',
namespace: 'default',
workflowIdPrefix: 'fabric-cli',
promptWorkflowMode: 'hybrid',
},
sandbox: {
backend: 'local', // 'virtual' | 'empty' | 'local' | 'docker' | 'cloudflare'
metadata: {
inheritSafeEnv: true,
envAllowlist: ['GH_TOKEN', 'DATABASE_URL'],
defaultTimeoutMs: 30_000,
outputLimitBytes: 256_000,
},
},
store: {
backend: 'file', // 'file' | 'sqlite' | 'postgres' | 'cloudflare'
},
cloudflare: {
workerName: 'my-agent',
routes: [{ pattern: 'api.example.com/agents/*', zoneName: 'example.com' }],
bindings: {
kv: [{ binding: 'SESSIONS' }],
r2: [{ binding: 'KB' }],
d1: [{ binding: 'DB' }],
},
},
};
export default config;The config is loaded dynamically — you can use TypeScript freely (imports, type checks, conditional logic, etc.).
Precedence
For each setting, the highest source wins:
CLI flag > environment variable > config.ts > agent defaultCommon environment variables:
| Variable | Purpose |
|---|---|
FABRIC_MODEL | Default provider/model-id for fh run. |
FABRIC_TARGET / FABRIC_HARNESS_TARGET | Default --target for fh run. |
FABRIC_TEMPORAL_TASK_QUEUE | Default Temporal task queue. |
FABRIC_TEMPORAL_ADDRESS | Default Temporal address. |
FABRIC_TEMPORAL_NAMESPACE | Default Temporal namespace. |
FABRIC_DOCKER_TEST | Gates live Docker tests (=1 to enable). |
OPENAI_API_KEY, AZURE_OPENAI_*, etc. | Provider credentials. |
Loading .env files
Fabric Harness auto-loads common env files from the repo root and workspace root:
.env
.env.local
.fabricharness/.env
.fabricharness/.env.localFor local development, put provider keys once in the repo-level .env.local:
cp .env.example .env.local
# edit .env.local and set OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.Shell environment values always win. Use explicit --env <file> only for overrides; repeatable explicit env files override auto-loaded files but not shell env.
fh run ask --env .env.test --question "hi"
fh dev --env .env.test
fh temporal-worker --env .env.test--env is supported on run, dev, and temporal-worker.
Agent-level overrides
A metadata agent can declare its own defaults:
export default agent({
name: 'ask',
model: 'openai/gpt-5.5', // wins over config.run.model
target: 'node', // wins over config.run.target
// ...
});CLI flags still override agent defaults.
Where config files live in the build
fh build reads .fabricharness/config.ts at build time and bakes the relevant subset into the manifest. Runtime-sensitive values (Temporal address, secrets, etc.) stay env-driven so they can change per environment.
Workspace Layout
The .fabricharness directory convention.
Use Cases
Ten Fabric Harness agents you can build today, across the software development lifecycle — issue triage, PR review, changelog drafting, test generation, dependency audit, migrations, API docs, bug repro, release notes, and incident runbooks. Every example shows both minimal and complete entrypoint forms.