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 withinputandoutput, both non-empty strings naming the typed observable unit. -
initial_position: one ofmanual,hitl,hotl,autonomous. The position before anyposition_changedevent exists, applied independently to every declared scope. -
deployment: one ofactive,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 ofinput,process,output,outcome. -
technique: one ofdeterministic,classifier,llm_judge,human. -
evaluation_basis: object withkind(one ofinvariant,reference_label,rubric,human_gold,downstream_result) andref, the name of the concrete invariant set, rubric, label set, human-gold protocol, or downstream measure. -
epistemic_status:proxyorground_truth. Whether this evaluator's verdict is an approximation of ground truth or ground truth itself. Independent of evaluation basis: a rubric-drivenllm_judgeis commonlyproxy;human_goldordinarily carriesground_truth, but neither mapping is enforced by the schema. -
version: non-empty string identifying this evaluator instance. Comparable evaluators may assert the samepropertywithout sharing technique, evaluation basis, epistemic status, version, or authority. -
authority:advisoryorblocking. No third value:shadowis 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.
Declared payload, 2 evaluators at manual
- Version
- 1
- Deployment
- active
- Initial position
- hitl
- Drawn at
- manual
- Scopes
- Not provided
| Station | Role | Property | Stage | Technique | Basis | Epistemic status | Authority | Placement | Can halt the effect | Version |
|---|---|---|---|---|---|---|---|---|---|---|
| refund_policy_invariants | Observer | refund_policy_invariants | output | deterministic | invariant: refund_policy_invariants | ground_truth | blocking | offline | no | 1 |
| should_escalate | Observer | should_escalate | output | classifier | reference_label: should_escalate_reference_label | ground_truth | blocking | offline | no | 1 |
Declared payload, 2 evaluators at hitl
- Version
- 1
- Deployment
- active
- Initial position
- hitl
- Drawn at
- hitl
- Scopes
- Not provided
| Station | Role | Property | Stage | Technique | Basis | Epistemic status | Authority | Placement | Can halt the effect | Version |
|---|---|---|---|---|---|---|---|---|---|---|
| refund_policy_invariants | Gate | refund_policy_invariants | output | deterministic | invariant: refund_policy_invariants | ground_truth | blocking | blocking | yes | 1 |
| should_escalate | Gate | should_escalate | output | classifier | reference_label: should_escalate_reference_label | ground_truth | blocking | blocking | yes | 1 |
Declared payload, 2 evaluators at hotl
- Version
- 1
- Deployment
- active
- Initial position
- hitl
- Drawn at
- hotl
- Scopes
- Not provided
| Station | Role | Property | Stage | Technique | Basis | Epistemic status | Authority | Placement | Can halt the effect | Version |
|---|---|---|---|---|---|---|---|---|---|---|
| refund_policy_invariants | Observer | refund_policy_invariants | output | deterministic | invariant: refund_policy_invariants | ground_truth | blocking | async | no | 1 |
| should_escalate | Observer | should_escalate | output | classifier | reference_label: should_escalate_reference_label | ground_truth | blocking | async | no | 1 |
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:sizemust be a positive integer (minimum 1). Example:{ kind: cases, size: 200 }. -
kind: duration:sizemust 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:
fromandtoare autonomy positions.reportis a non-empty string naming the required promotion report.windowis a typed window (cases or duration).-
executionisoperator_approvalorautomatic. A passing window against the declared report produces eligibility only. eligibility is a decision-artifact outcome (eligibleorineligible), not a position change. Actual movement requires amotionthat resolves via the declaredexecutionmode: 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:
fromandtoare autonomy positions.triggeris a non-empty string naming the demotion condition.-
windowis a typed window. Akind: cases, size: 1window 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.
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,invariantevaluation basis. Structural output gate. -
draft_quality: advisory, llm_judge,rubricevaluation basis,proxyepistemic status. Quality signal; does not block publication. -
publish_authorization: blocking, human,human_goldevaluation basis,ground_truthepistemic status, process target. Synchronous human authorization required before publication proceeds athitl. -
publish_quality: advisory, human,human_goldevaluation basis,ground_truthepistemic 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.
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.
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.
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