Declaration contract

Task Declaration Schema

This is the normative machine-checkable contract family for a PAA task. It includes the task declaration and the three runtime schemas it binds: evidence records, decision artifacts, and autonomy events.

Task declaration schema version: paa-task/0.2.1-draft. This page is the builder reference for field semantics, evaluator vocabulary, gate rules, typed transitions, and the conformance-tested examples.

Building from cold start? The Governed Autonomy Journey walks one task through every contract below in build order, stage by stage.

The contract family

A conformant PAA runtime produces four linked artifacts, each with its own normative schema: a task declaration (the static contract below), an evidence record per evaluator verdict, a decision artifact snapshotting the evidence behind a promotion or demotion, and an autonomy event row for every motion proposal, resolution, and position change. Downloads for all four are below; each is a byte-identical deployed copy of the corresponding file in schemas/.

Normative artifacts

  • PAA Task Declaration (paa-task/0.2.1-draft): Machine-checkable autonomy declaration for a Progressive Autonomy Architecture task. Download
  • PAA Evidence Record (paa-evidence-record/0.1.0-draft): Universal runtime envelope for one evaluator's verdict on one subject, produced against a PAA task declaration. Download
  • PAA Decision Artifact (paa-decision-artifact/0.1.0-draft): Immutable, capped admissibility snapshot backing one promotion or demotion decision for a PAA task. Download
  • PAA Autonomy Event (paa-autonomy-event/0.1.0-draft): One row of the append-only autonomy event stream: a motion proposal, its resolution, or the position change it authorized. Download

Each schema version is distinct from the site-wide version label. The public download URLs above are stable; the x-paa-schema-version field inside each file identifies the contract version. Use any JSON Schema draft-07 validator to check declarations or runtime artifacts in CI or tooling.

Top-level declaration fields

A valid task declaration is a strict object with additionalProperties: false at every level. Required top-level fields:

  • task: stable identifier matching [a-z][a-z0-9_]*.
  • version: integer declaration version, minimum 1. Each version owns an independent position and evidence partition. Publishing a successor does not implicitly carry forward position or promotion evidence.
  • description: non-empty string naming the bounded task and its governed effect.
  • boundary: object with input and output, both non-empty strings naming the typed observable unit.
  • initial_position: one of manual, hitl, hotl, autonomous. The position before any position_changed event exists, applied independently to every declared scope.
  • deployment: one of active, shadow, disabled. Required; there is no default.
  • evaluators: non-empty array; at least one evaluator is required.
  • position_policy: object with at least one entry mapping a position to a placement value.
  • promotion: promotion rule object.
  • demotion: demotion rule object.

Optional top-level field: scopes, a non-empty array of declared runtime scopes (for example, publish:bluesky). When absent, runtime scope is null. Position and motion history are held independently for each exact task / declaration_version / scope.

Evaluators and gate semantics

evaluators is a non-empty array. Each evaluator is a strict object with seven required fields. Every field is required; none default:

  • property: non-empty string naming the property being evaluated.
  • target: one of input, process, output, outcome.
  • technique: one of deterministic, classifier, llm_judge, human.
  • evaluation_basis: object with kind (one of invariant, reference_label, rubric, human_gold, downstream_result) and ref, the name of the concrete invariant set, rubric, label set, human-gold protocol, or downstream measure.
  • epistemic_status: proxy or ground_truth. Whether this evaluator's verdict is an approximation of ground truth or ground truth itself. Independent of evaluation basis: a rubric-driven llm_judge is commonly proxy; human_gold ordinarily carries ground_truth, but neither mapping is enforced by the schema.
  • version: non-empty string identifying this evaluator instance. Comparable evaluators may assert the same property without sharing technique, evaluation basis, epistemic status, version, or authority.
  • authority: advisory or blocking. No third value: shadow is a deployment mode, never an evaluator authority.

Fixed gate rule: all blocking evaluators must pass for the governed effect to proceed. For a blocking evaluator, a fail, error, timeout, abstention, malformed result, or missing result prevents the governed effect. advisory evaluators are recorded and surfaced but do not block execution.

Authority is not the same as technique. A human technique evaluator may be advisory (for quality review after the fact) while a deterministic evaluator may be blocking (for structural invariants). Technique describes the method; evaluation basis describes the reference; epistemic status describes how trusted the verdict is; authority describes the gate effect.

Deployment and autonomy positions

The four serialized autonomy positions are manual, hitl, hotl, and autonomous. These are the only values accepted by initial_position and the transition fields. Manual is the first on-spectrum position, not an off-spectrum or unmanaged state. See Evaluators and the recorded spectrum-entry decision.

