Readiness¶
readiness is a checklist a team fills in about its own service, such as "we
have a runbook" or "we load-tested it". Pacto turns it into a score and flags it
when the score is too low or the assessment has expired. The other sections
are in Contract sections,
Configuration and policy and
Dependencies and state.
readiness¶
Optional. A pactoVersion: "2.0" feature. Declares operational readiness
state for the service in a provider-neutral way. Each claim has a completion status,
optional category and weight. The assessment includes an expiry date and scoring
configuration. Pacto computes a readiness score from claim statuses and weights.
Readiness is a declared self-assessment: it records what the service's authors say they have done. Pacto checks the arithmetic and the expiry. The underlying work stays the authors' claim. Compliance is a separate verdict, decided from observed evidence about a running workload. The dashboard shows readiness on a revision and as a Needs attention category, and keeps it out of compliance verdicts.
readiness:
expires: "2027-06-30" # assessment-level expiry (YYYY-MM-DD)
minScore: 80 # gate: the derived score must be >= this (omitted ⇒ 100)
partialCredit: 0.5 # weight multiplier for partial claims (omitted ⇒ 0.5)
claims:
- id: dashboard
type: url
status: done
category: observability
weight: 20
evidence: https://grafana.example.com/d/service-dashboard
description: Main production dashboard
- id: runbook
type: document
status: partial
category: documentation
weight: 15
evidence: docs/runbook.md
description: Incident runbook exists but missing escalation procedures
- id: security-review
type: ticket
status: not-done
category: security
weight: 25
evidence: JIRA-1234
description: Security assessment pending
- id: legacy-cleanup
type: ticket
status: deferred
category: code-quality
weight: 10
evidence: TECH-5678
description: Post-launch cleanup task
history:
- date: "2026-12-15"
version: 1.0.0
author: alice
description: Initial readiness assessment
readiness.expires, readiness.claims[] and per-claim status are required when readiness
is present. readiness.minScore, readiness.partialCredit and readiness.history[] are optional.
readiness fields:
| Field | Type | Required | Constraints |
|---|---|---|---|
expires |
string | Yes | Assessment-level expiry as a strict YYYY-MM-DD date. If the current date is past this date, ALL claims earn 0 weight regardless of status. Parsing is exact round-trip: zero-padded fields required and the value must re-serialize unchanged, so 2026-1-1, RFC 3339 timestamps and impossible dates (for example 2026-02-30) are rejected. |
minScore |
integer | No | Gate threshold on the same 0–100 scale as the score. Omitted ⇒ 100 (every claim must be complete). Checked by pacto validate --readiness and the operator. |
partialCredit |
number | No | Multiplier for partial status claims (0.0–1.0). Omitted ⇒ 0.5 (half credit). |
claims |
Claim[] | Yes | At least one claim. |
history |
HistoryEntry[] | No | Audit trail of readiness assessment changes. |
Claim fields¶
| Field | Type | Required | Constraints |
|---|---|---|---|
id |
string | Yes | Stable readiness requirement id. Pattern: ^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$. Unique within the contract. Policies usually target this field. |
type |
string | Yes | Enum: url, document, ticket, report, artifact, identifier, other. Evidence type. |
status |
string | Yes | Enum: done, partial, not-done, deferred. Completion state for the claim. |
category |
string | No | Enum: architecture, testing, code-quality, observability, security, documentation, infrastructure, ci-cd, deployment, resilience, backup-recovery, incident-response, compliance, other. Categorizes the requirement type. |
weight |
integer | Yes | Contribution to the readiness score. Range 0–100. |
evidence |
string | Yes | Where the evidence lives: a URL, a bundle-relative file path, a ticket ID or any other string. Pacto checks only that it is non-empty. It never fetches the value, resolves a path or verifies that the target exists, so the evidence is your claim. interfaces[].ref and configurations[].schema, by contrast, must exist in the bundle. |
description |
string | No | Optional human-readable explanation (non-blank when present). |
History entry¶
| Field | Type | Required | Constraints |
|---|---|---|---|
date |
string | Yes | Date of the change as YYYY-MM-DD. |
version |
string | Yes | Contract version at the time of the change. Non-blank. |
author |
string | Yes | Person or system that made the change. Non-blank. |
description |
string | Yes | Description of what changed. |
The service owner is declared at the contract level, so readiness claims carry no
per-claim owner. Tooling computes the readiness score (pacto explain, the dashboard and the
operator) from claim statuses, weights, the assessment expiry and the current
time. The contract stores no score.
Readiness score and gate¶
If assessment is expired (today > readiness.expires):
score = 0
Otherwise:
earnedWeight = sum of earned weights for all in-scope claims
- deferred claims: excluded from both numerator and denominator
- done: full weight
- partial: round(weight × partialCredit)
- not-done: 0
totalWeight = sum of weights for all in-scope claims (excluding deferred)
score = round(earnedWeight / totalWeight × 100)
passing = score >= minScore # minScore defaults to 100
Worked example. Using the four claims from the example above (weights 20, 15, 25, 10):
legacy-cleanuphasstatus: deferred→ excluded from both numerator and denominator- In-scope weights:
20 + 15 + 25 = 60(total) dashboard(done, weight20) → earns20runbook(partial, weight15) → earnsround(15 × 0.5) = 8security-review(not-done, weight25) → earns0- Earned weight:
20 + 8 + 0 = 28 - Score:
round(28 / 60 × 100) = round(46.7) = 47
Weights are relative. The score normalizes by totalWeight, so only the
ratio of weights matters. A weight of 20 reads as "20%" only when the
weights sum to 100. Weights can sum to any value. When they sum to 100, each one
reads as a percentage. pacto explain and the dashboard show each claim's
normalized contribution.
The gate (minScore) is a readiness threshold. With minScore: 80 you
require 80% weighted completion, and a lower score fails the gate. Tooling
evaluates the gate separately from contract validity:
pacto explainshowsGate: PASS/FAIL (score N / minScore M).pacto validate --readiness(off by default) fails whenscore < minScore. It is opt-in because it depends on the current time, which would make plainvalidatenon-deterministic.- The operator sets
status.readiness.passingand theReadinessSatisfiedcondition from the same rule.
Because minScore is an authored literal, a policy can require
it org-wide, for example readiness.minScore >= 80. Presence rules live in
policies and the threshold lives here.
Requiring claims with policies¶
The base schema requires no specific claim. You express organizational standards
as policies using standard JSON Schema. For example, to
require a dashboard claim with status: done, category: observability and weight >= 20:
{
"type": "object",
"required": ["readiness"],
"properties": {
"readiness": {
"type": "object",
"required": ["claims"],
"properties": {
"claims": {
"type": "array",
"contains": {
"type": "object",
"required": ["id", "status", "category", "weight"],
"properties": {
"id": { "const": "dashboard" },
"status": { "const": "done" },
"category": { "const": "observability" },
"weight": { "minimum": 20 }
}
}
}
}
}
}
}
Combine multiple contains under allOf to require several claims (for example
dashboard, runbook and security-review). JSON Schema cannot express some
constraints, such as "total weight must equal 100", and Pacto has no other
policy engine for them yet.