Files
Ansible/scripts/docs/TARGET_OUTCOMES.md
T
2026-09-22 19:23:17 +02:00

109 lines
4.2 KiB
Markdown

# AIM per-target final execution outcomes
**AIM 3.3.0rc8 / service API 1.0. Capability:** `target_outcome_summary_v1`.
Core's overall execution result remains authoritative and unchanged. An Ansible run
with one unreachable target still returns, for example, `status: failed`, execution
stage and the native nonzero exit code. The additive target summary answers a
different question: what final Ansible outcome did each **requested target** have?
## Result fields
Every `RunResult` now contains:
```json
{
"target_summary": {
"schema": "target_outcome_summary_v1",
"requested": 25,
"successful": 24,
"failed": 0,
"unreachable": 1,
"not_started": 0,
"indeterminate": 0,
"complete": true,
"accounted": 25
},
"targets": [
{
"host": "host01.example",
"outcome": "successful",
"counts": {
"ok": 38,
"changed": 0,
"failures": 0,
"unreachable": 0,
"skipped": 22,
"rescued": 0,
"ignored": 0
}
}
]
}
```
The `targets` list is in the reviewed request order. `accounted` always equals
`requested`. Capability discovery advertises the schema, state vocabulary and that
the data is available in both `summary` and `detail` progress modes.
## Outcome semantics
Core derives these states from Ansible's **final per-host stats callback**, not from
aggregate task counters or a client's interpretation of progress events:
- `unreachable`: final host stats contain one or more unreachable results.
- `failed`: no unreachable count, but final host stats contain unresolved failures.
- `successful`: final host stats were emitted for the requested host and contain
neither unresolved failures nor unreachable results. Changed/skipped/rescued/
ignored task counts do not by themselves make the host unsuccessful.
- `not_started`: a complete final stats set was received, but the requested host
had no final host stats; or execution ended before remote work could start.
- `indeterminate`: remote execution may have started but Core did not receive a
complete final stats set (for example cancellation, process loss or invalid
event stream). Core deliberately does not infer success from earlier task events.
If both failure and unreachable counters exist for one host, `unreachable` takes
precedence because the target did not remain reachable through the execution.
Per-target `counts` are task counters for diagnostics; the `outcome` field is the
Core-owned final classification.
This describes Ansible execution truth, not arbitrary application-level semantics.
A playbook that intentionally ignores a module error or reports a domain-specific
problem without failing remains subject to the playbook's own Ansible semantics.
## Overall status remains separate
A mixed run can therefore be represented as:
```text
Core RunResult: failed / execution / exit 4
Target facts: 24 successful, 1 unreachable
```
An interface may choose a presentation label such as `Partially succeeded`, but
that label is not a Core status and must not replace or hide the authoritative
Core result.
Pre-execution `ServiceError` responses remain errors rather than fake partial
success. When `execute` returns a `RunResult` before launch, targets are accounted
as `not_started` and `remote_work_may_have_started` remains false.
## Transport and safety
The native callback sends only target indexes and numeric recap counts through the
private event bridge. Public host names come from the already reviewed request,
not arbitrary callback payloads. No raw module output, variable data, credentials,
exception text or task result dictionaries are added.
Consumers should use this result instead of reconstructing final target outcomes
from `play_task_host_v1`. Detailed events remain useful for live presentation; the
final target summary is the authoritative end-state accounting.
## Report validation is a separate layer
A native exit 0 and successful target stats do not prove a required operation report
was published. 3.3.0rc8 can fail the Core result at result_validation while preserving
those native target facts and exit_code 0. See OPERATION_RESULTS.md. Do not convert a
missing report into fake target success, nor rewrite native counts to express a
report-contract error.