Skip to content

Configuration

The harness is configured via harness.yaml in your project root. Create one with kcp-harness init.

Full Reference

yaml
version: "1.0"

governance:
  domains:
    - manifest: "./knowledge.yaml"    # Path to knowledge manifest
      paths:                           # File paths governed by this manifest
        - "docs/"
        - "src/models/"
      urls:                            # URL prefixes governed by this manifest
        - "https://docs.example.com/"
      tools:                           # Custom tool names to govern
        - "custom_knowledge_tool"

  policy:
    fail_closed: true          # Block access when governance can't verify (default: true)
    audit_all: true            # Log pass-through calls too (default: true)
    max_units: 5               # Maximum knowledge units per plan
    strict: false              # Strict mode — reject low-relevance units
    budget:                    # Monetary budget ceiling
      amount: 1.00
      currency: USDC
    context_budget: 50000      # Token budget ceiling
    env: prod                  # Environment (affects temporal gates)

  confidence:                  # Post-synthesis confidence gate (harness_assess)
    threshold: 0.7             # Pass/fail line, 0..1 — callers may tighten, never loosen
    severity: critical         # Label recorded on verdicts
    route_to_role: account-owner  # Route failed verdicts to this approval role
    expires_after: 72h         # TTL for routed tickets
    policy_ref: POL-9.1        # Policy citation carried as ticket evidence

  approvals:                   # Human-approval gates
    provider: file             # Ticket store: file (persisted) or memory
    dir: .kcp-harness/approvals
    require_signed_resolutions: false  # true: an unsigned/invalid --private-key resolution
                                        # fails closed — see api/cli.md `approvals approve`
    trusted_keys:               # Optional. Reviewer public keys (paths or inline PEM/base64/
      - ./keys/kari.pub          # hex). When set, a signature must verify against one of these
                                  # to bind it to a named identity; when omitted, the signature's
                                  # own embedded key is used (integrity only, not identity).
    rules:
      - match:                 # Absent criteria match everything; present ones AND together
          tools: [Write, Edit]
          paths: [records/]
        required_role: account-owner
        expires_after: 72h     # Unresolved tickets expire (fail-closed)
        policy_ref: POL-7.2

downstream:
  - name: "filesystem"         # Downstream MCP server name
    command: "npx"             # Command to launch
    args:                      # Arguments
      - "-y"
      - "@modelcontextprotocol/server-filesystem"
      - "."

audit:
  path: ".kcp-harness/audit.jsonl"   # Audit log path

Governed Domains

Each domain maps a knowledge.yaml manifest to the paths, URLs, and tools it governs. When a tool call targets a governed path, the harness routes it through the manifest's 14-gate cascade.

You can have multiple domains:

yaml
governance:
  domains:
    - manifest: "./docs/knowledge.yaml"
      paths: ["docs/"]
    - manifest: "./api/knowledge.yaml"
      paths: ["src/api/"]
      urls: ["https://api.example.com/"]

Policy

FieldTypeDefaultDescription
fail_closedbooleantrueBlock ungoverned access to governed paths
audit_allbooleantrueLog pass-through (non-governed) tool calls
max_unitsnumber5Maximum knowledge units per plan
strictbooleanfalseReject units below relevance threshold
budgetobjectMonetary budget ceiling (amount + currency)
context_budgetnumberToken budget ceiling
envstringEnvironment name (affects temporal gates)

Human-Approval Gates

governance.approvals holds calls for a named human — no matter what the automated governance paths would decide. See Governance Model for the state machine and invariants.

FieldTypeDescription
providerfile | memoryTicket store. file (default) persists to dir and survives restarts
dirstringStore directory (default .kcp-harness/approvals)
rules[].match.toolsstring[]Tool names the rule applies to (absent = all)
rules[].match.pathsstring[]Governed path prefixes (absent = all)
rules[].required_rolestringRole that must approve — required
rules[].expires_afterdurationTicket TTL (30m, 72h, 7d); expired = fail-closed
rules[].policy_refstringPolicy citation carried as ticket evidence

Approval requirements are org policy, not knowledge provenance — they live here in harness.yaml, never in the (signed) knowledge.yaml.

Confidence Gate

governance.confidence configures the harness_assess tool.

FieldTypeDescription
thresholdnumberPass/fail line, 0..1. A caller-supplied threshold can tighten this but never loosen it
severitystringLabel recorded on verdicts (e.g. critical)
route_to_rolestringWhen set (and approvals are configured), failed verdicts open an approval ticket for this role
expires_afterdurationTTL for routed tickets
policy_refstringPolicy citation carried as ticket evidence

Conformance Routing

governance.conformance routes holds opened by the procedural conformance gate (an active skill's action_scope violation) — independent of the confidence gate above, since "out of scope" and "low confidence" are different events that may need different reviewers or policy citations.

FieldTypeDescription
route_to_rolestringRoute conformance holds to this approval role (requires governance.approvals)
expires_afterdurationTTL for routed conformance tickets
policy_refstringPolicy citation carried as conformance ticket evidence

When governance.conformance is absent, a conformance hold falls back to governance.confidence's routing fields if configured, then to a hardcoded default role (governance-reviewer) with no policy citation.

Audit

The audit log is an append-only JSONL file. Each line is a self-contained event. See Audit Log for the full event schema.

Environment Variables

VariableDescription
KCP_HARNESS_CONFIGOverride config file path (default: harness.yaml)
KCP_HARNESS_AUDITOverride audit log path
ANTHROPIC_API_KEYRequired if kcp-agent needs Claude API access

Released under the Apache 2.0 License.