{
"$schema": "https://json-schema.org/draft-07/schema",
"batch_payload": {
"$defs": {
"AlreadyPresent": {
"description": "Advisory: the patch's content appears to already exist on the\ntarget. Never affects the verdict; q-port and the operator own\nthe exclusion decision.",
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/$defs/ContentPresence"
},
{
"type": "null"
}
],
"description": "Tier-2 tally: the post-image is (partly) present in the tree."
},
"identical": {
"anyOf": [
{
"$ref": "#/$defs/TargetMatch"
},
{
"type": "null"
}
],
"description": "Tier-1 hit: an identical patch landed on the target."
}
},
"type": "object"
},
"AlreadyPresentSkipped": {
"description": "Why already-present detection could not run. Emitted instead of\nsilence: an invisible skip would read as \"not present\".",
"oneOf": [
{
"description": "The candidate commit object is absent from the target object\nstore (an unfetched branch, usually).",
"properties": {
"reason": {
"const": "candidate_missing_from_target_odb",
"type": "string"
},
"sha": {
"type": "string"
}
},
"required": [
"reason",
"sha"
],
"type": "object"
},
{
"description": "The candidate and the target tip share no history.",
"properties": {
"reason": {
"const": "no_merge_base",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "The target-side walk failed (shallow clone, corrupt object).",
"properties": {
"detail": {
"type": "string"
},
"reason": {
"const": "target_walk_failed",
"type": "string"
}
},
"required": [
"reason",
"detail"
],
"type": "object"
}
]
},
"ApplyConflictKind": {
"description": "The apply outcomes a divergence predictor consumes, ordered by\nseverity: a higher variant outranks a lower one on the same path, so\ndedup to one conflict per path is a `max`.",
"enum": [
"postimage_collision",
"preimage_missing",
"file_absent"
],
"type": "string"
},
"ApplyForecast": {
"description": "Per-path apply prediction for one `(commit, series)` row, computed\nfrom the target tree. Present exactly when a target context was\nsupplied.",
"properties": {
"paths": {
"additionalProperties": {
"$ref": "#/$defs/PathApplyOutcome"
},
"description": "Every assessed touched path, including ones absent on the\ntarget (`Conflict { FileAbsent }`).",
"type": "object"
}
},
"required": [
"paths"
],
"type": "object"
},
"ArgShape": {
"oneOf": [
{
"description": "Variable identifier (starts with `_` or capital letter).",
"properties": {
"kind": {
"const": "variable",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Atom literal: `foo`, `'quoted atom'`.",
"properties": {
"kind": {
"const": "atom",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"description": "Integer literal.",
"properties": {
"kind": {
"const": "integer",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Float literal.",
"properties": {
"kind": {
"const": "float",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Binary literal: `<<...>>`.",
"properties": {
"kind": {
"const": "binary",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "List literal: `[...]`.",
"properties": {
"kind": {
"const": "list",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Tuple literal: `{...}` (size is the number of elements).",
"properties": {
"kind": {
"const": "tuple",
"type": "string"
},
"size": {
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"kind",
"size"
],
"type": "object"
},
{
"description": "Record reference: `#name{...}`.",
"properties": {
"kind": {
"const": "record",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"description": "String literal: `\"...\"`.",
"properties": {
"kind": {
"const": "string",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Anonymous fun: `fun ... end` or `fun mod:f/A`.",
"properties": {
"kind": {
"const": "fun",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Anything the extractor cannot classify. Always matches.",
"properties": {
"kind": {
"const": "unknown",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
}
]
},
"ArtifactKind": {
"oneOf": [
{
"description": "`<<<<<<<`, `=======`, `>>>>>>>`, or `||||||| ` marker present in a\ntouched file. The cherry-pick driver left a conflict unresolved.",
"properties": {
"artifact_kind": {
"const": "conflict_marker",
"type": "string"
},
"marker": {
"$ref": "#/$defs/ConflictMarker"
}
},
"required": [
"artifact_kind",
"marker"
],
"type": "object"
},
{
"description": "`-export([f/N])` line without a matching clause defining `f/N`.\nCompiles, then crashes at runtime on the first call.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"artifact_kind": {
"const": "export_without_body",
"type": "string"
},
"function": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"artifact_kind",
"module",
"function",
"arity"
],
"type": "object"
}
]
},
"BatchQuery": {
"description": "One series queried by the batch. Holds the pin set used during\nevaluation so consumers can correlate per-row results.",
"properties": {
"pins": {
"items": {
"$ref": "#/$defs/PinPayload"
},
"type": "array"
},
"series": {
"type": "string"
}
},
"required": [
"series",
"pins"
],
"type": "object"
},
"BatchResult": {
"description": "One row in the batch result set.",
"properties": {
"apply": {
"anyOf": [
{
"$ref": "#/$defs/ApplyForecast"
},
{
"type": "null"
}
],
"description": "Apply-axis prediction for this row. `None` means no target\ncontext was supplied, so the axis was not evaluated: never\n\"clean\". A producer with a target context always emits `Some`,\neven when the patch touched zero files."
},
"commit": {
"type": "string"
},
"diagnostics": {
"$ref": "#/$defs/Diagnostics"
},
"parent_count": {
"default": null,
"description": "Number of parents of the evaluated commit: 1 for plain\ncommits, 2 for PR merges, 3+ for octopus merges. `None` only\nwhen the envelope was produced by a pre-v7 binary; v7\nproducers always emit it.",
"format": "uint32",
"minimum": 1,
"type": [
"integer",
"null"
]
},
"patch_facts": {
"$ref": "#/$defs/PatchFacts"
},
"pr_commits": {
"default": null,
"description": "Inner PR-branch commits for 2-parent merge SHAs. `None` for\nnon-2-parent merges and non-merge SHAs.\n\nDo NOT add `skip_serializing_if = \"Option::is_none\"`. The\n`None` vs `Some(vec![])` distinction is part of the wire contract.",
"items": {
"$ref": "#/$defs/PrCommit"
},
"type": [
"array",
"null"
]
},
"series": {
"type": "string"
},
"target_findings": {
"anyOf": [
{
"$ref": "#/$defs/TargetFindings"
},
{
"type": "null"
}
],
"description": "Symbol-axis target findings for this row. `None` means no\ntarget context was supplied, so the axis was not evaluated:\nnever \"clean\". A producer with a target context always emits\n`Some`, even when no check produced a finding."
},
"touched_paths": {
"default": [],
"description": "Paths the analysed patch touched, in diff-encounter order.\nAlways emitted; an empty vec means the patch touched zero\nfiles.",
"items": {
"type": "string"
},
"type": "array"
},
"verdict": {
"$ref": "#/$defs/SeriesVerdict"
},
"verdict_fingerprint": {
"anyOf": [
{
"$ref": "#/$defs/VerdictFingerprint"
},
{
"type": "null"
}
],
"description": "Stable join key tying this row's verdict to a later build\noutcome. Absent for uncacheable rows (`--no-cache`, an\nunresolvable pin) and pre-fingerprint producers."
}
},
"required": [
"commit",
"series",
"verdict"
],
"type": "object"
},
"BumpStatus": {
"description": "Snapshot-store status of a bumped-to pin version.",
"oneOf": [
{
"description": "The bumped dep is not a tracked project; nothing to vet.",
"properties": {
"state": {
"const": "untracked",
"type": "string"
}
},
"required": [
"state"
],
"type": "object"
},
{
"description": "No snapshot for the bumped-to version; `note` carries the remedy.",
"properties": {
"note": {
"type": "string"
},
"state": {
"const": "snapshot_missing",
"type": "string"
}
},
"required": [
"state",
"note"
],
"type": "object"
},
{
"properties": {
"state": {
"const": "snapshot_present",
"type": "string"
}
},
"required": [
"state"
],
"type": "object"
}
]
},
"ConflictMarker": {
"oneOf": [
{
"const": "ours",
"description": "`<<<<<<<` line: start of the local side.",
"type": "string"
},
{
"const": "divider",
"description": "`=======` line: divider between sides.",
"type": "string"
},
{
"const": "theirs",
"description": "`>>>>>>>` line: end of the incoming side.",
"type": "string"
},
{
"const": "ancestor",
"description": "`||||||| ` line: base ancestor marker from a 3-way diff.",
"type": "string"
}
]
},
"ContentPresence": {
"description": "Tier-2 advisory: how much of the patch's post-image already exists\nin the named pin's tree. A tally, never a boolean: partial presence\nis common and the fraction is the signal.",
"properties": {
"hunks_already_applied": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"hunks_ambiguous": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"hunks_considered": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"hunks_low_confidence": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"per_file": {
"additionalProperties": {
"$ref": "#/$defs/HunkTally"
},
"type": "object"
},
"pin": {
"description": "The pin whose evaluation produced the tally. In cross-branch\nmode the self pin resolves to the target branch, so its tally\nis the target-tree answer.",
"type": "string"
}
},
"required": [
"pin",
"hunks_already_applied",
"hunks_considered",
"hunks_ambiguous",
"hunks_low_confidence"
],
"type": "object"
},
"DepPinDivergence": {
"description": "A dependency whose `rabbitmq-components.mk` pin differs between\nthe source commit's tree and the target tree, and that an app\ntouched by the patch (transitively) depends on. Advisory only.",
"properties": {
"dep": {
"type": "string"
},
"source": {
"description": "Pin at the source commit, e.g. `hex 2.16.0`.",
"type": "string"
},
"target": {
"description": "Pin at the target tree, e.g. `hex 2.13.0`.",
"type": "string"
}
},
"required": [
"dep",
"source",
"target"
],
"type": "object"
},
"DetectorName": {
"description": "A family-declared detector this run's dormancy list can name.",
"enum": [
"dep_behaviour_conformance",
"option_key_drift",
"macro_undefined_on_target",
"suite_not_registered_for_ct",
"schema_feature_unsupported_on_pin",
"schema_key_reader_missing"
],
"type": "string"
},
"Diagnostics": {
"description": "Series-wide diagnostic envelope. Strictly separate from `Verdict`\nso untracked-call signals never leak into machine-readable verdicts.",
"properties": {
"already_present": {
"anyOf": [
{
"$ref": "#/$defs/AlreadyPresent"
},
{
"type": "null"
}
],
"description": "Advisory: the patch's content appears to already exist on the\ntarget (tier-1 identical patch, tier-2 content tally, or both)."
},
"already_present_skipped": {
"anyOf": [
{
"$ref": "#/$defs/AlreadyPresentSkipped"
},
{
"type": "null"
}
],
"description": "Why already-present detection was skipped, when it was."
},
"context_refs_missing": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "In-scope references on *context* lines that do not resolve at\nsome pin, per module. Pre-existing target facts: never reasons.",
"type": "object"
},
"dep_pin_divergence": {
"description": "Dep pins that diverge between source and target trees and are\nreachable from the apps this patch touches.",
"items": {
"$ref": "#/$defs/DepPinDivergence"
},
"type": "array"
},
"dormant_detectors": {
"description": "Family-declared detectors that did not run this evaluation,\nwith the input whose absence disabled each. Gated on the\nfamily actually declaring the relevant vocabulary, so a\ngeneric project's runs carry an empty list. Silence must be\ndistinguishable from absence of findings.",
"items": {
"$ref": "#/$defs/DormantDetector"
},
"type": "array"
},
"indirect_call_checks": {
"$ref": "#/$defs/IndirectCallTally",
"description": "What the indirect-reference check (meck expectations and rpc\nforms) did with each recognized occurrence: resolved against the\ntarget module, or seen with an unreadable arity and withheld."
},
"local_call_shape_checks": {
"$ref": "#/$defs/ShapeCheckTally",
"description": "The same tally for local calls: resolved unqualified calls, compared or\nwithheld. Kept apart from the qualified tally so one axis's\ncoverage never reads as the other's."
},
"macro_value_checks": {
"$ref": "#/$defs/MacroValueTally",
"description": "Same-file `-define` value comparisons over macros the patch\nuses: compared, or withheld and why."
},
"missing_test_modules": {
"additionalProperties": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"type": "object"
},
"description": "Per-`_SUITE.erl` map of `helper_module -> call_site_count`. The\nalways-on diagnostic form of\n`Reason::TestModuleSymbolMissing`: emitted by the parse pass\neven without a target tree (which is why the inner key is the\n`ModuleName` rather than a resolved-or-not bit). When\n`--target-repo-dir-path` is supplied the resolver re-checks this\nmap and promotes the absent ones to typed reasons. The nested\n`BTreeMap` shape keeps the JSON envelope serialisable without\na custom composite-key encoder.",
"type": "object"
},
"pin_bumps": {
"description": "Dep pins this patch itself changes or introduces in the root\n`rabbitmq-components.mk`.",
"items": {
"$ref": "#/$defs/PinBump"
},
"type": "array"
},
"qualified_call_shape_checks": {
"$ref": "#/$defs/ShapeCheckTally",
"description": "What the live qualified-call gate's return-shape check did with\neach first-party resolved call: compared, or withheld and why."
},
"suggested_suites": {
"description": "SUITE names worth running for the patch, derived from touched paths.\nPopulated even when the verdict promotes to `Inapplicable` so that\nschema-only and config-only diffs still surface relevant suites.",
"items": {
"type": "string"
},
"type": "array"
},
"unanalyzed": {
"$ref": "#/$defs/Unanalyzed"
},
"unattributed_paths": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "Touched paths no configured project owns, tallied by their\nfirst two path components. The evidence behind an\n`Inapplicable { Untracked }` verdict.",
"type": "object"
},
"untracked_calls": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"type": "object"
},
"untracked_records": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"type": "object"
}
},
"type": "object"
},
"DormantDetector": {
"description": "One family-declared detector that a run could not exercise, and\nwhich input's absence disabled it.",
"properties": {
"detector": {
"$ref": "#/$defs/DetectorName"
},
"missing_input": {
"$ref": "#/$defs/MissingInput"
}
},
"required": [
"detector",
"missing_input"
],
"type": "object"
},
"DriftEvidence": {
"description": "How a dependency-behaviour drift finding was established. Wire-visible\nso consumers can weigh confidence: a set-difference finding is exact,\na name-anchored one is heuristic.",
"oneOf": [
{
"const": "source_side_set_difference",
"description": "Present in the source pin's callback set, absent from the\ntarget pin's.",
"type": "string"
},
{
"const": "name_anchored",
"description": "Callback-name collision at an undeclared arity, with no source\npin to confirm it.",
"type": "string"
}
]
},
"FileLoggingStyle": {
"properties": {
"dominant": {
"$ref": "#/$defs/LoggingStyle"
},
"logger_macro_sites": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"rabbit_log_sites": {
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"dominant",
"logger_macro_sites",
"rabbit_log_sites"
],
"type": "object"
},
"HunkTally": {
"description": "Per-file hunk counters for the content-presence check.",
"properties": {
"ambiguous": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"applied": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"considered": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"low_confidence": {
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"applied",
"considered",
"ambiguous",
"low_confidence"
],
"type": "object"
},
"InapplicableReason": {
"oneOf": [
{
"properties": {
"reason": {
"const": "no_erlang_surface_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_docs_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_test_fixtures_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_schema_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_makefile_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_mix_exs_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_ci_workflow_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_app_src_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_rebar_config_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "Every changed `.erl` hunk is a Variant A unwrap: dropping\n`-ifdef(TEST).` or `-endif.` around an `-export(...)` directive,\nor rewriting `-compile(export_all).` to an explicit\n`-export([...])`. No call sites, no specs, no bodies touched:\nonly test-visibility metadata.",
"properties": {
"reason": {
"const": "only_test_visibility_changed",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "The patch touches Erlang surface but every referenced symbol\nresolves to the self-pin or to a local definition: every\ntracked-dep pin has zero in-scope references. Without this\nreason the operator would see many vacuous `Compatible`\nrows for a patch that backhopper genuinely has no signal on.",
"properties": {
"reason": {
"const": "only_self_surface_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "Every touched path is in a sibling project's scope, not this\npin's. The pin has nothing to say about the patch. `project`\nnames the first sibling project (alphabetical) that owns the\nout-of-scope paths.",
"properties": {
"project": {
"type": "string"
},
"reason": {
"const": "out_of_scope_for",
"type": "string"
}
},
"required": [
"reason",
"project"
],
"type": "object"
},
{
"description": "Every touched path is unclaimed by any configured project's\nscan_paths or app_roots. Vendored files, docs, build scripts.",
"properties": {
"reason": {
"const": "untracked",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "`--target-repo-dir-path` was supplied and every touched path\nis missing from the target tree, with no configured\ntranslation mapping any of them. The patch as written does\nnot apply to the target.",
"properties": {
"paths": {
"items": {
"type": "string"
},
"type": "array"
},
"reason": {
"const": "paths_missing_on_target",
"type": "string"
}
},
"required": [
"reason",
"paths"
],
"type": "object"
}
]
},
"IncludeDirective": {
"description": "`-include` and `-include_lib` are syntactically distinct: the\nformer takes a relative-to-source path, the latter an\n`application/include/file.hrl` shape resolved through OTP's lib\npath. The variant preserves which form the source used so the\nremediation text can match.",
"oneOf": [
{
"properties": {
"form": {
"const": "include",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"form",
"path"
],
"type": "object"
},
{
"properties": {
"form": {
"const": "include_lib",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"form",
"path"
],
"type": "object"
}
]
},
"IndirectCallForm": {
"description": "Which recognized call form carried an indirect MFA reference. Names\nthe innermost form: a meck expectation reached through an rpc helper\nis `MeckExpect`, not the helper.",
"enum": [
"meck_expect",
"rpc_call",
"erpc_call",
"ct_broker_helper_rpc",
"rabbit_misc_rpc_call"
],
"type": "string"
},
"IndirectCallTally": {
"description": "What the indirect-reference check did with each recognized form\noccurrence. `checked` counts deduplicated resolved sites, the same\ndedup the reasons use; flagged sites are visible in the reasons,\nnot double-counted here.",
"properties": {
"checked": {
"description": "Module first-party, export and definition sets readable: the\nmembership check ran.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_dynamic": {
"description": "Module and function were literal atoms but the arity source was\nnot statically readable: a variable argument list, a list with a\ncons tail, or a non-literal arity argument.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"KhepriSignals": {
"properties": {
"touches_dual_branch": {
"default": false,
"type": "boolean"
},
"touches_khepri_module": {
"default": false,
"type": "boolean"
},
"touches_only_khepri_branch": {
"default": false,
"type": "boolean"
},
"uses_khepri_macros": {
"default": false,
"type": "boolean"
}
},
"type": "object"
},
"LoggingStyle": {
"enum": [
"logger_macros",
"rabbit_log_module",
"mixed",
"none"
],
"type": "string"
},
"MacroValueTally": {
"description": "What the macro-value check did with each `?MACRO` the patch uses:\ncompared, or withheld and why. Same-file `-define`s only; anything\nreached another way is withheld, never guessed.",
"properties": {
"compared": {
"description": "Defined exactly once same-file on both sides; values compared.\nDrift is visible in the reasons, not double-counted here.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_definition_elsewhere": {
"description": "Not defined same-file on both sides: the definition is in an\ninclude, or moved between files across the trees.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_multiple_defines": {
"description": "Defined more than once in the file on either side (`-ifdef`\nbranches): either value could be live.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_no_source": {
"description": "The touched file was not readable on the source side.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"Mfa": {
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"module",
"function",
"arity"
],
"type": "object"
},
"MissingInput": {
"description": "The gating input whose absence left a detector dormant.",
"enum": [
"target_repo_dir_path",
"source_pin",
"cuttlefish_pin"
],
"type": "string"
},
"NeedsPin": {
"description": "The minimum pin that satisfies a missing-symbol reason: the typed\nordering payload q-port turns into a \"bump must land first\" edge.",
"properties": {
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"project",
"tag"
],
"type": "object"
},
"PatchFacts": {
"description": "Source classifiers on the patch. Strictly separate from `Verdict` reasons.",
"properties": {
"introduces_versioned_record": {
"items": {
"type": "string"
},
"type": "array",
"uniqueItems": true
},
"khepri_signals": {
"$ref": "#/$defs/KhepriSignals"
},
"logging_style": {
"additionalProperties": {
"$ref": "#/$defs/FileLoggingStyle"
},
"type": "object"
}
},
"type": "object"
},
"PathApplyOutcome": {
"description": "How one touched path is predicted to apply to the target tree.\nRanked by [`PathApplyOutcome::severity`]; payload-carrying variants\nkeep the enum out of `Ord`.",
"oneOf": [
{
"description": "Every hunk's preimage matches at its expected line.",
"properties": {
"outcome": {
"const": "clean_exact",
"type": "string"
}
},
"required": [
"outcome"
],
"type": "object"
},
{
"description": "Applies, but at least one hunk's preimage was found at a shifted\nline. `line_delta` is the largest-magnitude shift.",
"properties": {
"line_delta": {
"format": "int64",
"type": "integer"
},
"outcome": {
"const": "clean_drifted",
"type": "string"
}
},
"required": [
"outcome",
"line_delta"
],
"type": "object"
},
{
"description": "The path could not be assessed; stated, never silent.",
"properties": {
"outcome": {
"const": "unassessed",
"type": "string"
},
"reason": {
"$ref": "#/$defs/UnassessedReason"
}
},
"required": [
"outcome",
"reason"
],
"type": "object"
},
{
"description": "At least one hunk predicts a conflict. `kind` is the worst\nconflict kind across the path's hunks.",
"properties": {
"kind": {
"$ref": "#/$defs/ApplyConflictKind"
},
"outcome": {
"const": "conflict",
"type": "string"
}
},
"required": [
"outcome",
"kind"
],
"type": "object"
}
]
},
"Pin": {
"properties": {
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"project",
"tag"
],
"type": "object"
},
"PinBump": {
"description": "A dep pin the candidate commit itself changes or introduces in the\nroot `rabbitmq-components.mk`. Advisory only: the verdict on a\nbump-only diff stays `Inapplicable`, this is the evidence behind it.",
"properties": {
"dep": {
"type": "string"
},
"from": {
"description": "Pin before the commit, e.g. `hex 2.16.0`; `None` when the\ncommit introduces the pin.",
"type": [
"string",
"null"
]
},
"status": {
"anyOf": [
{
"$ref": "#/$defs/BumpStatus"
},
{
"type": "null"
}
],
"description": "Snapshot-store assessment of the bumped-to version. Detection\nis a pure function of the patch and may be cached; the store's\ncontents are not a cache-key input, so this field is filled\npost-cache and cached values carry `None`."
},
"to": {
"description": "Pin after the commit, e.g. `hex 2.17.1`.",
"type": "string"
}
},
"required": [
"dep",
"to"
],
"type": "object"
},
"PinPayload": {
"description": "On-wire pin shape used inside `BatchQuery`. Distinct from\n`crate::model::pin::Pin` because the wire form is a `(project, tag)`\nprojection without the resolution logic.",
"properties": {
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"project",
"tag"
],
"type": "object"
},
"PinVerdict": {
"properties": {
"pin": {
"$ref": "#/$defs/Pin"
},
"source_delta_details": {
"items": {
"$ref": "#/$defs/SourceDelta"
},
"type": "array"
},
"touched": {
"$ref": "#/$defs/TouchedKinds"
},
"tracked_ref_details": {
"items": {
"$ref": "#/$defs/SymbolRef"
},
"type": "array"
},
"tracked_refs": {
"default": 0,
"format": "uint",
"minimum": 0,
"type": "integer"
},
"verdict": {
"$ref": "#/$defs/Verdict"
}
},
"required": [
"pin",
"verdict"
],
"type": "object"
},
"PrCommit": {
"description": "One commit on the PR-branch side of a 2-parent merge.",
"properties": {
"author_date": {
"type": "string"
},
"kind": {
"$ref": "#/$defs/PrCommitKind"
},
"sha": {
"type": "string"
},
"subject": {
"type": "string"
}
},
"required": [
"sha",
"subject",
"author_date",
"kind"
],
"type": "object"
},
"PrCommitKind": {
"description": "Classification of a PR-branch commit's role.\n\n`#[non_exhaustive]` so future, richer taxonomies (test-only,\ndocs-only, dependency-bump, etc.) can add variants without a\nbreaking change.",
"oneOf": [
{
"const": "substantive",
"description": "Default: substantive change worth reviewing.",
"type": "string"
},
{
"const": "conflict_resolution",
"description": "Subject matched the conflict-resolution catalog AND the file\nset was a strict subset of prior PR-branch commits.",
"type": "string"
},
{
"const": "review_feedback",
"description": "Subject indicated the commit applied code-review feedback.",
"type": "string"
},
{
"const": "fixup",
"description": "`git --fixup` auto-generated or the manual `fixup:` convention.",
"type": "string"
},
{
"const": "wip_or_cleanup",
"description": "Subject was `WIP` or bare `Cleanup`.",
"type": "string"
}
]
},
"Reason": {
"oneOf": [
{
"properties": {
"first_seen_at_tag": {
"description": "Earliest snapshot tag strictly later than the pin where the\nsymbol appears. `Some` reclassifies the reason as\nadaptable: land the dep pin bump first.",
"type": [
"string",
"null"
]
},
"kind": {
"const": "missing_symbol",
"type": "string"
},
"needs_pin_at_least": {
"anyOf": [
{
"$ref": "#/$defs/NeedsPin"
},
{
"type": "null"
}
]
},
"suggested_replacement": {
"anyOf": [
{
"$ref": "#/$defs/SymbolRef"
},
{
"type": "null"
}
]
},
"symbol": {
"$ref": "#/$defs/SymbolRef"
}
},
"required": [
"kind",
"symbol"
],
"type": "object"
},
{
"properties": {
"expected": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"expected_available_at": {
"description": "Earliest snapshot tag strictly later than the pin exporting\nthe expected arity. Same bump-first semantics as\n`MissingSymbol::first_seen_at_tag`.",
"type": [
"string",
"null"
]
},
"found": {
"items": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"type": "array"
},
"function": {
"type": "string"
},
"kind": {
"const": "arity_changed",
"type": "string"
},
"module": {
"type": "string"
},
"needs_pin_at_least": {
"anyOf": [
{
"$ref": "#/$defs/NeedsPin"
},
{
"type": "null"
}
]
}
},
"required": [
"kind",
"module",
"function",
"expected",
"found"
],
"type": "object"
},
{
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"expected_spec": {
"type": "string"
},
"found_spec": {
"type": "string"
},
"function": {
"type": "string"
},
"kind": {
"const": "signature_changed",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function",
"arity",
"expected_spec",
"found_spec"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "file_absent",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "context_drift",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index"
],
"type": "object"
},
{
"description": "The contiguous preimage block (Context and Removed lines from\nthe hunk) was found verbatim at a different starting line.\nCherry-pick adapters handle this with the `-x` trailer; the\noperator just needs the delta to confirm the patch's intent\nstill applies.",
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "preimage_drifted",
"type": "string"
},
"line_delta": {
"format": "int",
"type": "integer"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index",
"line_delta"
],
"type": "object"
},
{
"description": "The hunk's preimage matches, but its added lines land at a file\nedge where the target already has divergent content the base\nlacked: an add/add a contiguous preimage match cannot detect. The\n3-way cherry-pick conflicts where the preimage-only check reads\nclean. Non-blocking: the operator resolves the overlap.",
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "postimage_collision",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index"
],
"type": "object"
},
{
"description": "The preimage block does not appear anywhere in the file. The\npatch was authored against a tree where the lines existed; on\nthis pin they don't. Structurally inapplicable: the operator\nneeds an excerpt to reason about why.",
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "preimage_missing",
"type": "string"
},
"path": {
"type": "string"
},
"preimage_excerpt": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index",
"preimage_excerpt"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "deprecated_usage",
"type": "string"
},
"replacement": {
"anyOf": [
{
"$ref": "#/$defs/SymbolRef"
},
{
"type": "null"
}
]
},
"since": {
"type": [
"string",
"null"
]
},
"symbol": {
"$ref": "#/$defs/SymbolRef"
}
},
"required": [
"kind",
"symbol"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "now_hidden",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module"
],
"type": "object"
},
{
"properties": {
"expected": {
"items": {
"type": "string"
},
"type": "array"
},
"found": {
"items": {
"type": "string"
},
"type": "array"
},
"kind": {
"const": "record_fields_changed",
"type": "string"
},
"record": {
"type": "string"
}
},
"required": [
"kind",
"record",
"expected",
"found"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "unsupported_file_type",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "untracked_module_missing",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module"
],
"type": "object"
},
{
"description": "Call-site argument shapes don't satisfy any clause head at the\npin. Emitted when both the call and the pin's clause patterns\nare concrete enough to compare; `Unknown` on either side\nsuppresses the reason.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"call_args": {
"items": {
"$ref": "#/$defs/ArgShape"
},
"type": "array"
},
"function": {
"type": "string"
},
"kind": {
"const": "clause_mismatch",
"type": "string"
},
"module": {
"type": "string"
},
"pin_clauses": {
"items": {
"items": {
"$ref": "#/$defs/ArgShape"
},
"type": "array"
},
"type": "array"
}
},
"required": [
"kind",
"module",
"function",
"arity",
"call_args",
"pin_clauses"
],
"type": "object"
},
{
"description": "Patch references an MFA owned by the self-project but absent from the\nresolved self-snapshot. `suggested_source_for_prereq` is filled only\nwith `--suggest-prereqs`.",
"properties": {
"kind": {
"const": "missing_prereq",
"type": "string"
},
"self_branch": {
"type": "string"
},
"suggested_source_for_prereq": {
"type": [
"string",
"null"
]
},
"symbol": {
"$ref": "#/$defs/SymbolRef"
}
},
"required": [
"kind",
"symbol",
"self_branch"
],
"type": "object"
},
{
"description": "Pre-flight syntactic damage in a touched file: an unresolved\nmerge-conflict marker, an exported function with no definition, etc.",
"properties": {
"artifact": {
"$ref": "#/$defs/ArtifactKind"
},
"kind": {
"const": "syntactic_artifact",
"type": "string"
},
"line": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"line",
"artifact"
],
"type": "object"
},
{
"description": "Patch changes a `-callback` signature; an implementer still has the old one.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"expected_after_patch": {
"type": "string"
},
"implementer": {
"type": "string"
},
"implementer_signature": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_signature_changed",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"expected_after_patch",
"implementer",
"implementer_signature"
],
"type": "object"
},
{
"description": "Patch removes a required callback; implementer still exports it.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_removed",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"implementer"
],
"type": "object"
},
{
"description": "Patch adds a required callback; implementer is missing the export.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_added",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"implementer"
],
"type": "object"
},
{
"description": "Patch touches a path absent on pin, but a module of the same basename exists elsewhere.",
"properties": {
"kind": {
"const": "module_relocated",
"type": "string"
},
"module": {
"type": "string"
},
"patch_path": {
"type": "string"
}
},
"required": [
"kind",
"module",
"patch_path"
],
"type": "object"
},
{
"description": "Wire-bearing macro value differs between source and pin.",
"properties": {
"after": {
"type": "string"
},
"before": {
"type": "string"
},
"kind": {
"const": "wire_constant_changed",
"type": "string"
},
"macro_name": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"macro_name",
"before",
"after"
],
"type": "object"
},
{
"description": "`version/0` advanced without the matching historical-implementation module.",
"properties": {
"advertised_version_after": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"advertised_version_before": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"expected_historical_module": {
"type": "string"
},
"kind": {
"const": "historical_implementation_missing",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"advertised_version_before",
"advertised_version_after",
"expected_historical_module"
],
"type": "object"
},
{
"description": "Function bodies drifted at the same advertised `version/0`. Mixed-version cluster risk.",
"properties": {
"advertised_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"functions": {
"items": {
"type": "string"
},
"type": "array"
},
"kind": {
"const": "wire_contract_body_drift",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"functions",
"advertised_version"
],
"type": "object"
},
{
"description": "`version/0` decreased pin → patch.",
"properties": {
"kind": {
"const": "wire_contract_regression",
"type": "string"
},
"module": {
"type": "string"
},
"patch_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"pin_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"kind",
"module",
"pin_version",
"patch_version"
],
"type": "object"
},
{
"description": "Spec return shape differs between source and pin for a referenced MFA.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "return_shape_mismatch",
"type": "string"
},
"module": {
"type": "string"
},
"pin_signature": {
"type": "string"
},
"source_signature": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function",
"arity",
"source_signature",
"pin_signature"
],
"type": "object"
},
{
"description": "A type-reference inside a `-spec`, `-callback`, `-type`, or\n`-opaque` attribute resolves to a name and arity that the pin\ndoes not expose via `-export_type`. Non-blocking: a missing\ntype alias is a dialyzer-level concern, not a load-time crash.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "missing_type",
"type": "string"
},
"module": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"module",
"name",
"arity"
],
"type": "object"
},
{
"description": "A touched path is absent from the target tree, but a\nconfigured `[[path_translation]]` rewrites it to a path that\ndoes exist on the target. Non-blocking: the operator (or the\ncherry-pick driver) rewrites the path before applying.",
"properties": {
"kind": {
"const": "path_rename",
"type": "string"
},
"source_path": {
"type": "string"
},
"target_path": {
"type": "string"
},
"translation": {
"$ref": "#/$defs/TranslationSource"
}
},
"required": [
"kind",
"source_path",
"target_path",
"translation"
],
"type": "object"
},
{
"description": "A touched path is absent on the target while others are present\nand no `[[path_translation]]` rewrites it. Non-blocking: dropping\nthe hunks for this path lets the rest apply. The all-absent case\nis `InapplicableReason::PathsMissingOnTarget`.",
"properties": {
"kind": {
"const": "target_path_absent",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"description": "A `_SUITE.erl` file in the patch references `missing_module:f/n`\nwhere `missing_module` resolves to no source file under any\nconfigured `FamilyDefaults.test_helper_search_paths` on the\ntarget tree. The cherry-pick compiles and the SUITE may even\nload, but every call to the missing helper crashes at runtime:\nthe failure pattern seen in the Jun 2026 v4.1.x → v4.0.x round\n(the `amqp_utils:connection_config/1` undef in\n`amqp10_connection_max_SUITE`). Non-blocking by default: the\ndiagnostic equivalent (`Diagnostics.missing_test_modules`)\nalways fires; the `Reason` variant fires only when\n`--target-repo-dir-path` is supplied and the resolution is\nauthoritative.",
"properties": {
"call_sites": {
"items": {
"$ref": "#/$defs/TestCallSite"
},
"type": "array"
},
"kind": {
"const": "test_module_symbol_missing",
"type": "string"
},
"missing_module": {
"type": "string"
},
"suite_path": {
"type": "string"
}
},
"required": [
"kind",
"suite_path",
"missing_module",
"call_sites"
],
"type": "object"
},
{
"description": "A touched `.erl` declares `-behaviour(behaviour)` (or\n`-behavior(...)`) where `behaviour` resolves to no source\nmodule on the target tree. `erlc` compiles with a warning,\nthen hook dispatch crashes at runtime. The `BehaviourCallback*`\nvariants model implementer drift; this one catches the\nmissing-behaviour-module case they do not.",
"properties": {
"behaviour": {
"type": "string"
},
"kind": {
"const": "behaviour_module_missing",
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"behaviour"
],
"type": "object"
},
{
"description": "A touched `.erl` or `.hrl` declares `-include(path)` or\n`-include_lib(app/include/file.hrl)` against a target tree that\ndoes not ship the resolved header. Compile-time failure rather\nthan runtime, but same user-facing shape as\n`TestModuleSymbolMissing`: looked fine on source, broken on\ntarget.",
"properties": {
"attempted_paths": {
"items": {
"type": "string"
},
"type": "array"
},
"include_directive": {
"$ref": "#/$defs/IncludeDirective"
},
"kind": {
"const": "header_file_missing",
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"include_directive",
"attempted_paths"
],
"type": "object"
},
{
"description": "A touched `.erl` or `.hrl` file references `?MACRO` on an added\nline, but `MACRO` is defined nowhere the target tree reaches (not\nin the file, its includes, or the patch itself) and is not\npredefined. Compiles on source, dangles on target. Non-blocking:\nthe operator drops or adapts the reference.",
"properties": {
"kind": {
"const": "macro_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"macro_name": {
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"macro_name",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` or `.hrl` file uses `#record{}` on an added\nline, but `record` is defined nowhere the target tree reaches and\nis not added by the patch. Same check as `MacroUndefinedOnTarget`\nfor the record namespace; non-blocking.",
"properties": {
"kind": {
"const": "record_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"record_name": {
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"record_name",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` file calls an unqualified `f/a` on an added line\nthat the target version of the same module neither defines,\nexports, imports, nor inherits as an auto-imported BIF. The\nsame check for the function namespace; non-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "local_call_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"function",
"arity",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` file calls a qualified `m:f/a` on an added line\nwhose module is a first-party module present on the target tree,\nbut the target version of that module does not export `f/a` (and\nthe patch does not add it). The qualified form of\n`LocalCallUndefinedOnTarget`, resolved against the called\nmodule's exports. Withheld when any pin snapshot already covers\nthe module, when it is absent from the tree, or when its export\nsurface is not fully readable. Non-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "qualified_call_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"module": {
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"module",
"function",
"arity",
"line"
],
"type": "object"
},
{
"description": "A qualified `m:f/a` call that resolves against the target tree\nhas a target-tree `-spec` return shape that disagrees with its\nsource-tree `-spec`. Same comparison as `ReturnShapeMismatch` on\nthe live, snapshot-free first-party axis: same comparator,\nnon-blocking like the rest of that axis. Only evaluated once the\ncall is confirmed to resolve; withheld when either side lacks a\n`-spec`.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "qualified_call_return_shape_drift",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"module": {
"type": "string"
},
"source_path": {
"type": "string"
},
"source_signature": {
"type": "string"
},
"target_signature": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"module",
"function",
"arity",
"source_signature",
"target_signature",
"line"
],
"type": "object"
},
{
"description": "An unqualified call that resolves against the target module's\nown definitions has a target-tree `-spec` return shape that\ndisagrees with its source-tree `-spec`. The local-call form of\n`QualifiedCallReturnShapeDrift`; imported resolutions are\nwithheld, since the callee's spec is in another module.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "local_call_return_shape_drift",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
},
"source_signature": {
"type": "string"
},
"target_signature": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"function",
"arity",
"source_signature",
"target_signature",
"line"
],
"type": "object"
},
{
"description": "A `?MACRO` the patch uses is defined in the touched file itself\non both trees, exactly once each, and the normalized `-define`\nbodies disagree: the compile-clean, behavior-divergent class.\nWithheld for definitions reached any other way. Non-blocking.",
"properties": {
"kind": {
"const": "macro_value_drift",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"macro_name": {
"type": "string"
},
"source_path": {
"type": "string"
},
"source_value": {
"type": "string"
},
"target_value": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"macro_name",
"source_value",
"target_value",
"line"
],
"type": "object"
},
{
"description": "The target's version of a behaviour the patch declares requires\na callback the source's version does not, and the target does\nnot list it as optional: an implementation written against the\nsource is missing it. `line` is the `-behaviour` attribute's\nline in the touched file. Non-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_added_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"behaviour",
"callback",
"arity",
"line"
],
"type": "object"
},
{
"description": "A callback both trees' versions of a declared behaviour declare\nhas a different normalized signature on the target. The whole\nsignature is compared, not just the return half: a callback\ncontract's argument types are the implementer's obligation.\nNon-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_drift_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
},
"source_signature": {
"type": "string"
},
"target_signature": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"behaviour",
"callback",
"arity",
"source_signature",
"target_signature",
"line"
],
"type": "object"
},
{
"description": "Declared versioned-machine module is touched but the snapshot\nhas no recorded `versioned_machine_version` on `side`.\nNon-blocking.",
"properties": {
"kind": {
"const": "versioned_machine_snapshot_missing",
"type": "string"
},
"module": {
"type": "string"
},
"side": {
"$ref": "#/$defs/SnapshotSide"
}
},
"required": [
"kind",
"module",
"side"
],
"type": "object"
},
{
"description": "Declared wire constants are touched but the snapshot's\n`wire_constants` vector lacks the listed macros on `side`.\n`macros` is sorted alphabetically. Non-blocking.",
"properties": {
"kind": {
"const": "wire_constant_bindings_missing",
"type": "string"
},
"macros": {
"items": {
"type": "string"
},
"type": "array"
},
"module": {
"type": "string"
},
"side": {
"$ref": "#/$defs/SnapshotSide"
}
},
"required": [
"kind",
"module",
"macros",
"side"
],
"type": "object"
},
{
"description": "A first-party `m:f/a` referenced as arguments to a mocking or\nrpc form (a meck expectation, `rpc:call`, `erpc:call`, or a CT\nbroker rpc helper) is neither exported nor defined by the target\ntree's module. Non-blocking: a meck expectation can install a\nfunction the module never had, so absence proves drift, not\nfailure.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "indirect_call_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"module": {
"type": "string"
},
"source_path": {
"type": "string"
},
"via": {
"$ref": "#/$defs/IndirectCallForm"
}
},
"required": [
"kind",
"source_path",
"module",
"function",
"arity",
"via",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` file adds an `-export_type([t/a])` entry naming\na type neither the target version of the same module declares\nnor the patch adds. An `erlc` error, unlike `MissingType`, which\nis dialyzer-level; non-blocking regardless, being a target-tree\nfinding rather than a pin verdict. Withheld when the target file\nis unreadable or declares a `parse_transform`, or when the added\nlist names a macro.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "exported_type_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
},
"type_name": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"type_name",
"arity",
"line"
],
"type": "object"
},
{
"description": "A touched implementer of a family-declared dependency behaviour\n(`FamilyDefaults.dep_behaviours`) exports a callback the pinned\nbehaviour does not declare. The callback compiles but is never\ninvoked at this pin. Non-blocking: the operator judges whether\nthe backport still does anything useful without it.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"evidence": {
"$ref": "#/$defs/DriftEvidence"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_unknown_on_pin",
"type": "string"
},
"pin_arities": {
"items": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"type": "array"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"pin_arities",
"implementer",
"evidence"
],
"type": "object"
},
{
"description": "An added implementer of a family-declared dependency behaviour\nlacks a callback the pinned behaviour requires. Blocking: the\nmissing callback crashes the first time the behaviour invokes it.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_missing_on_pin",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"implementer"
],
"type": "object"
},
{
"description": "An added line uses a map key that a family-declared option type\n(`FamilyDefaults.option_types`) gained after the pinned version.\nNon-blocking: an unrecognized key is typically ignored by the\nolder dependency rather than rejected.",
"properties": {
"key": {
"type": "string"
},
"kind": {
"const": "option_key_unknown_on_pin",
"type": "string"
},
"module": {
"type": "string"
},
"pin_tag": {
"type": "string"
},
"project": {
"type": "string"
},
"type_name": {
"type": "string"
}
},
"required": [
"kind",
"project",
"module",
"type_name",
"key",
"pin_tag"
],
"type": "object"
},
{
"description": "The patch adds a test suite to an app whose Makefile dispatches\nsuites by explicit registration (`FamilyDefaults.suite_registration`)\nwithout registering it there. Non-blocking: the suite still\ncompiles, it just never runs under CI.",
"properties": {
"kind": {
"const": "suite_not_registered_for_ct",
"type": "string"
},
"makefile_path": {
"type": "string"
},
"suite_path": {
"type": "string"
}
},
"required": [
"kind",
"suite_path",
"makefile_path"
],
"type": "object"
},
{
"description": "An introduced cuttlefish schema mapping uses an attribute the\npinned cuttlefish version does not support. Blocking: the\ncorpus evidence for this shape is a boot failure.",
"properties": {
"conf_key": {
"type": [
"string",
"null"
]
},
"feature": {
"type": "string"
},
"kind": {
"const": "schema_feature_unsupported_on_pin",
"type": "string"
},
"pinned_version": {
"type": "string"
},
"required_version": {
"type": "string"
},
"schema_path": {
"type": "string"
}
},
"required": [
"kind",
"schema_path",
"feature",
"required_version",
"pinned_version"
],
"type": "object"
},
{
"description": "An introduced cuttlefish schema mapping targets an application\nenvironment key that nothing in the target tree's owning apps\nreads. Non-blocking: the token search is deliberately crude, so\nthe operator reviews before trusting a positive.",
"properties": {
"absent_apps": {
"description": "Apps the key names that do not exist on the target tree at\nall: a stronger form of the same finding.",
"items": {
"type": "string"
},
"type": "array"
},
"kind": {
"const": "schema_key_reader_missing",
"type": "string"
},
"schema_path": {
"type": "string"
},
"searched_apps": {
"items": {
"type": "string"
},
"type": "array"
},
"target_key": {
"type": "string"
}
},
"required": [
"kind",
"schema_path",
"target_key",
"searched_apps",
"absent_apps"
],
"type": "object"
}
]
},
"RefOrigin": {
"description": "Which side of the hunk a reference was extracted from. `Added`\nlines are requirements the patch introduces; `Context` lines are\npre-existing facts about the target and never drive verdicts.\n`Added` orders first so a kind-level dedup keeps the stronger\norigin.",
"enum": [
"added",
"context"
],
"type": "string"
},
"ResolverClass": {
"description": "A class of symbol whose presence a backport can dangle on.",
"enum": [
"macro",
"include",
"behaviour",
"qualified_call",
"record",
"local_call",
"type",
"indirect_call"
],
"type": "string"
},
"ResolverCoverage": {
"description": "The set of classes a producer checks, stamped on a verdict envelope\nso a corpus row self-describes its producer's coverage. Stores only\nthe checked set: `unchecked` is derived, so a class can never be in\nboth or neither.",
"properties": {
"checked": {
"items": {
"$ref": "#/$defs/ResolverClass"
},
"type": "array",
"uniqueItems": true
}
},
"required": [
"checked"
],
"type": "object"
},
"SeriesSummary": {
"properties": {
"compatible": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"inapplicable": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"incompatible": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"requires_adaptation": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"compatible",
"requires_adaptation",
"incompatible"
],
"type": "object"
},
"SeriesVerdict": {
"properties": {
"results": {
"items": {
"$ref": "#/$defs/PinVerdict"
},
"type": "array"
},
"summary": {
"$ref": "#/$defs/SeriesSummary"
}
},
"required": [
"results",
"summary"
],
"type": "object"
},
"ShapeCheckTally": {
"description": "What the live qualified-call gate's return-shape check did with\neach first-party resolved call. Never reasons: a withhold is not a\nfinding, but a round where most calls are shape-blind must read\ndifferently from a round where all of them were compared.",
"properties": {
"compared": {
"description": "Both sides had a `-spec` that parsed to a known type; the shapes\nwere compared. Drift is visible in the reasons, not double-counted\nhere.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_imported": {
"description": "The call resolved through an `-import`: the callee's `-spec`\nis in another module, so the calling module's tables cannot\ncompare it. Local-call axis only.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_no_source": {
"description": "The callee module was not readable on the source side: no\ncheckout was supplied, or the checkout has no file at the\nmodule's path (a defaulted `--repo-dir-path` that is not the\nsource tree lands here, not in `withheld_no_spec`).",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_no_spec": {
"description": "One or both sides declare no `-spec` for the called function.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_unknown_type": {
"description": "Both sides have a spec but at least one parses to\n`SpecType::Unknown`.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"SnapshotSide": {
"description": "Which side of a snapshot comparison the data is missing from.",
"enum": [
"source",
"target",
"both"
],
"type": "string"
},
"SourceDelta": {
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"module": {
"type": "string"
},
"source_spec": {
"type": "string"
},
"target_spec": {
"type": "string"
}
},
"required": [
"module",
"function",
"arity",
"source_spec",
"target_spec"
],
"type": "object"
},
"SymbolRef": {
"oneOf": [
{
"properties": {
"kind": {
"const": "behaviour",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module"
],
"type": "object"
},
{
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "callback",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function",
"arity"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "function",
"type": "string"
},
"mfa": {
"$ref": "#/$defs/Mfa"
}
},
"required": [
"kind",
"mfa"
],
"type": "object"
},
{
"description": "A function reference whose arity could not be determined from\nthe source line (the call's closing paren sits on a later\nline). Resolves against a snapshot when *any* export carries\nthe name; never produces an arity mismatch.",
"properties": {
"function": {
"type": "string"
},
"kind": {
"const": "function_any_arity",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "macro",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "record",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "type",
"type": "string"
},
"module": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"module",
"name",
"arity"
],
"type": "object"
}
],
"properties": {
"origin": {
"$ref": "#/$defs/RefOrigin"
}
},
"type": "object"
},
"TargetFindings": {
"description": "Symbol-axis findings for one row, resolved against the target tree.\nPresent exactly when a target context was supplied; independent of\nevery pin verdict, so an inapplicable row still carries its\nfindings.",
"properties": {
"reasons": {
"description": "Every reason the live-axis target checks produced for this row,\nin production order.",
"items": {
"$ref": "#/$defs/Reason"
},
"type": "array"
}
},
"required": [
"reasons"
],
"type": "object"
},
"TargetMatch": {
"description": "A target commit found to carry the candidate's patch. The subject\nis included so consumers can auto-fill exclusion reasons without\na second git query.",
"properties": {
"commit": {
"type": "string"
},
"subject": {
"type": "string"
},
"via": {
"$ref": "#/$defs/TargetMatchKind"
}
},
"required": [
"commit",
"via",
"subject"
],
"type": "object"
},
"TargetMatchKind": {
"description": "How a tier-1 already-present match against the target branch was\nestablished.",
"oneOf": [
{
"const": "trailer_intersection",
"description": "A walked target commit's `-x` trailer names the candidate (or\none of its trailer origins or inner PR commits).",
"type": "string"
},
{
"const": "trailer_ancestry",
"description": "One of the candidate's own trailer origins is already an\nancestor of the target tip.",
"type": "string"
},
{
"const": "patch_id",
"description": "A walked target commit's normalized patch hash equals the\ncandidate's.",
"type": "string"
}
]
},
"TestCallSite": {
"description": "One `Module:Function/Arity` reference inside a `_SUITE.erl` that\nresolves to a module absent on the target tree. Carries the line\nnumber so the operator can jump straight to the call site.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"function",
"arity",
"line"
],
"type": "object"
},
"TouchedKinds": {
"description": "Per-pin tally of file kinds the patch touched. Lets `promote_inapplicable`\ntell a real green check from a diff with nothing analyzable to check.",
"properties": {
"app_src": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"ci_workflow": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"docs": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"erl": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"hrl": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"makefile": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"mix_exs": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"only_self_surface": {
"description": "The patch touches Erlang surface but references no tracked-dep\nAPI (every non-self pin has zero in-scope references). The CLI\nsets this after `evaluate_series` when a self-pin is present\nand every non-self pin's `tracked_refs` is empty; see\n`InapplicableReason::OnlySelfSurfaceTouched`.",
"type": "boolean"
},
"only_test_visibility": {
"description": "Every changed `.erl` hunk is a Variant A unwrap of test-only\n`-ifdef(TEST)` guards around an `-export` directive (see\n`InapplicableReason::OnlyTestVisibilityChanged`). When true,\nthe patch touches Erlang surface but adds no semantic\ncontent, so an empty reason set should promote to\n`Inapplicable` instead of `Compatible`.",
"type": "boolean"
},
"other": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"rebar_config": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"schema": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"tests": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"TranslationSource": {
"oneOf": [
{
"properties": {
"kind": {
"const": "config_stanza",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "external_file",
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"name"
],
"type": "object"
}
]
},
"Unanalyzed": {
"description": "Counts of call sites the analyzer could not resolve: `apply/3`-style\nBIFs, and dispatch through a variable module or function. Informational only.",
"properties": {
"apply": {
"default": 0,
"format": "uint",
"minimum": 0,
"type": "integer"
},
"variable_dispatch": {
"default": 0,
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"UnassessedReason": {
"description": "Why a path's apply outcome could not be assessed. The `Ord` only\nbreaks merge ties deterministically; it is not a severity.",
"oneOf": [
{
"const": "binary_file",
"description": "The diff marks the file binary; there is no hunk text to match.",
"type": "string"
},
{
"const": "target_not_text",
"description": "The target blob exists but is not valid UTF-8.",
"type": "string"
}
]
},
"Verdict": {
"oneOf": [
{
"properties": {
"verdict": {
"const": "compatible",
"type": "string"
}
},
"required": [
"verdict"
],
"type": "object"
},
{
"properties": {
"reasons": {
"items": {
"$ref": "#/$defs/Reason"
},
"type": "array"
},
"verdict": {
"const": "requires_adaptation",
"type": "string"
}
},
"required": [
"verdict",
"reasons"
],
"type": "object"
},
{
"properties": {
"reasons": {
"items": {
"$ref": "#/$defs/Reason"
},
"type": "array"
},
"verdict": {
"const": "incompatible",
"type": "string"
}
},
"required": [
"verdict",
"reasons"
],
"type": "object"
},
{
"properties": {
"reason": {
"$ref": "#/$defs/InapplicableReason"
},
"verdict": {
"const": "inapplicable",
"type": "string"
}
},
"required": [
"verdict",
"reason"
],
"type": "object"
}
]
},
"VerdictFingerprint": {
"description": "A verdict's stable identity for measurement: equal fingerprints\nmean the same patch against the same target and pins, whatever\nbackhopper version produced either side. Thirty-two lowercase hex\ncharacters: a truncated BLAKE3 digest, formatted here so\n`backhopper-core` takes no dependency on `blake3`.",
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Top-level payload of a `check batch` envelope.",
"properties": {
"fingerprint_version": {
"default": null,
"description": "The fingerprint generation this producer stamped. Lets a corpus\nspanning a bump segregate generations instead of reading an\nunexplained zero-match. `None` for a producer that predates it.",
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"queried_against": {
"items": {
"$ref": "#/$defs/BatchQuery"
},
"type": "array"
},
"resolver_coverage": {
"anyOf": [
{
"$ref": "#/$defs/ResolverCoverage"
},
{
"type": "null"
}
],
"default": null,
"description": "Symbol classes this producer checks. A corpus row keeps it so the\nfold routes bug-vs-gap against the producing binary, not the one\nrunning the fold. `None` for a producer that predates the field."
},
"results": {
"items": {
"$ref": "#/$defs/BatchResult"
},
"type": "array"
},
"self_projects": {
"default": null,
"description": "Projects evaluated as the backport subject itself, excluded from\nthe tracked-dependency tally. `None` means the producing binary\npredates the field, not \"no self project\": a current producer\nalways emits `Some`, even when empty, so it is never skipped.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
],
"uniqueItems": true
}
},
"required": [
"queried_against",
"results"
],
"title": "BatchPayload",
"type": "object"
},
"cache_list_payload": {
"$defs": {
"CacheLevel": {
"description": "Which workspace cache an entry belongs to.",
"oneOf": [
{
"const": "by_input",
"description": "`.verdict_cache/by-input/`: SHA-keyed verdict entries.",
"type": "string"
},
{
"const": "by_content",
"description": "`.verdict_cache/by-content/`: content-keyed verdict entries.",
"type": "string"
}
]
},
"CacheListRow": {
"description": "One row in `cache list`.",
"properties": {
"age_days": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"alias": {
"default": false,
"description": "True for `by-input` entries created from a content-level hit.",
"type": "boolean"
},
"bytes": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"commit": {
"description": "The evaluated commit, for verdict entries that carry one.",
"type": [
"string",
"null"
]
},
"key": {
"description": "The entry's key hash (the file-name stem after the format\nprefix); unique prefixes of it address entries in `show` and\n`evict`.",
"type": "string"
},
"level": {
"$ref": "#/$defs/CacheLevel"
},
"series": {
"description": "The series or pin target, when the pre-image names one.",
"type": [
"string",
"null"
]
}
},
"required": [
"key",
"level",
"age_days",
"bytes"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "The `cache list` payload.",
"properties": {
"rows": {
"items": {
"$ref": "#/$defs/CacheListRow"
},
"type": "array"
}
},
"required": [
"rows"
],
"title": "CacheListPayload",
"type": "object"
},
"cache_mutation_payload": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Payload for `cache evict`, `cache prune`, and `cache clear`.",
"properties": {
"removed_bytes": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"removed_entries": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"removed_entries",
"removed_bytes"
],
"title": "CacheMutationPayload",
"type": "object"
},
"cache_show_payload": {
"$defs": {
"CacheLevel": {
"description": "Which workspace cache an entry belongs to.",
"oneOf": [
{
"const": "by_input",
"description": "`.verdict_cache/by-input/`: SHA-keyed verdict entries.",
"type": "string"
},
{
"const": "by_content",
"description": "`.verdict_cache/by-content/`: content-keyed verdict entries.",
"type": "string"
}
]
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "The `cache show` payload: one entry, pre-image included.",
"properties": {
"age_days": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"alias": {
"default": false,
"description": "True for `by-input` entries created as aliases of a\ncontent-level hit.",
"type": "boolean"
},
"bytes": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"created_at": {
"type": "string"
},
"key": {
"type": "string"
},
"key_inputs": {
"description": "The canonical-JSON key pre-image stored inside the entry."
},
"level": {
"$ref": "#/$defs/CacheLevel"
},
"value": {
"description": "The full stored value, under `--full` only."
},
"verdict_summary": {
"description": "Verdict counts for the stored evaluation."
}
},
"required": [
"key",
"level",
"created_at",
"age_days",
"bytes",
"key_inputs"
],
"title": "CacheShowPayload",
"type": "object"
},
"cache_stats_payload": {
"$defs": {
"CacheLevelStats": {
"description": "Per-level counters inside `cache stats`.",
"properties": {
"bytes": {
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"entries": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"entries",
"bytes"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "The `cache stats` payload.",
"properties": {
"aliases": {
"description": "`by-input` entries created as aliases of a content-level hit.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"by_content": {
"$ref": "#/$defs/CacheLevelStats"
},
"by_input": {
"$ref": "#/$defs/CacheLevelStats"
},
"newest_entry_at": {
"type": [
"string",
"null"
]
},
"oldest_entry_at": {
"description": "RFC3339 write times of the oldest and newest entries across\nevery level; absent when all caches are empty.",
"type": [
"string",
"null"
]
},
"total_bytes": {
"format": "uint64",
"minimum": 0,
"type": "integer"
}
},
"required": [
"by_input",
"by_content",
"aliases",
"total_bytes"
],
"title": "CacheStatsPayload",
"type": "object"
},
"command_family": "check",
"description": "v17 (doc 025, the six family specializations): six new `Reason` variants (`BehaviourCallbackUnknownOnPin`, `BehaviourCallbackMissingOnPin`, `OptionKeyUnknownOnPin`, `SuiteNotRegisteredForCt`, `SchemaFeatureUnsupportedOnPin`, `SchemaKeyReaderMissing`), the `DriftEvidence` enum one of them carries, and `Diagnostics.dormant_detectors`.",
"envelope": {
"$defs": {
"AlreadyPresent": {
"description": "Advisory: the patch's content appears to already exist on the\ntarget. Never affects the verdict; q-port and the operator own\nthe exclusion decision.",
"properties": {
"content": {
"anyOf": [
{
"$ref": "#/$defs/ContentPresence"
},
{
"type": "null"
}
],
"description": "Tier-2 tally: the post-image is (partly) present in the tree."
},
"identical": {
"anyOf": [
{
"$ref": "#/$defs/TargetMatch"
},
{
"type": "null"
}
],
"description": "Tier-1 hit: an identical patch landed on the target."
}
},
"type": "object"
},
"AlreadyPresentSkipped": {
"description": "Why already-present detection could not run. Emitted instead of\nsilence: an invisible skip would read as \"not present\".",
"oneOf": [
{
"description": "The candidate commit object is absent from the target object\nstore (an unfetched branch, usually).",
"properties": {
"reason": {
"const": "candidate_missing_from_target_odb",
"type": "string"
},
"sha": {
"type": "string"
}
},
"required": [
"reason",
"sha"
],
"type": "object"
},
{
"description": "The candidate and the target tip share no history.",
"properties": {
"reason": {
"const": "no_merge_base",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "The target-side walk failed (shallow clone, corrupt object).",
"properties": {
"detail": {
"type": "string"
},
"reason": {
"const": "target_walk_failed",
"type": "string"
}
},
"required": [
"reason",
"detail"
],
"type": "object"
}
]
},
"ApplyConflictKind": {
"description": "The apply outcomes a divergence predictor consumes, ordered by\nseverity: a higher variant outranks a lower one on the same path, so\ndedup to one conflict per path is a `max`.",
"enum": [
"postimage_collision",
"preimage_missing",
"file_absent"
],
"type": "string"
},
"ApplyForecast": {
"description": "Per-path apply prediction for one `(commit, series)` row, computed\nfrom the target tree. Present exactly when a target context was\nsupplied.",
"properties": {
"paths": {
"additionalProperties": {
"$ref": "#/$defs/PathApplyOutcome"
},
"description": "Every assessed touched path, including ones absent on the\ntarget (`Conflict { FileAbsent }`).",
"type": "object"
}
},
"required": [
"paths"
],
"type": "object"
},
"ArgShape": {
"oneOf": [
{
"description": "Variable identifier (starts with `_` or capital letter).",
"properties": {
"kind": {
"const": "variable",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Atom literal: `foo`, `'quoted atom'`.",
"properties": {
"kind": {
"const": "atom",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"description": "Integer literal.",
"properties": {
"kind": {
"const": "integer",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Float literal.",
"properties": {
"kind": {
"const": "float",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Binary literal: `<<...>>`.",
"properties": {
"kind": {
"const": "binary",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "List literal: `[...]`.",
"properties": {
"kind": {
"const": "list",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Tuple literal: `{...}` (size is the number of elements).",
"properties": {
"kind": {
"const": "tuple",
"type": "string"
},
"size": {
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"kind",
"size"
],
"type": "object"
},
{
"description": "Record reference: `#name{...}`.",
"properties": {
"kind": {
"const": "record",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"description": "String literal: `\"...\"`.",
"properties": {
"kind": {
"const": "string",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Anonymous fun: `fun ... end` or `fun mod:f/A`.",
"properties": {
"kind": {
"const": "fun",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
},
{
"description": "Anything the extractor cannot classify. Always matches.",
"properties": {
"kind": {
"const": "unknown",
"type": "string"
}
},
"required": [
"kind"
],
"type": "object"
}
]
},
"ArtifactKind": {
"oneOf": [
{
"description": "`<<<<<<<`, `=======`, `>>>>>>>`, or `||||||| ` marker present in a\ntouched file. The cherry-pick driver left a conflict unresolved.",
"properties": {
"artifact_kind": {
"const": "conflict_marker",
"type": "string"
},
"marker": {
"$ref": "#/$defs/ConflictMarker"
}
},
"required": [
"artifact_kind",
"marker"
],
"type": "object"
},
{
"description": "`-export([f/N])` line without a matching clause defining `f/N`.\nCompiles, then crashes at runtime on the first call.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"artifact_kind": {
"const": "export_without_body",
"type": "string"
},
"function": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"artifact_kind",
"module",
"function",
"arity"
],
"type": "object"
}
]
},
"BumpStatus": {
"description": "Snapshot-store status of a bumped-to pin version.",
"oneOf": [
{
"description": "The bumped dep is not a tracked project; nothing to vet.",
"properties": {
"state": {
"const": "untracked",
"type": "string"
}
},
"required": [
"state"
],
"type": "object"
},
{
"description": "No snapshot for the bumped-to version; `note` carries the remedy.",
"properties": {
"note": {
"type": "string"
},
"state": {
"const": "snapshot_missing",
"type": "string"
}
},
"required": [
"state",
"note"
],
"type": "object"
},
{
"properties": {
"state": {
"const": "snapshot_present",
"type": "string"
}
},
"required": [
"state"
],
"type": "object"
}
]
},
"CheckPayload": {
"description": "The parsed payload of every `check`-family verb.",
"properties": {
"apply": {
"anyOf": [
{
"$ref": "#/$defs/ApplyForecast"
},
{
"type": "null"
}
],
"description": "Apply-axis prediction. Absent when no target context was\nsupplied: the axis was not evaluated, never \"clean\"."
},
"diagnostics": {
"$ref": "#/$defs/Diagnostics",
"description": "Series-wide diagnostics (untracked calls, suggested suites)."
},
"fingerprint_version": {
"default": null,
"description": "The fingerprint generation this binary stamped. Always emitted.",
"format": "uint32",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"pr_commits": {
"default": null,
"description": "Inner PR-branch commits for 2-parent merge inputs, `None` for\neverything else. The `None` vs `Some(vec![])` distinction is\npart of the wire contract, so no `skip_serializing_if`.",
"items": {
"$ref": "#/$defs/PrCommit"
},
"type": [
"array",
"null"
]
},
"project_suggestions": {
"description": "Projects the untracked-call analysis suggests adding.",
"items": {
"$ref": "#/$defs/ProjectSuggestion"
},
"type": "array"
},
"queried_against": {
"$ref": "#/$defs/QueriedAgainst",
"description": "What the verb was queried against (a series or a pin)."
},
"resolver_coverage": {
"anyOf": [
{
"$ref": "#/$defs/ResolverCoverage"
},
{
"type": "null"
}
],
"default": null,
"description": "Symbol classes this binary checks, for the measurement fold.\nAlways emitted so a consumer tells it from an old binary."
},
"results": {
"$ref": "#/$defs/SeriesVerdict",
"description": "Per-pin verdicts plus summary."
},
"self_projects": {
"default": null,
"description": "Projects excluded from the tracked-dependency tally. Always\nemitted so a consumer can tell an empty set from an old binary.",
"items": {
"type": "string"
},
"type": [
"array",
"null"
],
"uniqueItems": true
},
"target_findings": {
"anyOf": [
{
"$ref": "#/$defs/TargetFindings"
},
{
"type": "null"
}
],
"description": "Symbol-axis target findings, `None` when no target context."
},
"verdict_fingerprint": {
"anyOf": [
{
"$ref": "#/$defs/VerdictFingerprint"
},
{
"type": "null"
}
],
"description": "Stable join key for this verdict, omitted for inputs with no\ncache key (patch, range, PR, or an unresolvable pin)."
}
},
"required": [
"queried_against",
"results"
],
"type": "object"
},
"ConflictMarker": {
"oneOf": [
{
"const": "ours",
"description": "`<<<<<<<` line: start of the local side.",
"type": "string"
},
{
"const": "divider",
"description": "`=======` line: divider between sides.",
"type": "string"
},
{
"const": "theirs",
"description": "`>>>>>>>` line: end of the incoming side.",
"type": "string"
},
{
"const": "ancestor",
"description": "`||||||| ` line: base ancestor marker from a 3-way diff.",
"type": "string"
}
]
},
"ContentPresence": {
"description": "Tier-2 advisory: how much of the patch's post-image already exists\nin the named pin's tree. A tally, never a boolean: partial presence\nis common and the fraction is the signal.",
"properties": {
"hunks_already_applied": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"hunks_ambiguous": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"hunks_considered": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"hunks_low_confidence": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"per_file": {
"additionalProperties": {
"$ref": "#/$defs/HunkTally"
},
"type": "object"
},
"pin": {
"description": "The pin whose evaluation produced the tally. In cross-branch\nmode the self pin resolves to the target branch, so its tally\nis the target-tree answer.",
"type": "string"
}
},
"required": [
"pin",
"hunks_already_applied",
"hunks_considered",
"hunks_ambiguous",
"hunks_low_confidence"
],
"type": "object"
},
"DepPinDivergence": {
"description": "A dependency whose `rabbitmq-components.mk` pin differs between\nthe source commit's tree and the target tree, and that an app\ntouched by the patch (transitively) depends on. Advisory only.",
"properties": {
"dep": {
"type": "string"
},
"source": {
"description": "Pin at the source commit, e.g. `hex 2.16.0`.",
"type": "string"
},
"target": {
"description": "Pin at the target tree, e.g. `hex 2.13.0`.",
"type": "string"
}
},
"required": [
"dep",
"source",
"target"
],
"type": "object"
},
"DetectorName": {
"description": "A family-declared detector this run's dormancy list can name.",
"enum": [
"dep_behaviour_conformance",
"option_key_drift",
"macro_undefined_on_target",
"suite_not_registered_for_ct",
"schema_feature_unsupported_on_pin",
"schema_key_reader_missing"
],
"type": "string"
},
"Diagnostics": {
"description": "Series-wide diagnostic envelope. Strictly separate from `Verdict`\nso untracked-call signals never leak into machine-readable verdicts.",
"properties": {
"already_present": {
"anyOf": [
{
"$ref": "#/$defs/AlreadyPresent"
},
{
"type": "null"
}
],
"description": "Advisory: the patch's content appears to already exist on the\ntarget (tier-1 identical patch, tier-2 content tally, or both)."
},
"already_present_skipped": {
"anyOf": [
{
"$ref": "#/$defs/AlreadyPresentSkipped"
},
{
"type": "null"
}
],
"description": "Why already-present detection was skipped, when it was."
},
"context_refs_missing": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "In-scope references on *context* lines that do not resolve at\nsome pin, per module. Pre-existing target facts: never reasons.",
"type": "object"
},
"dep_pin_divergence": {
"description": "Dep pins that diverge between source and target trees and are\nreachable from the apps this patch touches.",
"items": {
"$ref": "#/$defs/DepPinDivergence"
},
"type": "array"
},
"dormant_detectors": {
"description": "Family-declared detectors that did not run this evaluation,\nwith the input whose absence disabled each. Gated on the\nfamily actually declaring the relevant vocabulary, so a\ngeneric project's runs carry an empty list. Silence must be\ndistinguishable from absence of findings.",
"items": {
"$ref": "#/$defs/DormantDetector"
},
"type": "array"
},
"indirect_call_checks": {
"$ref": "#/$defs/IndirectCallTally",
"description": "What the indirect-reference check (meck expectations and rpc\nforms) did with each recognized occurrence: resolved against the\ntarget module, or seen with an unreadable arity and withheld."
},
"local_call_shape_checks": {
"$ref": "#/$defs/ShapeCheckTally",
"description": "The same tally for local calls: resolved unqualified calls, compared or\nwithheld. Kept apart from the qualified tally so one axis's\ncoverage never reads as the other's."
},
"macro_value_checks": {
"$ref": "#/$defs/MacroValueTally",
"description": "Same-file `-define` value comparisons over macros the patch\nuses: compared, or withheld and why."
},
"missing_test_modules": {
"additionalProperties": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"type": "object"
},
"description": "Per-`_SUITE.erl` map of `helper_module -> call_site_count`. The\nalways-on diagnostic form of\n`Reason::TestModuleSymbolMissing`: emitted by the parse pass\neven without a target tree (which is why the inner key is the\n`ModuleName` rather than a resolved-or-not bit). When\n`--target-repo-dir-path` is supplied the resolver re-checks this\nmap and promotes the absent ones to typed reasons. The nested\n`BTreeMap` shape keeps the JSON envelope serialisable without\na custom composite-key encoder.",
"type": "object"
},
"pin_bumps": {
"description": "Dep pins this patch itself changes or introduces in the root\n`rabbitmq-components.mk`.",
"items": {
"$ref": "#/$defs/PinBump"
},
"type": "array"
},
"qualified_call_shape_checks": {
"$ref": "#/$defs/ShapeCheckTally",
"description": "What the live qualified-call gate's return-shape check did with\neach first-party resolved call: compared, or withheld and why."
},
"suggested_suites": {
"description": "SUITE names worth running for the patch, derived from touched paths.\nPopulated even when the verdict promotes to `Inapplicable` so that\nschema-only and config-only diffs still surface relevant suites.",
"items": {
"type": "string"
},
"type": "array"
},
"unanalyzed": {
"$ref": "#/$defs/Unanalyzed"
},
"unattributed_paths": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "Touched paths no configured project owns, tallied by their\nfirst two path components. The evidence behind an\n`Inapplicable { Untracked }` verdict.",
"type": "object"
},
"untracked_calls": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"type": "object"
},
"untracked_records": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"type": "object"
}
},
"type": "object"
},
"DormantDetector": {
"description": "One family-declared detector that a run could not exercise, and\nwhich input's absence disabled it.",
"properties": {
"detector": {
"$ref": "#/$defs/DetectorName"
},
"missing_input": {
"$ref": "#/$defs/MissingInput"
}
},
"required": [
"detector",
"missing_input"
],
"type": "object"
},
"DriftEvidence": {
"description": "How a dependency-behaviour drift finding was established. Wire-visible\nso consumers can weigh confidence: a set-difference finding is exact,\na name-anchored one is heuristic.",
"oneOf": [
{
"const": "source_side_set_difference",
"description": "Present in the source pin's callback set, absent from the\ntarget pin's.",
"type": "string"
},
{
"const": "name_anchored",
"description": "Callback-name collision at an undeclared arity, with no source\npin to confirm it.",
"type": "string"
}
]
},
"EnvelopeWarning": {
"description": "A non-fatal warning carried alongside a payload.",
"properties": {
"code": {
"description": "Stable warning code, kebab-case (e.g. `stale-extractor`).",
"type": "string"
},
"message": {
"description": "Human-readable message.",
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"HunkTally": {
"description": "Per-file hunk counters for the content-presence check.",
"properties": {
"ambiguous": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"applied": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"considered": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"low_confidence": {
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"applied",
"considered",
"ambiguous",
"low_confidence"
],
"type": "object"
},
"InapplicableReason": {
"oneOf": [
{
"properties": {
"reason": {
"const": "no_erlang_surface_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_docs_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_test_fixtures_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_schema_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_makefile_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_mix_exs_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_ci_workflow_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_app_src_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"properties": {
"reason": {
"const": "only_rebar_config_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "Every changed `.erl` hunk is a Variant A unwrap: dropping\n`-ifdef(TEST).` or `-endif.` around an `-export(...)` directive,\nor rewriting `-compile(export_all).` to an explicit\n`-export([...])`. No call sites, no specs, no bodies touched:\nonly test-visibility metadata.",
"properties": {
"reason": {
"const": "only_test_visibility_changed",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "The patch touches Erlang surface but every referenced symbol\nresolves to the self-pin or to a local definition: every\ntracked-dep pin has zero in-scope references. Without this\nreason the operator would see many vacuous `Compatible`\nrows for a patch that backhopper genuinely has no signal on.",
"properties": {
"reason": {
"const": "only_self_surface_touched",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "Every touched path is in a sibling project's scope, not this\npin's. The pin has nothing to say about the patch. `project`\nnames the first sibling project (alphabetical) that owns the\nout-of-scope paths.",
"properties": {
"project": {
"type": "string"
},
"reason": {
"const": "out_of_scope_for",
"type": "string"
}
},
"required": [
"reason",
"project"
],
"type": "object"
},
{
"description": "Every touched path is unclaimed by any configured project's\nscan_paths or app_roots. Vendored files, docs, build scripts.",
"properties": {
"reason": {
"const": "untracked",
"type": "string"
}
},
"required": [
"reason"
],
"type": "object"
},
{
"description": "`--target-repo-dir-path` was supplied and every touched path\nis missing from the target tree, with no configured\ntranslation mapping any of them. The patch as written does\nnot apply to the target.",
"properties": {
"paths": {
"items": {
"type": "string"
},
"type": "array"
},
"reason": {
"const": "paths_missing_on_target",
"type": "string"
}
},
"required": [
"reason",
"paths"
],
"type": "object"
}
]
},
"IncludeDirective": {
"description": "`-include` and `-include_lib` are syntactically distinct: the\nformer takes a relative-to-source path, the latter an\n`application/include/file.hrl` shape resolved through OTP's lib\npath. The variant preserves which form the source used so the\nremediation text can match.",
"oneOf": [
{
"properties": {
"form": {
"const": "include",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"form",
"path"
],
"type": "object"
},
{
"properties": {
"form": {
"const": "include_lib",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"form",
"path"
],
"type": "object"
}
]
},
"IndirectCallForm": {
"description": "Which recognized call form carried an indirect MFA reference. Names\nthe innermost form: a meck expectation reached through an rpc helper\nis `MeckExpect`, not the helper.",
"enum": [
"meck_expect",
"rpc_call",
"erpc_call",
"ct_broker_helper_rpc",
"rabbit_misc_rpc_call"
],
"type": "string"
},
"IndirectCallTally": {
"description": "What the indirect-reference check did with each recognized form\noccurrence. `checked` counts deduplicated resolved sites, the same\ndedup the reasons use; flagged sites are visible in the reasons,\nnot double-counted here.",
"properties": {
"checked": {
"description": "Module first-party, export and definition sets readable: the\nmembership check ran.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_dynamic": {
"description": "Module and function were literal atoms but the arity source was\nnot statically readable: a variable argument list, a list with a\ncons tail, or a non-literal arity argument.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"MacroValueTally": {
"description": "What the macro-value check did with each `?MACRO` the patch uses:\ncompared, or withheld and why. Same-file `-define`s only; anything\nreached another way is withheld, never guessed.",
"properties": {
"compared": {
"description": "Defined exactly once same-file on both sides; values compared.\nDrift is visible in the reasons, not double-counted here.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_definition_elsewhere": {
"description": "Not defined same-file on both sides: the definition is in an\ninclude, or moved between files across the trees.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_multiple_defines": {
"description": "Defined more than once in the file on either side (`-ifdef`\nbranches): either value could be live.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_no_source": {
"description": "The touched file was not readable on the source side.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"Mfa": {
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"module",
"function",
"arity"
],
"type": "object"
},
"MissingInput": {
"description": "The gating input whose absence left a detector dormant.",
"enum": [
"target_repo_dir_path",
"source_pin",
"cuttlefish_pin"
],
"type": "string"
},
"NeedsPin": {
"description": "The minimum pin that satisfies a missing-symbol reason: the typed\nordering payload q-port turns into a \"bump must land first\" edge.",
"properties": {
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"project",
"tag"
],
"type": "object"
},
"PathApplyOutcome": {
"description": "How one touched path is predicted to apply to the target tree.\nRanked by [`PathApplyOutcome::severity`]; payload-carrying variants\nkeep the enum out of `Ord`.",
"oneOf": [
{
"description": "Every hunk's preimage matches at its expected line.",
"properties": {
"outcome": {
"const": "clean_exact",
"type": "string"
}
},
"required": [
"outcome"
],
"type": "object"
},
{
"description": "Applies, but at least one hunk's preimage was found at a shifted\nline. `line_delta` is the largest-magnitude shift.",
"properties": {
"line_delta": {
"format": "int64",
"type": "integer"
},
"outcome": {
"const": "clean_drifted",
"type": "string"
}
},
"required": [
"outcome",
"line_delta"
],
"type": "object"
},
{
"description": "The path could not be assessed; stated, never silent.",
"properties": {
"outcome": {
"const": "unassessed",
"type": "string"
},
"reason": {
"$ref": "#/$defs/UnassessedReason"
}
},
"required": [
"outcome",
"reason"
],
"type": "object"
},
{
"description": "At least one hunk predicts a conflict. `kind` is the worst\nconflict kind across the path's hunks.",
"properties": {
"kind": {
"$ref": "#/$defs/ApplyConflictKind"
},
"outcome": {
"const": "conflict",
"type": "string"
}
},
"required": [
"outcome",
"kind"
],
"type": "object"
}
]
},
"Pin": {
"properties": {
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"project",
"tag"
],
"type": "object"
},
"PinBump": {
"description": "A dep pin the candidate commit itself changes or introduces in the\nroot `rabbitmq-components.mk`. Advisory only: the verdict on a\nbump-only diff stays `Inapplicable`, this is the evidence behind it.",
"properties": {
"dep": {
"type": "string"
},
"from": {
"description": "Pin before the commit, e.g. `hex 2.16.0`; `None` when the\ncommit introduces the pin.",
"type": [
"string",
"null"
]
},
"status": {
"anyOf": [
{
"$ref": "#/$defs/BumpStatus"
},
{
"type": "null"
}
],
"description": "Snapshot-store assessment of the bumped-to version. Detection\nis a pure function of the patch and may be cached; the store's\ncontents are not a cache-key input, so this field is filled\npost-cache and cached values carry `None`."
},
"to": {
"description": "Pin after the commit, e.g. `hex 2.17.1`.",
"type": "string"
}
},
"required": [
"dep",
"to"
],
"type": "object"
},
"PinPayload": {
"description": "On-wire pin shape used inside `BatchQuery`. Distinct from\n`crate::model::pin::Pin` because the wire form is a `(project, tag)`\nprojection without the resolution logic.",
"properties": {
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"project",
"tag"
],
"type": "object"
},
"PinVerdict": {
"properties": {
"pin": {
"$ref": "#/$defs/Pin"
},
"source_delta_details": {
"items": {
"$ref": "#/$defs/SourceDelta"
},
"type": "array"
},
"touched": {
"$ref": "#/$defs/TouchedKinds"
},
"tracked_ref_details": {
"items": {
"$ref": "#/$defs/SymbolRef"
},
"type": "array"
},
"tracked_refs": {
"default": 0,
"format": "uint",
"minimum": 0,
"type": "integer"
},
"verdict": {
"$ref": "#/$defs/Verdict"
}
},
"required": [
"pin",
"verdict"
],
"type": "object"
},
"PrCommit": {
"description": "One commit on the PR-branch side of a 2-parent merge.",
"properties": {
"author_date": {
"type": "string"
},
"kind": {
"$ref": "#/$defs/PrCommitKind"
},
"sha": {
"type": "string"
},
"subject": {
"type": "string"
}
},
"required": [
"sha",
"subject",
"author_date",
"kind"
],
"type": "object"
},
"PrCommitKind": {
"description": "Classification of a PR-branch commit's role.\n\n`#[non_exhaustive]` so future, richer taxonomies (test-only,\ndocs-only, dependency-bump, etc.) can add variants without a\nbreaking change.",
"oneOf": [
{
"const": "substantive",
"description": "Default: substantive change worth reviewing.",
"type": "string"
},
{
"const": "conflict_resolution",
"description": "Subject matched the conflict-resolution catalog AND the file\nset was a strict subset of prior PR-branch commits.",
"type": "string"
},
{
"const": "review_feedback",
"description": "Subject indicated the commit applied code-review feedback.",
"type": "string"
},
{
"const": "fixup",
"description": "`git --fixup` auto-generated or the manual `fixup:` convention.",
"type": "string"
},
{
"const": "wip_or_cleanup",
"description": "Subject was `WIP` or bare `Cleanup`.",
"type": "string"
}
]
},
"ProjectSuggestion": {
"description": "A project the untracked-call analysis suggests adding to config so its\ncalls become tracked-dependency evidence.",
"properties": {
"call_sites": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"modules": {
"items": {
"type": "string"
},
"type": "array"
},
"name": {
"type": "string"
}
},
"required": [
"name",
"modules",
"call_sites"
],
"type": "object"
},
"QueriedAgainst": {
"description": "What a `check`-family verb was queried against: a single pin or a\nwhole series.",
"oneOf": [
{
"description": "`check ... --project NAME --tag TAG`.",
"properties": {
"kind": {
"const": "pin",
"type": "string"
},
"project": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"kind",
"project",
"tag"
],
"type": "object"
},
{
"description": "`check ... --series NAME`.",
"properties": {
"kind": {
"const": "series",
"type": "string"
},
"name": {
"type": "string"
},
"pins": {
"items": {
"$ref": "#/$defs/PinPayload"
},
"type": "array"
}
},
"required": [
"kind",
"name",
"pins"
],
"type": "object"
}
]
},
"Reason": {
"oneOf": [
{
"properties": {
"first_seen_at_tag": {
"description": "Earliest snapshot tag strictly later than the pin where the\nsymbol appears. `Some` reclassifies the reason as\nadaptable: land the dep pin bump first.",
"type": [
"string",
"null"
]
},
"kind": {
"const": "missing_symbol",
"type": "string"
},
"needs_pin_at_least": {
"anyOf": [
{
"$ref": "#/$defs/NeedsPin"
},
{
"type": "null"
}
]
},
"suggested_replacement": {
"anyOf": [
{
"$ref": "#/$defs/SymbolRef"
},
{
"type": "null"
}
]
},
"symbol": {
"$ref": "#/$defs/SymbolRef"
}
},
"required": [
"kind",
"symbol"
],
"type": "object"
},
{
"properties": {
"expected": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"expected_available_at": {
"description": "Earliest snapshot tag strictly later than the pin exporting\nthe expected arity. Same bump-first semantics as\n`MissingSymbol::first_seen_at_tag`.",
"type": [
"string",
"null"
]
},
"found": {
"items": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"type": "array"
},
"function": {
"type": "string"
},
"kind": {
"const": "arity_changed",
"type": "string"
},
"module": {
"type": "string"
},
"needs_pin_at_least": {
"anyOf": [
{
"$ref": "#/$defs/NeedsPin"
},
{
"type": "null"
}
]
}
},
"required": [
"kind",
"module",
"function",
"expected",
"found"
],
"type": "object"
},
{
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"expected_spec": {
"type": "string"
},
"found_spec": {
"type": "string"
},
"function": {
"type": "string"
},
"kind": {
"const": "signature_changed",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function",
"arity",
"expected_spec",
"found_spec"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "file_absent",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "context_drift",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index"
],
"type": "object"
},
{
"description": "The contiguous preimage block (Context and Removed lines from\nthe hunk) was found verbatim at a different starting line.\nCherry-pick adapters handle this with the `-x` trailer; the\noperator just needs the delta to confirm the patch's intent\nstill applies.",
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "preimage_drifted",
"type": "string"
},
"line_delta": {
"format": "int",
"type": "integer"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index",
"line_delta"
],
"type": "object"
},
{
"description": "The hunk's preimage matches, but its added lines land at a file\nedge where the target already has divergent content the base\nlacked: an add/add a contiguous preimage match cannot detect. The\n3-way cherry-pick conflicts where the preimage-only check reads\nclean. Non-blocking: the operator resolves the overlap.",
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "postimage_collision",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index"
],
"type": "object"
},
{
"description": "The preimage block does not appear anywhere in the file. The\npatch was authored against a tree where the lines existed; on\nthis pin they don't. Structurally inapplicable: the operator\nneeds an excerpt to reason about why.",
"properties": {
"hunk_index": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "preimage_missing",
"type": "string"
},
"path": {
"type": "string"
},
"preimage_excerpt": {
"type": "string"
}
},
"required": [
"kind",
"path",
"hunk_index",
"preimage_excerpt"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "deprecated_usage",
"type": "string"
},
"replacement": {
"anyOf": [
{
"$ref": "#/$defs/SymbolRef"
},
{
"type": "null"
}
]
},
"since": {
"type": [
"string",
"null"
]
},
"symbol": {
"$ref": "#/$defs/SymbolRef"
}
},
"required": [
"kind",
"symbol"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "now_hidden",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module"
],
"type": "object"
},
{
"properties": {
"expected": {
"items": {
"type": "string"
},
"type": "array"
},
"found": {
"items": {
"type": "string"
},
"type": "array"
},
"kind": {
"const": "record_fields_changed",
"type": "string"
},
"record": {
"type": "string"
}
},
"required": [
"kind",
"record",
"expected",
"found"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "unsupported_file_type",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "untracked_module_missing",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module"
],
"type": "object"
},
{
"description": "Call-site argument shapes don't satisfy any clause head at the\npin. Emitted when both the call and the pin's clause patterns\nare concrete enough to compare; `Unknown` on either side\nsuppresses the reason.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"call_args": {
"items": {
"$ref": "#/$defs/ArgShape"
},
"type": "array"
},
"function": {
"type": "string"
},
"kind": {
"const": "clause_mismatch",
"type": "string"
},
"module": {
"type": "string"
},
"pin_clauses": {
"items": {
"items": {
"$ref": "#/$defs/ArgShape"
},
"type": "array"
},
"type": "array"
}
},
"required": [
"kind",
"module",
"function",
"arity",
"call_args",
"pin_clauses"
],
"type": "object"
},
{
"description": "Patch references an MFA owned by the self-project but absent from the\nresolved self-snapshot. `suggested_source_for_prereq` is filled only\nwith `--suggest-prereqs`.",
"properties": {
"kind": {
"const": "missing_prereq",
"type": "string"
},
"self_branch": {
"type": "string"
},
"suggested_source_for_prereq": {
"type": [
"string",
"null"
]
},
"symbol": {
"$ref": "#/$defs/SymbolRef"
}
},
"required": [
"kind",
"symbol",
"self_branch"
],
"type": "object"
},
{
"description": "Pre-flight syntactic damage in a touched file: an unresolved\nmerge-conflict marker, an exported function with no definition, etc.",
"properties": {
"artifact": {
"$ref": "#/$defs/ArtifactKind"
},
"kind": {
"const": "syntactic_artifact",
"type": "string"
},
"line": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"line",
"artifact"
],
"type": "object"
},
{
"description": "Patch changes a `-callback` signature; an implementer still has the old one.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"expected_after_patch": {
"type": "string"
},
"implementer": {
"type": "string"
},
"implementer_signature": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_signature_changed",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"expected_after_patch",
"implementer",
"implementer_signature"
],
"type": "object"
},
{
"description": "Patch removes a required callback; implementer still exports it.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_removed",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"implementer"
],
"type": "object"
},
{
"description": "Patch adds a required callback; implementer is missing the export.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_added",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"implementer"
],
"type": "object"
},
{
"description": "Patch touches a path absent on pin, but a module of the same basename exists elsewhere.",
"properties": {
"kind": {
"const": "module_relocated",
"type": "string"
},
"module": {
"type": "string"
},
"patch_path": {
"type": "string"
}
},
"required": [
"kind",
"module",
"patch_path"
],
"type": "object"
},
{
"description": "Wire-bearing macro value differs between source and pin.",
"properties": {
"after": {
"type": "string"
},
"before": {
"type": "string"
},
"kind": {
"const": "wire_constant_changed",
"type": "string"
},
"macro_name": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"macro_name",
"before",
"after"
],
"type": "object"
},
{
"description": "`version/0` advanced without the matching historical-implementation module.",
"properties": {
"advertised_version_after": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"advertised_version_before": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"expected_historical_module": {
"type": "string"
},
"kind": {
"const": "historical_implementation_missing",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"advertised_version_before",
"advertised_version_after",
"expected_historical_module"
],
"type": "object"
},
{
"description": "Function bodies drifted at the same advertised `version/0`. Mixed-version cluster risk.",
"properties": {
"advertised_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"functions": {
"items": {
"type": "string"
},
"type": "array"
},
"kind": {
"const": "wire_contract_body_drift",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"functions",
"advertised_version"
],
"type": "object"
},
{
"description": "`version/0` decreased pin → patch.",
"properties": {
"kind": {
"const": "wire_contract_regression",
"type": "string"
},
"module": {
"type": "string"
},
"patch_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"pin_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"kind",
"module",
"pin_version",
"patch_version"
],
"type": "object"
},
{
"description": "Spec return shape differs between source and pin for a referenced MFA.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "return_shape_mismatch",
"type": "string"
},
"module": {
"type": "string"
},
"pin_signature": {
"type": "string"
},
"source_signature": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function",
"arity",
"source_signature",
"pin_signature"
],
"type": "object"
},
{
"description": "A type-reference inside a `-spec`, `-callback`, `-type`, or\n`-opaque` attribute resolves to a name and arity that the pin\ndoes not expose via `-export_type`. Non-blocking: a missing\ntype alias is a dialyzer-level concern, not a load-time crash.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "missing_type",
"type": "string"
},
"module": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"module",
"name",
"arity"
],
"type": "object"
},
{
"description": "A touched path is absent from the target tree, but a\nconfigured `[[path_translation]]` rewrites it to a path that\ndoes exist on the target. Non-blocking: the operator (or the\ncherry-pick driver) rewrites the path before applying.",
"properties": {
"kind": {
"const": "path_rename",
"type": "string"
},
"source_path": {
"type": "string"
},
"target_path": {
"type": "string"
},
"translation": {
"$ref": "#/$defs/TranslationSource"
}
},
"required": [
"kind",
"source_path",
"target_path",
"translation"
],
"type": "object"
},
{
"description": "A touched path is absent on the target while others are present\nand no `[[path_translation]]` rewrites it. Non-blocking: dropping\nthe hunks for this path lets the rest apply. The all-absent case\nis `InapplicableReason::PathsMissingOnTarget`.",
"properties": {
"kind": {
"const": "target_path_absent",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"description": "A `_SUITE.erl` file in the patch references `missing_module:f/n`\nwhere `missing_module` resolves to no source file under any\nconfigured `FamilyDefaults.test_helper_search_paths` on the\ntarget tree. The cherry-pick compiles and the SUITE may even\nload, but every call to the missing helper crashes at runtime:\nthe failure pattern seen in the Jun 2026 v4.1.x → v4.0.x round\n(the `amqp_utils:connection_config/1` undef in\n`amqp10_connection_max_SUITE`). Non-blocking by default: the\ndiagnostic equivalent (`Diagnostics.missing_test_modules`)\nalways fires; the `Reason` variant fires only when\n`--target-repo-dir-path` is supplied and the resolution is\nauthoritative.",
"properties": {
"call_sites": {
"items": {
"$ref": "#/$defs/TestCallSite"
},
"type": "array"
},
"kind": {
"const": "test_module_symbol_missing",
"type": "string"
},
"missing_module": {
"type": "string"
},
"suite_path": {
"type": "string"
}
},
"required": [
"kind",
"suite_path",
"missing_module",
"call_sites"
],
"type": "object"
},
{
"description": "A touched `.erl` declares `-behaviour(behaviour)` (or\n`-behavior(...)`) where `behaviour` resolves to no source\nmodule on the target tree. `erlc` compiles with a warning,\nthen hook dispatch crashes at runtime. The `BehaviourCallback*`\nvariants model implementer drift; this one catches the\nmissing-behaviour-module case they do not.",
"properties": {
"behaviour": {
"type": "string"
},
"kind": {
"const": "behaviour_module_missing",
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"behaviour"
],
"type": "object"
},
{
"description": "A touched `.erl` or `.hrl` declares `-include(path)` or\n`-include_lib(app/include/file.hrl)` against a target tree that\ndoes not ship the resolved header. Compile-time failure rather\nthan runtime, but same user-facing shape as\n`TestModuleSymbolMissing`: looked fine on source, broken on\ntarget.",
"properties": {
"attempted_paths": {
"items": {
"type": "string"
},
"type": "array"
},
"include_directive": {
"$ref": "#/$defs/IncludeDirective"
},
"kind": {
"const": "header_file_missing",
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"include_directive",
"attempted_paths"
],
"type": "object"
},
{
"description": "A touched `.erl` or `.hrl` file references `?MACRO` on an added\nline, but `MACRO` is defined nowhere the target tree reaches (not\nin the file, its includes, or the patch itself) and is not\npredefined. Compiles on source, dangles on target. Non-blocking:\nthe operator drops or adapts the reference.",
"properties": {
"kind": {
"const": "macro_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"macro_name": {
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"macro_name",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` or `.hrl` file uses `#record{}` on an added\nline, but `record` is defined nowhere the target tree reaches and\nis not added by the patch. Same check as `MacroUndefinedOnTarget`\nfor the record namespace; non-blocking.",
"properties": {
"kind": {
"const": "record_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"record_name": {
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"record_name",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` file calls an unqualified `f/a` on an added line\nthat the target version of the same module neither defines,\nexports, imports, nor inherits as an auto-imported BIF. The\nsame check for the function namespace; non-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "local_call_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"function",
"arity",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` file calls a qualified `m:f/a` on an added line\nwhose module is a first-party module present on the target tree,\nbut the target version of that module does not export `f/a` (and\nthe patch does not add it). The qualified form of\n`LocalCallUndefinedOnTarget`, resolved against the called\nmodule's exports. Withheld when any pin snapshot already covers\nthe module, when it is absent from the tree, or when its export\nsurface is not fully readable. Non-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "qualified_call_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"module": {
"type": "string"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"module",
"function",
"arity",
"line"
],
"type": "object"
},
{
"description": "A qualified `m:f/a` call that resolves against the target tree\nhas a target-tree `-spec` return shape that disagrees with its\nsource-tree `-spec`. Same comparison as `ReturnShapeMismatch` on\nthe live, snapshot-free first-party axis: same comparator,\nnon-blocking like the rest of that axis. Only evaluated once the\ncall is confirmed to resolve; withheld when either side lacks a\n`-spec`.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "qualified_call_return_shape_drift",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"module": {
"type": "string"
},
"source_path": {
"type": "string"
},
"source_signature": {
"type": "string"
},
"target_signature": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"module",
"function",
"arity",
"source_signature",
"target_signature",
"line"
],
"type": "object"
},
{
"description": "An unqualified call that resolves against the target module's\nown definitions has a target-tree `-spec` return shape that\ndisagrees with its source-tree `-spec`. The local-call form of\n`QualifiedCallReturnShapeDrift`; imported resolutions are\nwithheld, since the callee's spec is in another module.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "local_call_return_shape_drift",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
},
"source_signature": {
"type": "string"
},
"target_signature": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"function",
"arity",
"source_signature",
"target_signature",
"line"
],
"type": "object"
},
{
"description": "A `?MACRO` the patch uses is defined in the touched file itself\non both trees, exactly once each, and the normalized `-define`\nbodies disagree: the compile-clean, behavior-divergent class.\nWithheld for definitions reached any other way. Non-blocking.",
"properties": {
"kind": {
"const": "macro_value_drift",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"macro_name": {
"type": "string"
},
"source_path": {
"type": "string"
},
"source_value": {
"type": "string"
},
"target_value": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"macro_name",
"source_value",
"target_value",
"line"
],
"type": "object"
},
{
"description": "The target's version of a behaviour the patch declares requires\na callback the source's version does not, and the target does\nnot list it as optional: an implementation written against the\nsource is missing it. `line` is the `-behaviour` attribute's\nline in the touched file. Non-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_added_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"behaviour",
"callback",
"arity",
"line"
],
"type": "object"
},
{
"description": "A callback both trees' versions of a declared behaviour declare\nhas a different normalized signature on the target. The whole\nsignature is compared, not just the return half: a callback\ncontract's argument types are the implementer's obligation.\nNon-blocking.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_drift_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
},
"source_signature": {
"type": "string"
},
"target_signature": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"behaviour",
"callback",
"arity",
"source_signature",
"target_signature",
"line"
],
"type": "object"
},
{
"description": "Declared versioned-machine module is touched but the snapshot\nhas no recorded `versioned_machine_version` on `side`.\nNon-blocking.",
"properties": {
"kind": {
"const": "versioned_machine_snapshot_missing",
"type": "string"
},
"module": {
"type": "string"
},
"side": {
"$ref": "#/$defs/SnapshotSide"
}
},
"required": [
"kind",
"module",
"side"
],
"type": "object"
},
{
"description": "Declared wire constants are touched but the snapshot's\n`wire_constants` vector lacks the listed macros on `side`.\n`macros` is sorted alphabetically. Non-blocking.",
"properties": {
"kind": {
"const": "wire_constant_bindings_missing",
"type": "string"
},
"macros": {
"items": {
"type": "string"
},
"type": "array"
},
"module": {
"type": "string"
},
"side": {
"$ref": "#/$defs/SnapshotSide"
}
},
"required": [
"kind",
"module",
"macros",
"side"
],
"type": "object"
},
{
"description": "A first-party `m:f/a` referenced as arguments to a mocking or\nrpc form (a meck expectation, `rpc:call`, `erpc:call`, or a CT\nbroker rpc helper) is neither exported nor defined by the target\ntree's module. Non-blocking: a meck expectation can install a\nfunction the module never had, so absence proves drift, not\nfailure.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "indirect_call_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"module": {
"type": "string"
},
"source_path": {
"type": "string"
},
"via": {
"$ref": "#/$defs/IndirectCallForm"
}
},
"required": [
"kind",
"source_path",
"module",
"function",
"arity",
"via",
"line"
],
"type": "object"
},
{
"description": "A touched `.erl` file adds an `-export_type([t/a])` entry naming\na type neither the target version of the same module declares\nnor the patch adds. An `erlc` error, unlike `MissingType`, which\nis dialyzer-level; non-blocking regardless, being a target-tree\nfinding rather than a pin verdict. Withheld when the target file\nis unreadable or declares a `parse_transform`, or when the added\nlist names a macro.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "exported_type_undefined_on_target",
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"source_path": {
"type": "string"
},
"type_name": {
"type": "string"
}
},
"required": [
"kind",
"source_path",
"type_name",
"arity",
"line"
],
"type": "object"
},
{
"description": "A touched implementer of a family-declared dependency behaviour\n(`FamilyDefaults.dep_behaviours`) exports a callback the pinned\nbehaviour does not declare. The callback compiles but is never\ninvoked at this pin. Non-blocking: the operator judges whether\nthe backport still does anything useful without it.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"evidence": {
"$ref": "#/$defs/DriftEvidence"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_unknown_on_pin",
"type": "string"
},
"pin_arities": {
"items": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"type": "array"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"pin_arities",
"implementer",
"evidence"
],
"type": "object"
},
{
"description": "An added implementer of a family-declared dependency behaviour\nlacks a callback the pinned behaviour requires. Blocking: the\nmissing callback crashes the first time the behaviour invokes it.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"behaviour": {
"type": "string"
},
"callback": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_callback_missing_on_pin",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"callback",
"arity",
"implementer"
],
"type": "object"
},
{
"description": "An added line uses a map key that a family-declared option type\n(`FamilyDefaults.option_types`) gained after the pinned version.\nNon-blocking: an unrecognized key is typically ignored by the\nolder dependency rather than rejected.",
"properties": {
"key": {
"type": "string"
},
"kind": {
"const": "option_key_unknown_on_pin",
"type": "string"
},
"module": {
"type": "string"
},
"pin_tag": {
"type": "string"
},
"project": {
"type": "string"
},
"type_name": {
"type": "string"
}
},
"required": [
"kind",
"project",
"module",
"type_name",
"key",
"pin_tag"
],
"type": "object"
},
{
"description": "The patch adds a test suite to an app whose Makefile dispatches\nsuites by explicit registration (`FamilyDefaults.suite_registration`)\nwithout registering it there. Non-blocking: the suite still\ncompiles, it just never runs under CI.",
"properties": {
"kind": {
"const": "suite_not_registered_for_ct",
"type": "string"
},
"makefile_path": {
"type": "string"
},
"suite_path": {
"type": "string"
}
},
"required": [
"kind",
"suite_path",
"makefile_path"
],
"type": "object"
},
{
"description": "An introduced cuttlefish schema mapping uses an attribute the\npinned cuttlefish version does not support. Blocking: the\ncorpus evidence for this shape is a boot failure.",
"properties": {
"conf_key": {
"type": [
"string",
"null"
]
},
"feature": {
"type": "string"
},
"kind": {
"const": "schema_feature_unsupported_on_pin",
"type": "string"
},
"pinned_version": {
"type": "string"
},
"required_version": {
"type": "string"
},
"schema_path": {
"type": "string"
}
},
"required": [
"kind",
"schema_path",
"feature",
"required_version",
"pinned_version"
],
"type": "object"
},
{
"description": "An introduced cuttlefish schema mapping targets an application\nenvironment key that nothing in the target tree's owning apps\nreads. Non-blocking: the token search is deliberately crude, so\nthe operator reviews before trusting a positive.",
"properties": {
"absent_apps": {
"description": "Apps the key names that do not exist on the target tree at\nall: a stronger form of the same finding.",
"items": {
"type": "string"
},
"type": "array"
},
"kind": {
"const": "schema_key_reader_missing",
"type": "string"
},
"schema_path": {
"type": "string"
},
"searched_apps": {
"items": {
"type": "string"
},
"type": "array"
},
"target_key": {
"type": "string"
}
},
"required": [
"kind",
"schema_path",
"target_key",
"searched_apps",
"absent_apps"
],
"type": "object"
}
]
},
"RefOrigin": {
"description": "Which side of the hunk a reference was extracted from. `Added`\nlines are requirements the patch introduces; `Context` lines are\npre-existing facts about the target and never drive verdicts.\n`Added` orders first so a kind-level dedup keeps the stronger\norigin.",
"enum": [
"added",
"context"
],
"type": "string"
},
"ResolverClass": {
"description": "A class of symbol whose presence a backport can dangle on.",
"enum": [
"macro",
"include",
"behaviour",
"qualified_call",
"record",
"local_call",
"type",
"indirect_call"
],
"type": "string"
},
"ResolverCoverage": {
"description": "The set of classes a producer checks, stamped on a verdict envelope\nso a corpus row self-describes its producer's coverage. Stores only\nthe checked set: `unchecked` is derived, so a class can never be in\nboth or neither.",
"properties": {
"checked": {
"items": {
"$ref": "#/$defs/ResolverClass"
},
"type": "array",
"uniqueItems": true
}
},
"required": [
"checked"
],
"type": "object"
},
"SeriesSummary": {
"properties": {
"compatible": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"inapplicable": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"incompatible": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"requires_adaptation": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"compatible",
"requires_adaptation",
"incompatible"
],
"type": "object"
},
"SeriesVerdict": {
"properties": {
"results": {
"items": {
"$ref": "#/$defs/PinVerdict"
},
"type": "array"
},
"summary": {
"$ref": "#/$defs/SeriesSummary"
}
},
"required": [
"results",
"summary"
],
"type": "object"
},
"ShapeCheckTally": {
"description": "What the live qualified-call gate's return-shape check did with\neach first-party resolved call. Never reasons: a withhold is not a\nfinding, but a round where most calls are shape-blind must read\ndifferently from a round where all of them were compared.",
"properties": {
"compared": {
"description": "Both sides had a `-spec` that parsed to a known type; the shapes\nwere compared. Drift is visible in the reasons, not double-counted\nhere.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_imported": {
"description": "The call resolved through an `-import`: the callee's `-spec`\nis in another module, so the calling module's tables cannot\ncompare it. Local-call axis only.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_no_source": {
"description": "The callee module was not readable on the source side: no\ncheckout was supplied, or the checkout has no file at the\nmodule's path (a defaulted `--repo-dir-path` that is not the\nsource tree lands here, not in `withheld_no_spec`).",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_no_spec": {
"description": "One or both sides declare no `-spec` for the called function.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"withheld_unknown_type": {
"description": "Both sides have a spec but at least one parses to\n`SpecType::Unknown`.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"SnapshotSide": {
"description": "Which side of a snapshot comparison the data is missing from.",
"enum": [
"source",
"target",
"both"
],
"type": "string"
},
"SourceDelta": {
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"module": {
"type": "string"
},
"source_spec": {
"type": "string"
},
"target_spec": {
"type": "string"
}
},
"required": [
"module",
"function",
"arity",
"source_spec",
"target_spec"
],
"type": "object"
},
"SymbolRef": {
"oneOf": [
{
"properties": {
"kind": {
"const": "behaviour",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module"
],
"type": "object"
},
{
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"kind": {
"const": "callback",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function",
"arity"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "function",
"type": "string"
},
"mfa": {
"$ref": "#/$defs/Mfa"
}
},
"required": [
"kind",
"mfa"
],
"type": "object"
},
{
"description": "A function reference whose arity could not be determined from\nthe source line (the call's closing paren sits on a later\nline). Resolves against a snapshot when *any* export carries\nthe name; never produces an arity mismatch.",
"properties": {
"function": {
"type": "string"
},
"kind": {
"const": "function_any_arity",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"module",
"function"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "macro",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "record",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"kind": {
"const": "type",
"type": "string"
},
"module": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"module",
"name",
"arity"
],
"type": "object"
}
],
"properties": {
"origin": {
"$ref": "#/$defs/RefOrigin"
}
},
"type": "object"
},
"TargetFindings": {
"description": "Symbol-axis findings for one row, resolved against the target tree.\nPresent exactly when a target context was supplied; independent of\nevery pin verdict, so an inapplicable row still carries its\nfindings.",
"properties": {
"reasons": {
"description": "Every reason the live-axis target checks produced for this row,\nin production order.",
"items": {
"$ref": "#/$defs/Reason"
},
"type": "array"
}
},
"required": [
"reasons"
],
"type": "object"
},
"TargetMatch": {
"description": "A target commit found to carry the candidate's patch. The subject\nis included so consumers can auto-fill exclusion reasons without\na second git query.",
"properties": {
"commit": {
"type": "string"
},
"subject": {
"type": "string"
},
"via": {
"$ref": "#/$defs/TargetMatchKind"
}
},
"required": [
"commit",
"via",
"subject"
],
"type": "object"
},
"TargetMatchKind": {
"description": "How a tier-1 already-present match against the target branch was\nestablished.",
"oneOf": [
{
"const": "trailer_intersection",
"description": "A walked target commit's `-x` trailer names the candidate (or\none of its trailer origins or inner PR commits).",
"type": "string"
},
{
"const": "trailer_ancestry",
"description": "One of the candidate's own trailer origins is already an\nancestor of the target tip.",
"type": "string"
},
{
"const": "patch_id",
"description": "A walked target commit's normalized patch hash equals the\ncandidate's.",
"type": "string"
}
]
},
"TestCallSite": {
"description": "One `Module:Function/Arity` reference inside a `_SUITE.erl` that\nresolves to a module absent on the target tree. Carries the line\nnumber so the operator can jump straight to the call site.",
"properties": {
"arity": {
"format": "uint8",
"maximum": 255,
"minimum": 0,
"type": "integer"
},
"function": {
"type": "string"
},
"line": {
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"function",
"arity",
"line"
],
"type": "object"
},
"TouchedKinds": {
"description": "Per-pin tally of file kinds the patch touched. Lets `promote_inapplicable`\ntell a real green check from a diff with nothing analyzable to check.",
"properties": {
"app_src": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"ci_workflow": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"docs": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"erl": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"hrl": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"makefile": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"mix_exs": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"only_self_surface": {
"description": "The patch touches Erlang surface but references no tracked-dep\nAPI (every non-self pin has zero in-scope references). The CLI\nsets this after `evaluate_series` when a self-pin is present\nand every non-self pin's `tracked_refs` is empty; see\n`InapplicableReason::OnlySelfSurfaceTouched`.",
"type": "boolean"
},
"only_test_visibility": {
"description": "Every changed `.erl` hunk is a Variant A unwrap of test-only\n`-ifdef(TEST)` guards around an `-export` directive (see\n`InapplicableReason::OnlyTestVisibilityChanged`). When true,\nthe patch touches Erlang surface but adds no semantic\ncontent, so an empty reason set should promote to\n`Inapplicable` instead of `Compatible`.",
"type": "boolean"
},
"other": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"rebar_config": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"schema": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"tests": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"TranslationSource": {
"oneOf": [
{
"properties": {
"kind": {
"const": "config_stanza",
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"kind",
"name"
],
"type": "object"
},
{
"properties": {
"kind": {
"const": "external_file",
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path",
"name"
],
"type": "object"
}
]
},
"Unanalyzed": {
"description": "Counts of call sites the analyzer could not resolve: `apply/3`-style\nBIFs, and dispatch through a variable module or function. Informational only.",
"properties": {
"apply": {
"default": 0,
"format": "uint",
"minimum": 0,
"type": "integer"
},
"variable_dispatch": {
"default": 0,
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"UnassessedReason": {
"description": "Why a path's apply outcome could not be assessed. The `Ord` only\nbreaks merge ties deterministically; it is not a severity.",
"oneOf": [
{
"const": "binary_file",
"description": "The diff marks the file binary; there is no hunk text to match.",
"type": "string"
},
{
"const": "target_not_text",
"description": "The target blob exists but is not valid UTF-8.",
"type": "string"
}
]
},
"Verdict": {
"oneOf": [
{
"properties": {
"verdict": {
"const": "compatible",
"type": "string"
}
},
"required": [
"verdict"
],
"type": "object"
},
{
"properties": {
"reasons": {
"items": {
"$ref": "#/$defs/Reason"
},
"type": "array"
},
"verdict": {
"const": "requires_adaptation",
"type": "string"
}
},
"required": [
"verdict",
"reasons"
],
"type": "object"
},
{
"properties": {
"reasons": {
"items": {
"$ref": "#/$defs/Reason"
},
"type": "array"
},
"verdict": {
"const": "incompatible",
"type": "string"
}
},
"required": [
"verdict",
"reasons"
],
"type": "object"
},
{
"properties": {
"reason": {
"$ref": "#/$defs/InapplicableReason"
},
"verdict": {
"const": "inapplicable",
"type": "string"
}
},
"required": [
"verdict",
"reason"
],
"type": "object"
}
]
},
"VerdictFingerprint": {
"description": "A verdict's stable identity for measurement: equal fingerprints\nmean the same patch against the same target and pins, whatever\nbackhopper version produced either side. Thirty-two lowercase hex\ncharacters: a truncated BLAKE3 digest, formatted here so\n`backhopper-core` takes no dependency on `blake3`.",
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "The `{schema_version, command, data, exit_code[, warnings]}` frame.\n\n`command` and `warnings` are lenient on the read side (an older\nproducer may omit either); `warnings` is dropped from the wire when\nempty, matching the CLI, which does not emit it today.",
"properties": {
"command": {
"default": null,
"type": [
"string",
"null"
]
},
"data": {
"$ref": "#/$defs/CheckPayload"
},
"exit_code": {
"default": 0,
"format": "int32",
"type": "integer"
},
"schema_version": {
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"warnings": {
"items": {
"$ref": "#/$defs/EnvelopeWarning"
},
"type": "array"
}
},
"required": [
"schema_version",
"data"
],
"title": "WireEnvelope",
"type": "object"
},
"schema_version": 17,
"suite_plan_payload": {
"$defs": {
"BroadImpactModule": {
"description": "A modified module whose suite fanout is an outsized share of all\ndiscovered suites. The cap drops the suites this module alone pulled\nin and records this row instead, so a near-full selection driven by\none helper is never silent.",
"properties": {
"application": {
"type": [
"string",
"null"
]
},
"module": {
"type": "string"
},
"suite_fanout": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"total_suites": {
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"module",
"suite_fanout",
"total_suites"
],
"type": "object"
},
"SuiteInclusionReason": {
"description": "Why a suite was included in the plan. A suite can appear under\nmultiple reasons when more than one rule fires.",
"oneOf": [
{
"description": "The suite file itself appears in the diff.",
"properties": {
"kind": {
"const": "test_modified",
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"kind",
"path"
],
"type": "object"
},
{
"description": "Fast unit or property suite swept because its application has\nmodified source and the suite references at least one of the\nmodified modules.",
"properties": {
"application": {
"type": "string"
},
"kind": {
"const": "unit_or_prop_sweep",
"type": "string"
},
"triggering_modules": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"kind",
"application",
"triggering_modules"
],
"type": "object"
},
{
"description": "Suite is in the same application as a modified module and\nreferences that module by name.",
"properties": {
"application": {
"type": "string"
},
"kind": {
"const": "same_app_caller",
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"application",
"module"
],
"type": "object"
},
{
"description": "Suite is in a different application from a modified library\nmodule and references that module by name.",
"properties": {
"kind": {
"const": "cross_app_caller",
"type": "string"
},
"library_application": {
"type": "string"
},
"module": {
"type": "string"
}
},
"required": [
"kind",
"library_application",
"module"
],
"type": "object"
},
{
"description": "Suite was included by a user-configured rule.",
"properties": {
"kind": {
"const": "configured_rule",
"type": "string"
},
"rule_name": {
"type": "string"
},
"triggering_path": {
"type": "string"
}
},
"required": [
"kind",
"rule_name",
"triggering_path"
],
"type": "object"
},
{
"description": "A modified `.erl` is itself a behaviour module; this suite\nreferences one of its implementers.",
"properties": {
"behaviour": {
"type": "string"
},
"implementer": {
"type": "string"
},
"kind": {
"const": "behaviour_implementer_sweep",
"type": "string"
}
},
"required": [
"kind",
"behaviour",
"implementer"
],
"type": "object"
}
]
},
"SuitePlanEntry": {
"description": "One entry in the plan: the suite plus every rule that included it.",
"properties": {
"reasons": {
"items": {
"$ref": "#/$defs/SuiteInclusionReason"
},
"type": "array"
},
"suite": {
"$ref": "#/$defs/SuiteRef"
}
},
"required": [
"suite",
"reasons"
],
"type": "object"
},
"SuiteRef": {
"description": "A test-suite module reference. `module` ends in `_SUITE` by\nconvention but the constructor does not enforce this.",
"properties": {
"application": {
"type": "string"
},
"module": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"application",
"module",
"path"
],
"type": "object"
},
"UncoveredApplication": {
"description": "An application with modified source modules that no plan entry\ncovers. Advisory only: the operator picks suites from `suites`\n(or finds the application has none) instead of discovering the\ngap from a silent empty plan.",
"properties": {
"application": {
"type": "string"
},
"discovered_suites": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"modified_modules": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"suites": {
"description": "The application's discovered suites: the operator's candidate\nlist. Empty means the application has no tests at all.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"application",
"modified_modules",
"discovered_suites",
"suites"
],
"type": "object"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Output of `plan()`. Entries are sorted by suite; reasons within\neach entry are in rule-application order.",
"properties": {
"broad_impact": {
"description": "Modules whose suite fanout was capped: each removed the suites it\nalone pulled in, replaced by this row.",
"items": {
"$ref": "#/$defs/BroadImpactModule"
},
"type": "array"
},
"entries": {
"items": {
"$ref": "#/$defs/SuitePlanEntry"
},
"type": "array"
},
"unattributed_paths": {
"description": "Modified paths that resolve to no application, so a plan with\nfewer reasons than inputs is still fully accounted for.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"uncovered": {
"items": {
"$ref": "#/$defs/UncoveredApplication"
},
"type": "array"
}
},
"required": [
"entries"
],
"title": "SuitePlan",
"type": "object"
},
"summary_row": {
"$defs": {
"TouchedKinds": {
"description": "Per-pin tally of file kinds the patch touched. Lets `promote_inapplicable`\ntell a real green check from a diff with nothing analyzable to check.",
"properties": {
"app_src": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"ci_workflow": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"docs": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"erl": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"hrl": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"makefile": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"mix_exs": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"only_self_surface": {
"description": "The patch touches Erlang surface but references no tracked-dep\nAPI (every non-self pin has zero in-scope references). The CLI\nsets this after `evaluate_series` when a self-pin is present\nand every non-self pin's `tracked_refs` is empty; see\n`InapplicableReason::OnlySelfSurfaceTouched`.",
"type": "boolean"
},
"only_test_visibility": {
"description": "Every changed `.erl` hunk is a Variant A unwrap of test-only\n`-ifdef(TEST)` guards around an `-export` directive (see\n`InapplicableReason::OnlyTestVisibilityChanged`). When true,\nthe patch touches Erlang surface but adds no semantic\ncontent, so an empty reason set should promote to\n`Inapplicable` instead of `Compatible`.",
"type": "boolean"
},
"other": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"rebar_config": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"schema": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"tests": {
"default": 0,
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"type": "object"
},
"VerdictKind": {
"description": "Kind-only projection of `Verdict`: drops the variant payloads so a\nsummary row stays single-line.",
"enum": [
"compatible",
"requires_adaptation",
"incompatible",
"inapplicable"
],
"type": "string"
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "One row in the summary output: a compact projection of a single\n`SeriesEvaluation` result. JSON and text formatters share the type.",
"properties": {
"apply_conflicts": {
"default": 0,
"description": "Paths the apply forecast predicts will conflict on the target.\nZero when the forecast is clean or was not evaluated; the\nverdict kind never reflects it, so the row states it itself.",
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"parent_count": {
"default": null,
"description": "Parent count of the evaluated commit; `None` for patch and PR\ninputs (no commit identity) and pre-v7 envelopes.",
"format": "uint32",
"minimum": 1,
"type": [
"integer",
"null"
]
},
"series": {
"default": null,
"description": "The series the row was evaluated against. `None` for\npin-targeted single evaluations and pre-v7 envelopes.",
"type": [
"string",
"null"
]
},
"sha": {
"type": "string"
},
"subject": {
"type": "string"
},
"target_findings": {
"default": 0,
"description": "Symbol-axis findings on the target. Zero when the axis found\nnothing or was not evaluated; the verdict kind on an\nall-inapplicable row never reflects it, so the row states it.",
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"touched": {
"$ref": "#/$defs/TouchedKinds"
},
"tracked": {
"description": "Total tracked-dep symbol references summed over every evaluated\npin. Zero means the patch references no tracked-dep API; the\nrow is safe to skip at a glance.",
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"verdict": {
"$ref": "#/$defs/VerdictKind"
}
},
"required": [
"sha",
"verdict",
"touched",
"tracked",
"subject"
],
"title": "SummaryRow",
"type": "object"
},
"title": "backhopper envelope v17"
}