The three deployment modes are active, shadow, and disabled, and the field is required on every declaration. Deployment is independent of initial_position: a declaration may be shadow-deployed (executing candidate automation and evaluation and recording evidence, but its candidate effect does not take effect) while also declaring hitl as its initial_position. Shadow is a deployment mode, not an autonomy position or an evaluator authority.

Position policy (placement)

position_policy is a top-level task field, not an evaluator field. It maps one or more autonomy positions to a placement value, answering when evaluation occurs relative to the governed effect:

  • blocking: gates at the declared position run before the governed effect executes.
  • async: gates at the declared position run after execution, before the next cycle.
  • offline: evaluation happens in batch or aggregate, not per-execution.

The keys are autonomy positions (manual, hitl, hotl, autonomous). At least one key is required. The initial_position and every position referenced by promotion or demotion must be declared; other positions may be omitted. Placement is not owned by any individual evaluator and is not the same as evaluator authority. Authority answers whether a given evaluator's verdict can halt the effect, not when it runs. See Evaluator placement for the full distinction.

Per-evaluator placement overrides

A position's value may be a single placement, which applies to every declared evaluator, or an object declaring a default placement plus explicit overrides. Both forms are conformant; the single value is the common case.

Overrides exist because one position genuinely needs two placements at once. HOTL is defined by taking the human out of the synchronous path while the machine evaluators stay exactly where they were. A single value for the whole position cannot say that: declaring hotl: async also moves the deterministic invariants after the effect, so the task loses its machine gates at precisely the position where the human supervisor was removed. outbound_content_publish below is the worked example.

Each override names a selector and a placement. The selector identifies one declared evaluator by property and technique, with an optional version. Both identity fields are required because a task may declare two evaluators asserting the same property, as in the maturity-curve case, and those two are exactly the pair a declaration will want to place differently.

