grafos placements
Inspect the scheduler’s placement log. Each row summarizes one
placement decision with a per-typed-reason rollup of rejected
candidates. Use --json for the full per-candidate detail.
For the full operator runbook including the typed-reason
vocabulary and common jq queries, see the admission and
placement explanations runbook.
grafos placements
Placement log: read `/api/v1/placements` and render the scheduler's recent placement decisions. Each row summarizes one placement decision with a per-typed_reason rollup of rejected candidates (slice-36 vocabulary). Use `--json` for the full per-candidate detail
Usage: grafos placements [OPTIONS]
Options: --fabric <FABRIC> Fabric address (host:port). Overrides GRAFOS_FABRIC env var [env: GRAFOS_FABRIC=] --scheduler <SCHEDULER> Scheduler URL. Falls back to `GRAFOS_SCHEDULER`, then to the Tenura-hosted credentials when that context applies [env: GRAFOS_SCHEDULER=] --bearer <BEARER> FabricAdmin bearer token (alternative to mTLS) [env: GRAFOS_BEARER=] --cert <CERT> Client certificate (PEM) for mTLS [env: GRAFOS_CERT=] --wide Show additional columns in table output --key <KEY> Client private key (PEM) matching --cert [env: GRAFOS_KEY=] --no-color Disable color output --ca <CA> CA bundle (PEM) used to verify the scheduler's TLS cert [env: GRAFOS_CA=] --pool <POOL> Pool name (default: "default") [default: default] --limit <LIMIT> Maximum rows to render in table mode. JSON mode returns every entry the scheduler reported [default: 50] --reason <REASON> Filter to placements that contain at least one rejected candidate whose `typed_reason` matches one of the supplied snake_case labels. Repeatable: `--reason placement_policy_excluded --reason node_address_unknown` matches either. Unknown labels fail the parse with a typed error listing every valid label --json Emit JSON. The body is byte-passthrough of the scheduler's response so existing `jq` scripts keep working unchanged. JSON mode is the only path that surfaces per-candidate `typed_reason` today; the table mode summarizes at the placement level -h, --help Print help -V, --version Print versionPer-candidate typed reasons
Each rejected candidate in the placement log carries a stable
typed_reason snake_case label. The default table mode rolls
candidates up by reason; --json exposes the per-candidate
detail.
Placement-specific labels (in addition to the admission-side set):
placement_policy_excluded— top-level placement authorization, active-degradation set exclusion, or pinned-strategy mismatch. Prosereasonscarries the specific sub-reason; SIEM rules alert on the typed label across all of them.node_address_unknown— operational state, scheduler doesn’t have a control-plane address for the candidate. Distinct from policy exclusions so dashboards alert on the two classes separately.
Default table format
TIMESTAMP | TENANT | RESOURCE | BYTES | STRATEGY | OUTCOME | CHOSEN | CANDIDATESThe CANDIDATES column rolls up rejected candidates by
typed_reason in alphabetical order:
1 accepted1 accepted, 3 rejected (node_address_unknown:1, placement_policy_excluded:2)Operators scanning the table see the dominant rejection
class without needing --json.
Common jq queries
# Per-candidate rejection rollup across all placement records.grafos placements --json \ | jq -r '.[].candidate_explanations[] | select(.decision == "rejected") | .typed_reason' \ | sort | uniq -c | sort -rn
# Placements where ALL candidates were rejected.grafos placements --json \ | jq '.[] | select( [.candidate_explanations[] | select(.decision == "accepted")] | length == 0)'