ContractRefine — Contract Taxonomy

This page catalogs the Phase 1 set of contracts the ContractRefine verifier evaluates at pre-execution time. The catalog is deliberately small and finite — see the parent Architecture for the design discipline (“Not a generic policy DSL”, “Not Isaac-aware”) this restraint serves.

Reason layer

Every contract failure emits a reason that conforms to the existing <layer>: <subreason> regex enforced by runtime/reasons_shape_test.go. ContractRefine introduces one new canonical layer:

contract:

Subreasons follow the existing convention: lowercase, underscores allowed after the first character. See the catalog below for the full list.

The Phase 1 catalog

Contract kind

Checks

Failure subreason

plan_shape

Each PlannedToolCall.Kind is a known runtime tool kind; no duplicates beyond a small bound; the plan is non-empty.

plan_shape_invalid

argument_provenance

Every param marked trusted in policy carries a Provenance.Source drawn from the allowed source set (operator, policy, supervisor, sensor, policy, model).

argument_provenance_failed

capability_in_zone

The requested capability is permitted inside context.zone. Zone defaults to default.

capability_not_permitted_in_zone

rollback_contract

context.rollback_contract id resolves in the rollback/ registry AND is in the ready state at preflight time.

rollback_contract_missing or rollback_contract_not_ready

expected_evidence

Every WAL attribute key the caller pledges via context.expected_evidence belongs to a known emitter set. The caller cannot pledge invented evidence.

expected_evidence_unknown

attestation_freshness

When attestation is enabled, the snapshot age is within a policy-defined ceiling.

attestation_snapshot_stale

decision_chain_complete

The runtime configuration at preflight time can produce a complete decision chain for the requested capability. The Phase 1 chain is hardcoded in runtime/contract/chain.go: policy_eval + attestation_snapshot + wal_decision_emit + lock_fingerprint. Three outcomes, distinct from each other: (1) introspection succeeds and a link is missing ⇒ ContractResult{outcome:"fail", severity:"blocking"} with reason chain_link_missing_<link> (top-level PreflightDecision.outcome aggregates this as deny); (2) introspection itself errors (panic, malformed runtime config) ⇒ ContractResult{outcome:"fail", severity:"blocking"} with reason introspector_error (top-level deny; INV-CR-2 owns this); (3) introspection succeeds but the chain cannot be proven complete because evaluating it requires substrate the verifier cannot reach offline (e.g., orchestrator-side enrollment state on an edge node operating disconnected) ⇒ ContractResult{outcome:"fail", severity:"advisory"} with reason chain_unverifiable_offline (top-level PreflightDecision.outcome remains pass — see “Where advisory signals live” in Architecture; /v1/tool proceeds normally; the WAL records the advisory for audit).

chain_link_missing_<link> (blocking) · introspector_error (blocking) · chain_unverifiable_offline (advisory)

What the catalog is NOT

  • No domain-specific contracts. No MAVLink-specific obligations, no Isaac mission-gate semantics, no ROSOrin restricted-zone primitives. Those land in consumer epics (#849 Isaac, #793 ROSOrin) on top of the neutral primitives here.

  • No EntitlementResolver / ApprovalResolver contracts. Deferred for interface-quality reasons — there is no substrate in adk to anchor the resolver interface against. A follow-up epic will land them once ROSOrin’s /v1/intent substrate is in place.

  • No per-capability custom chains. Phase 1 ships exactly one hardcoded decision chain. Per-capability chain customization via the policy bundle is a documented v2 feature; introspection failure on a custom chain returns the advisory chain_unverifiable_offline, never a fail-closed deny.

Repair-hint shape

A repair_required outcome carries one or more RepairHint entries:

{
  "field": "plan[1].params.altitude_m",
  "suggestion": "altitude_m exceeds zone ceiling; reduce to 30 or below.",
  "suggested_value": 30,
  "bounded": true
}
  • field — JSON pointer-style path to the offending param.

  • suggestion — human-readable repair text. Audit-only; never parsed by the runtime.

  • suggested_value — present iff a deterministic, bounded correction can be named.

  • boundedtrue ⇒ the suggestion is a deterministic, contract- derived value the caller may apply mechanically. false ⇒ informational only; no machine-applicable correction.

Refinement is bounded by INV-CR-6: at most one repair attempt per session by default, configurable up to a small constant ≤ 3. Beyond that, the verifier returns deny.

Policy integration

Two surfaces let policy bundles interact with ContractRefine:

  1. manifest.requires_preflight: true — when set, /v1/tool calls for capabilities owned by this bundle MUST present a fresh, matching X-Autonomy-Preflight-Id. Absent header ⇒ policy denies with contract: preflight_required. Default is false (preflight remains optional). Behavior is gated globally by runtime.contract_refine.mode.

  2. input.preflight in Rego — when a preflight has run, the PreflightDecision is exposed verbatim to policy as input.preflight. Rules MAY read it (e.g., to deny a pass verdict whose expected_evidence did not include a required attr). Rules MUST NOT use it to flip a contract deny into a policy allow — that violates INV-CR-9.

Adding to the catalog (v2 path)

New contract kinds land via the following discipline:

  • One contract kind per PR. The kind, its checks, its failure subreasons, and its repair-hint semantics are reviewed together.

  • Reason subreasons go into runtime/reasons_shape_test.go along with the contract.

  • An INV-CR-N entry on Invariants iff the kind asserts a new safety or security property that operators rely on.

  • A taxonomy table row on this page.

Catalog growth is bounded by deliberate review pressure — operators ask “what new invariant does this contract assert?” before “is the code clean?”. A new kind that does not assert a new invariant is an implementation detail of an existing kind, not a new entry.