Semantic validation rejects a selector that matches no declared evaluator (placement.override_matches_no_evaluator), one that matches more than one (placement.override_ambiguous, resolved by adding version), two overrides at one position selecting the same evaluator (placement.override_duplicate, which compares the evaluator each selector resolves to, so a versionless selector and one naming that evaluator's version are a duplicate pair), and an override whose placement merely repeats the position's default (placement.override_redundant). The last is an error rather than a no-op so that every override in a declaration is doing visible work.

What the policy draws

refund_approval declares all four positions, and both of its evaluators hold authority: blocking. The figures below read that one declaration at manual, hitl, and hotl.

The two axes stay independent in the drawing. Placement decides the line a station sits on; authority at that placement decides its shape. A diamond can halt the effect, a hexagon records a verdict and nothing more, and circles are the stage boundaries (input, process, output, outcome) where observation branches off the critical path.

refund_approval at the manual position refund_request: Boundary refund_request decision: Boundary decision refund_approval: Task refund_approval output: Checkpoint output refund_policy_invariants: Evaluator refund_policy_invariants should_escalate: Evaluator should_escalate
manual: offline. A human performs the work, so both evaluators score in batch off the critical path. No machine verdict gates anything.
Declared payload, 2 evaluators at manual
Version
1
Deployment
active
Initial position
hitl
Drawn at
manual
Scopes
Not provided
refund_approval evaluators at manual
Station Role PropertyStageTechniqueBasisEpistemic statusAuthorityPlacementCan halt the effectVersion
refund_policy_invariants Observer refund_policy_invariantsoutputdeterministicinvariant: refund_policy_invariantsground_truthblockingofflineno1
should_escalate Observer should_escalateoutputclassifierreference_label: should_escalate_reference_labelground_truthblockingofflineno1
refund_approval at the HITL position refund_request: Boundary refund_request decision: Boundary decision refund_approval: Task refund_approval output: Checkpoint output refund_policy_invariants: Gate refund_policy_invariants should_escalate: Gate should_escalate
hitl: blocking. Both evaluators are gates, in series, on the path the artifact travels. The only position where a machine verdict can stop the effect.
Declared payload, 2 evaluators at hitl
Version
1
Deployment
active
Initial position
hitl
Drawn at
hitl
Scopes
Not provided
refund_approval evaluators at hitl
Station Role PropertyStageTechniqueBasisEpistemic statusAuthorityPlacementCan halt the effectVersion
refund_policy_invariants Gate refund_policy_invariantsoutputdeterministicinvariant: refund_policy_invariantsground_truthblockingblockingyes1
should_escalate Gate should_escalateoutputclassifierreference_label: should_escalate_reference_labelground_truthblockingblockingyes1
refund_approval at the HOTL position refund_request: Boundary refund_request decision: Boundary decision refund_approval: Task refund_approval output: Checkpoint output refund_policy_invariants: Evaluator refund_policy_invariants should_escalate: Evaluator should_escalate
hotl: async. The same two evaluators, still declared blocking, run after the effect. Authority with nothing left to stop is observation: the diamonds become hexagons and step off the line.
Declared payload, 2 evaluators at hotl
Version
1
Deployment
active
Initial position
hitl
Drawn at
hotl
Scopes
Not provided
refund_approval evaluators at hotl
Station Role PropertyStageTechniqueBasisEpistemic statusAuthorityPlacementCan halt the effectVersion
refund_policy_invariants Observer refund_policy_invariantsoutputdeterministicinvariant: refund_policy_invariantsground_truthblockingasyncno1
should_escalate Observer should_escalateoutputclassifierreference_label: should_escalate_reference_labelground_truthblockingasyncno1

Between hitl and hotl the critical path empties. That is the cost the declaration makes explicit: the move buys throughput by giving up the ability to halt, and promotion.window is the evidence that has to justify it.

A map is a function of placement, not of position. Position enters only by selecting one. autonomous: offline therefore draws manual's map exactly, and for the opposite reason: under manual nothing machine-side gates because a human performs the work, and under autonomous nothing gates because nothing is meant to.

Typed windows

Both promotion.window and demotion.window use the same discriminated window type. The kind key determines the required type of size:

  • kind: cases: size must be a positive integer (minimum 1). Example: { kind: cases, size: 200 }.
  • kind: duration: size must be a non-empty ISO 8601 duration string. Example: { kind: duration, size: P14D }.

The schema enforces these types structurally. A window with kind: cases and a string size is rejected; a window with kind: duration and an integer size is rejected.

Promotion and demotion transitions

A declaration version governs exactly one promotion edge and one demotion edge. The contract is an edge declaration, not a complete transition graph. To govern a later edge, publish a successor declaration version with that edge's policy and establish position independently under the successor.

Promotion requires from, to, report, window, and execution:

  • from and to are autonomy positions.
  • report is a non-empty string naming the required promotion report.
  • window is a typed window (cases or duration).
  • execution is operator_approval or automatic. A passing window against the declared report produces eligibility only. eligibility is a decision-artifact outcome (eligible or ineligible), not a position change. Actual movement requires a motion that resolves via the declared execution mode: an explicit operator approval or an automatic execution. Position and motion status are both projections over the append-only autonomy-event stream. See Autonomy Events.

Demotion requires from, to, trigger, and window:

  • from and to are autonomy positions.
  • trigger is a non-empty string naming the demotion condition.
  • window is a typed window. A kind: cases, size: 1 window makes demotion immediate on one confirmed failure, which is intentional for high-stakes tasks.

Demotion is intentionally asymmetric: a policy failure can require downward movement, and an operator may initiate a demotion motion immediately without waiting for a metric to cross the window. Demotion is not automatic-only, and its window models the observation period for the trigger condition. It is not a delay before demotion fires.

Evidence Records

PAA Evidence Record (paa-evidence-record/0.1.0-draft) : Universal runtime envelope for one evaluator's verdict on one subject, produced against a PAA task declaration. Download paa-evidence-record.schema.json

There is no evidence_log key anywhere in the contract family. Evidence is a runtime record commitment, produced once per evaluator verdict per subject, not a declaration field. Every evidence record is required to identify: the exact task, declaration_version, and scope it was produced against; the subject (a case or run) it evaluates; boundary references to the observed input and, if produced, output; the complete producing evaluator identity (all seven fields, above); the verdict; producer id and version; timestamps (started, completed, recorded); source_references to the underlying rows or artifacts; and a payload_schema URI that types the task-specific payload.

Materially different declaration versions do not silently share a promotion window. declaration_version on every evidence record is what prevents a changed declaration from borrowing evidence collected under a prior contract. Recording evidence does not by itself make it admissible; admissibility is decided when a decision artifact is generated, below.

Compatibility is explicit, never inferred. Historical records remain attributable and auditable under the declaration version that produced them, but a successor declaration must collect its own promotion window. An operator may use prior records as context when approving a new motion; those records are not admissible evidence for the successor's declared window.

Decision Artifacts

PAA Decision Artifact (paa-decision-artifact/0.1.0-draft) : Immutable, capped admissibility snapshot backing one promotion or demotion decision for a PAA task. Download paa-decision-artifact.schema.json

A decision artifact is an immutable, capped admissibility snapshot backing one promotion or demotion decision. It carries the declared policy (the promotion report or demotion trigger identity and version) and observed window, plus the exact included_evidence and excluded_evidence references and reasons. Every excluded record names why it was excluded. Its decision.outcome is eligible or ineligible: producing an artifact is not itself a position change.

Each evidence reference in included_evidence and excluded_evidence carries an evidence_sha256 content hash, not "hash where available." A motion binds to a decision artifact's canonical bytes through evidence_ref and evidence_sha256 together, and approval fails closed on any hash loss or mismatch.

Autonomy Events

PAA Autonomy Event (paa-autonomy-event/0.1.0-draft) : One row of the append-only autonomy event stream: a motion proposal, its resolution, or the position change it authorized. Download paa-autonomy-event.schema.json

Every promotion or demotion is two or three append-only rows sharing one motion_id: motion_proposed, then either motion_approved or motion_rejected, and, only on approval, position_changed. Each row carries from_position, to_position, the evidence_ref and evidence_sha256 it is bound to, an actor, a reason, and a timestamp. A rule producing an eligible decision artifact does not itself fire a transition. It proposes a motion, and the motion's event sequence is what the position and motion status are projected from. There is no separate "position" field to read; current position and current motion status are both folds over this stream.

Human authorization and a human quality label are distinct records. One review action may produce both, but the permission to proceed (an autonomy_event) and the quality judgment (an evidence_record) are separate commitments.

Conformance fixtures

Four validated examples

These YAML fixtures are the positive conformance fixtures. Each passes npm run schema:check against the normative schema. The source is imported directly from examples/paa-tasks/, so displayed content is byte-identical to the validated files.

refund_approval

A two-evaluator declaration. refund_policy_invariants is a blocking deterministic evaluator with an invariant evaluation basis and ground_truth epistemic status, checking structural output invariants. should_escalate is a blocking classifier evaluator with a reference_label evaluation basis, also ground_truth. Deployment is active; initial position is hitl. Promotion window is 200 cases; demotion fires on one confirmed failure.

refund_approval.v1.yaml
task: refund_approval
version: 1
description: Evaluate a refund request and decide to approve or escalate for human review.

boundary:
  input: refund_request
  output: decision

initial_position: hitl
deployment: active

evaluators:
  - property: refund_policy_invariants
    target: output
    technique: deterministic
    evaluation_basis:
      kind: invariant
      ref: refund_policy_invariants
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

  - property: should_escalate
    target: output
    technique: classifier
    evaluation_basis:
      kind: reference_label
      ref: should_escalate_reference_label
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

position_policy:
  manual: offline
  hitl: blocking
  hotl: async
  autonomous: offline

promotion:
  from: hitl
  to: hotl
  report: refund_approval_promotion_report
  window:
    kind: cases
    size: 200
  execution: operator_approval

demotion:
  from: hotl
  to: hitl
  trigger: chargebacks_or_complaints_exceed_bound
  window:
    kind: cases
    size: 1

outbound_content_publish

A four-evaluator declaration illustrating the distinction between authorization and quality review:

  • outbound_content_invariants: blocking, deterministic, invariant evaluation basis. Structural output gate.
  • draft_quality: advisory, llm_judge, rubric evaluation basis, proxy epistemic status. Quality signal; does not block publication.
  • publish_authorization: blocking, human, human_gold evaluation basis, ground_truth epistemic status, process target. Synchronous human authorization required before publication proceeds at hitl.
  • publish_quality: advisory, human, human_gold evaluation basis, ground_truth epistemic status, outcome target. Asynchronous quality review after publication; does not authorize or block.

Deployment is active. author_rate is intentionally absent. rate limiting on the author is inbound-only and does not apply to outbound publication.

outbound_content_publish.v1.yaml
task: outbound_content_publish
version: 1
description: Publish a content revision to a configured external platform.

boundary:
  input: outbound_draft_revision
  output: publication

initial_position: hitl
deployment: active

scopes:
  - publish:bluesky
  - publish:farcaster

evaluators:
  - property: outbound_content_invariants
    target: output
    technique: deterministic
    evaluation_basis:
      kind: invariant
      ref: outbound_content_invariants
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

  - property: draft_quality
    target: output
    technique: llm_judge
    evaluation_basis:
      kind: rubric
      ref: draft_quality_rubric
    epistemic_status: proxy
    version: "1"
    authority: advisory

  - property: publish_authorization
    target: process
    technique: human
    evaluation_basis:
      kind: human_gold
      ref: publish_authorization_human_gold
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

  - property: publish_quality
    target: outcome
    technique: human
    evaluation_basis:
      kind: human_gold
      ref: publish_quality_human_gold
    epistemic_status: ground_truth
    version: "1"
    authority: advisory

position_policy:
  manual: offline
  hitl: blocking
  # At HOTL the human authorization gate becomes post-hoc review, while the
  # deterministic content invariants keep blocking before publication. A single
  # placement value for the whole position cannot express that.
  hotl:
    default: blocking
    overrides:
      - selector:
          property: publish_authorization
          technique: human
        placement: async
      - selector:
          property: publish_quality
          technique: human
        placement: async
  autonomous: offline

promotion:
  from: hitl
  to: hotl
  report: outbound_publish_promotion_report
  window:
    kind: cases
    size: 50
  execution: operator_approval

demotion:
  from: hotl
  to: hitl
  trigger: operator_decision_or_policy_failure
  window:
    kind: cases
    size: 1

Shadow deployment, not yet active at HITL. This declaration is deployment: shadow: it executes candidate evaluation and records evidence, but its candidate effect does not take effect. Both its response_quality evaluators (versions 1 and 2, below) are advisory. They collect quality evidence without authorizing surfacing. A concrete synchronous human authorization record and the runtime mechanism to enforce it must be declared and implemented before this task may be activated at hitl.

inbound_reply_surfacing

A four-evaluator declaration with a duration-typed promotion window, including two evaluators against the same response_quality property. The multiple- evaluators-per-property case described on Evaluators: version 1 is an llm_judge with a rubric evaluation basis and proxy epistemic status; version 2 is a human evaluator with a human_gold evaluation basis and ground_truth epistemic status. Both are advisory; neither authorizes admission to the surfaced-event flow, and version 2 does not overwrite version 1's evidence; both versions' records persist with their complete producing identity.

Promotion window is P14D (14 days, ISO 8601 duration), demonstrating the kind: duration window type.

inbound_reply_surfacing.v1.yaml
task: inbound_reply_surfacing
version: 1
description: Admit an evaluated inbound reply candidate into the surfaced-event and operator-digest flow.

boundary:
  input: inbound_candidate
  output: surfaced_event

initial_position: hitl
deployment: shadow

evaluators:
  - property: content_invariants
    target: output
    technique: deterministic
    evaluation_basis:
      kind: invariant
      ref: content_invariants
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

  - property: author_rate
    target: process
    technique: deterministic
    evaluation_basis:
      kind: invariant
      ref: author_rate
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

  - property: response_quality
    target: output
    technique: llm_judge
    evaluation_basis:
      kind: rubric
      ref: response_quality_rubric
    epistemic_status: proxy
    version: "1"
    authority: advisory

  - property: response_quality
    target: output
    technique: human
    evaluation_basis:
      kind: human_gold
      ref: response_quality_human_gold
    epistemic_status: ground_truth
    version: "2"
    authority: advisory

position_policy:
  manual: offline
  hitl: blocking
  hotl: async
  autonomous: offline

promotion:
  from: hitl
  to: hotl
  report: phase1_audit
  window:
    kind: duration
    size: P14D
  execution: operator_approval

demotion:
  from: hotl
  to: hitl
  trigger: operator_decision_or_policy_failure
  window:
    kind: cases
    size: 1

canonical_promotion

A two-evaluator declaration for approving candidate observations into a versioned canonical dossier. Deployment is disabled. This task exists in the declaration contract only and has no running implementation. Promotion execution is operator_approval, consistent with every example declaration here.

claim_admissibility is a blocking deterministic input-target evaluator with an invariant evaluation basis, checking structural constraints before review. canonical_truth is a blocking human output-target evaluator with a human_gold evaluation basis and ground_truth epistemic status. Expert judgment is required for every canonical inclusion decision.

canonical_promotion.v1.yaml
task: canonical_promotion
version: 1
description: Approve a candidate observation for inclusion in a versioned canonical dossier.

boundary:
  input: promotion_candidate
  output: approved_canonical_change

initial_position: hitl
deployment: disabled

evaluators:
  - property: claim_admissibility
    target: input
    technique: deterministic
    evaluation_basis:
      kind: invariant
      ref: claim_admissibility
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

  - property: canonical_truth
    target: output
    technique: human
    evaluation_basis:
      kind: human_gold
      ref: canonical_truth_human_gold
    epistemic_status: ground_truth
    version: "1"
    authority: blocking

position_policy:
  manual: offline
  hitl: blocking
  hotl: async
  autonomous: offline

promotion:
  from: hitl
  to: hotl
  report: canonical_promotion_report
  window:
    kind: cases
    size: 50
  execution: operator_approval

demotion:
  from: hotl
  to: hitl
  trigger: operator_decision_or_policy_failure
  window:
    kind: cases
    size: 1