paybondpaybond
Sign in

Harbor predicate DSL

Supported predicate format, clause semantics, limits, and evaluation responses for Harbor evidence checks.

Harbor uses predicate_dsl to define the release rule attached to an intent. When evidence is later submitted, Harbor evaluates that evidence against the stored rule and returns a pass or fail result with an audit trace.

This format is intentionally narrow. It supports deterministic checks on the submitted evidence and on the intent budget, but it does not run arbitrary code, call external services, or read data from another tenant.

Use predicate_dsl when you want to send the rule inline on POST /intents. Use predicate_ref when you want a reusable, versioned tenant policy managed centrally. For the surrounding endpoints, see the Harbor API reference.

Where this appears

HTTPField / bodyRole
POST /intentspredicate_dsl (JSON object, used when predicate_ref is not provided)Stored on the intent and validated when the intent is created.
POST /intents/{id}/evidenceRequest payloadEvaluated as evidence JSON against the intent's stored predicate.
POST /intents/{id}/evidenceResponse predicate_evaluationReturns the evaluation result (passed and trace).

Harbor rejects malformed or oversized predicate documents at intent creation with 400 Bad Request. During evidence submission, business-rule mismatches usually return passed: false, while evidence-shape problems can return 422 Unprocessable Entity.

Product guarantees

  • Deterministic evaluation: the same predicate and evidence produce the same result.
  • Bounded execution: Harbor enforces fixed depth, path, and fuel limits so evaluation remains predictable.
  • Tenant-scoped inputs only: evaluation uses only the current intent, its declared evidence schema, and the submitted evidence payload.
  • Stable release rule: Harbor binds the predicate to the intent at creation time so the rule evaluated later is the same rule the parties approved.

For the broader isolation model, see Tenant model.

Document envelope

Every predicate document must include:

FieldTypeDescription
versionintegerDSL revision. Only 1 is supported today.
rootobjectRoot clause. Must include string field op.
{
  "version": 1,
  "root": { "op": "true" }
}

Treat unknown version values as unsupported.

Evidence paths

Paths are arrays of string keys into the submitted evidence JSON object. They support nested objects only.

Example:

{ "path": ["status"] }

reads payload.status, while:

{ "path": ["job", "result", "status"] }

reads payload.job.result.status.

Clauses (op)

All clauses are JSON objects with an op field in snake_case.

Boolean composition

opFieldsSemantics
trueAlways satisfied.
andclauses: array of clause objectsAll clauses must pass.
orclauses: array of clause objectsAt least one clause must pass.
notclause: single clause objectNegates the inner result.

Evidence checks

opFieldsSemantics
eqpath: string[], value: anyEvidence at path must equal value using JSON equality.
completionpath: string[], value: anySame as eq, but intended for completion-style checks such as status = completed.
ltepath: string[], limit_source: stringInteger at path must be less than or equal to a server-owned limit. Today the only supported value is "amount_cents", which compares against the intent amount.
budget_cappath: string[]Shorthand for checking that an integer field is less than or equal to amount_cents.

Schema-aware check

opFieldsSemantics
schema_fieldfield: string (non-empty)Top-level evidence key field must exist, and its JSON value type must match the type declared in evidence_schema.properties[field].type.
array_nonemptyfield: string (non-empty)Top-level evidence key field must exist and be a JSON array with at least one element.

This is useful when you want to require a field without hard-coding one exact value. evidence_schema follows a minimal JSON Schema-style contract, for example:

{
  "type": "object",
  "properties": {
    "status": { "type": "string" },
    "cost": { "type": "integer" }
  }
}

Supported type values are null, boolean, string, integer, number, array, and object. An array of type strings is also allowed for multi-type fields.

Limits

These limits apply at both intent creation and evidence evaluation.

LimitValueApplies to
Max nesting depth (and / or / not)24Clause tree
Max fuel (AST nodes visited)256Whole document
Max path segments16path on eq, completion, lte, budget_cap
Max clauses length in and / or32Per operator

Evaluation result (predicate_evaluation)

On successful evidence submission, Harbor includes a predicate_evaluation object shaped like:

{
  "passed": true,
  "trace": [
    {
      "kind": "completion",
      "detail": "value matched",
      "data": { "path": "status", "passed": true, "expected": "completed", "observed": "completed" }
    }
  ]
}
FieldDescription
passedWhether the evidence satisfied the predicate.
traceOrdered evaluation steps that explain why Harbor passed or failed the rule.

Logical failures such as an eq mismatch return passed: false with a trace explaining what failed. That is different from a malformed request or invalid evidence shape.

Direct DSL vs managed policies

  • Use predicate_dsl when each intent carries its own inline rule.
  • Use predicate_ref when you want a reusable tenant policy with versioning, preview, and controlled rollout.
  • Managed policy lifecycle endpoints are part of the Harbor API reference.

Examples

Accept any evidence (useful for smoke tests):

{
  "version": 1,
  "root": { "op": "true" }
}

Require a completed status and keep cost within budget:

{
  "version": 1,
  "root": {
    "op": "and",
    "clauses": [
      { "op": "completion", "path": ["status"], "value": "completed" },
      { "op": "budget_cap", "path": ["cost"] }
    ]
  }
}

Evidence might be { "status": "completed", "cost": 5000 } with amount_cents >= 5000.

Require a declared field from the evidence schema:

{
  "version": 1,
  "root": { "op": "schema_field", "field": "invoice_id" }
}

Evidence must include top-level invoice_id, and evidence_schema.properties.invoice_id.type must describe its JSON type.

Managed policy templates

Harbor ships managed templates that materialize tenant parameters into validated predicate_dsl. Templates are listed at GET /harbor/policy/v1/templates and previewed or tested via the policy registry API and console workbench.

Template IDUse caseMaterialized rule (summary)
true_v1Sandbox smoke / externally governed releaseAlways pass
completion_v1Single completion-style fieldcompletion on status_path
completion_budget_v1Completion and cost within intent budgetand of completion and budget_cap
api_response_v1Paid API returned successeq on HTTP status and schema_field for vendor_ref_id and response_digest
webhook_confirmation_v1Async webhook confirmation in evidencecompletion on event type and schema_field for webhook id and payload digest
artifact_hash_v1Out-of-band artifact attestationschema_field and array_nonempty on hash array and completion on operation and schema_field on vendor ref

Preset IDs, sample evidence, and parameter defaults live in the shared completion preset catalog (catalog.json).

api_response_v1 parameters:

{
  "http_status_path": ["http_status"],
  "expected_http_status": 200
}

webhook_confirmation_v1 parameters:

{
  "event_type_path": ["event_type"],
  "expected_event_type": "payment.succeeded"
}

artifact_hash_v1 parameters:

{
  "operation_path": ["operation"],
  "expected_operation": "attested"
}

Integrators collect vendor signals out of band and place references and digests in evidence; the predicate VM evaluates only the submitted JSON.

Version support

predicate_dsl.versionMeaning
1Current wire format (this page).