Skip to content

reasoning.explain

One reasoning record with the whole chain of its assessment: the uncertainty and its evidence, the plan and who it selected or why nobody, each consultation, each disagreement and the experiment that settled it, the conclusion and its validation — the provenance of a decision without the conversation that produced it.

One reasoning record with the whole chain of its assessment: the uncertainty and its evidence, the plan and who it selected or why nobody, each consultation, each disagreement and the experiment that settled it, the conclusion and its validation — the provenance of a decision without the conversation that produced it.

Exposure

Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.

surfaceas
MCPtool majordomus_reasoning_explain
HTTPGET /api/v1/reasoning/explain operationId reasoning.explain
command linemajordomus reasoning explain

Schemas

The canonical input and output, from the Rust types; the MCP tool schema and the OpenAPI parameters and responses are derived from these.

input · ReasoningExplainInput

The input of reasoning.explain: the id of the record whose assessment chain is explained. An id no record carries is a not-found answer.

use majordomus_cli::capability::builtin::reasoning::ReasoningExplainInput;

let input: ReasoningExplainInput = serde_json::from_str(r#"{"id":"conclusion-1"}"#).unwrap();
assert_eq!(input.id, "conclusion-1");
assert!(serde_json::from_str::<ReasoningExplainInput>("{}").is_err(), "the id is required");
propertytyperequireddescription
id string yes A record id: a conclusion, usually.
JSON Schema
{
  "additionalProperties": false,
  "description": "The input of `reasoning.explain`: the id of the record whose assessment chain is\nexplained. An id no record carries is a not-found answer.\n\n```\nuse majordomus_cli::capability::builtin::reasoning::ReasoningExplainInput;\n\nlet input: ReasoningExplainInput = serde_json::from_str(r#\"{\"id\":\"conclusion-1\"}\"#).unwrap();\nassert_eq!(input.id, \"conclusion-1\");\nassert!(serde_json::from_str::<ReasoningExplainInput>(\"{}\").is_err(), \"the id is required\");\n```",
  "properties": {
    "id": {
      "description": "A record id: a conclusion, usually.",
      "type": "string"
    }
  },
  "required": [
    "id"
  ],
  "title": "ReasoningExplainInput",
  "type": "object"
}

output · ReasoningExplanation

A record with everything it rests on and everything that rests on it.

It carries the record itself, the assessment it belongs to, and that assessment's whole provenance chain as timeline steps in order. A record that belongs to no assessment has a chain of itself alone.

#### use majordomus_cli::reasoning::record::ReasoningRecord;
#### use serde_json::json;
#### fn rec(id: &str, n: u32, body: serde_json::Value) -> ReasoningRecord {
####     serde_json::from_value(json!({
####         "schema": "majordomus/reasoning-record", "version": 1, "id": id, "task": "t",
####         "recorded_at": format!("2026-10-01T00:00:{n:02}Z"), "body": body,
####     }))
####     .unwrap()
#### }
use majordomus_cli::reasoning::state::{explain, ReasoningExplanation};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("attempt-1", 1, json!({
    "kind": "attempt", "attempt": "inline it", "observed_failure": "still slow",
})));
let e: ReasoningExplanation = explain(&loaded, "attempt-1").unwrap();
assert_eq!(e.record.id, "attempt-1");
assert_eq!(e.assessment, None);
assert_eq!(e.chain.len(), 1);
propertytyperequireddescription
assessment string | null no The assessment it belongs to, when it belongs to one.
chain array yes Every record of that assessment, in order: its provenance chain.
record reference yes The record asked about.
JSON Schema
{
  "$defs": {
    "AdvisorCircuit": {
      "description": "An open circuit: the consultation that opened it, the failures behind it, and when it\ncloses. Derived from the records and the clock, never stored.\n\n```\nuse majordomus_cli::reasoning::availability::*;\nuse majordomus_cli::reasoning::catalogue::{AdvisorCatalogue, References};\nuse majordomus_cli::reasoning::record::ConsultationStatus;\n\nstruct All;\nimpl Presence for All {\n    fn executable(&self, _: &str) -> bool { true }\n    fn variable(&self, _: &str) -> bool { true }\n}\nlet c: AdvisorCatalogue = majordomus_cli::metadata::yaml::parse_into(\n    \"version: 1\\ncapabilities:\\n  - id: code_review\\n    description: x\\nadvisors:\\n  - id: a\\n    title: A\\n    transport: cli\\n    adapter: a-cli\\n    executable: a\\n    capabilities: [code_review]\\n\",\n).unwrap();\nlet limited = [Outcome {\n    id: \"consultation-1\".into(), advisor: \"a\".into(),\n    status: ConsultationStatus::RateLimited, at: 0, retry_after: Some(60),\n}];\nlet refs = References::default();\nlet states = derive_availability(&c, &Inputs {\n    refs: &refs, presence: &All, mode: ReasoningMode::Standard, disabled: &[],\n    history: &limited, peers: &[], now: 10, cooldown: None,\n});\nlet circuit: &AdvisorCircuit = states[0].circuit.as_ref().unwrap();\nassert_eq!(circuit.opened_by, \"consultation-1\");\nassert_eq!(circuit.until, \"1970-01-01T00:01:00Z\");\n```",
      "properties": {
        "failures": {
          "description": "The consecutive failures behind it.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "opened_by": {
          "description": "The consultation outcome that opened it.",
          "type": "string"
        },
        "until": {
          "description": "When it closes again, RFC 3339.",
          "type": "string"
        }
      },
      "required": [
        "opened_by",
        "failures",
        "until"
      ],
      "type": "object"
    },
    "AdvisorState": {
      "description": "One advisor as it stands now: what the catalogue declares of it, its status, the one\nmachine word saying why, and what was probed. The row `reasoning.advisors` reports and\nthe policy plans over.\n\n```\nuse majordomus_cli::reasoning::availability::*;\nuse majordomus_cli::reasoning::catalogue::{AdvisorCatalogue, References};\n\nstruct Nothing;\nimpl Presence for Nothing {\n    fn executable(&self, _: &str) -> bool { false }\n    fn variable(&self, _: &str) -> bool { false }\n}\nlet c: AdvisorCatalogue = majordomus_cli::metadata::yaml::parse_into(\n    \"version: 1\\ncapabilities:\\n  - id: code_review\\n    description: x\\nadvisors:\\n  - id: a\\n    title: A\\n    transport: local_runtime\\n    adapter: a-rt\\n    executable: rt\\n    capabilities: [code_review]\\n\",\n).unwrap();\nlet refs = References::default();\nlet state: AdvisorState = derive_availability(&c, &Inputs {\n    refs: &refs, presence: &Nothing, mode: ReasoningMode::Standard, disabled: &[],\n    history: &[], peers: &[], now: 0, cooldown: None,\n})\n.remove(0);\nassert_eq!((state.id.as_str(), state.status), (\"a\", AdvisorStatus::Unavailable));\nassert_eq!(state.probe, \"executable rt on PATH\");\nassert!(state.circuit.is_none() && !state.recovering);\n```",
      "properties": {
        "adapter": {
          "description": "The adapter that speaks to it.",
          "type": "string"
        },
        "capabilities": {
          "description": "The advisory capabilities it offers.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "circuit": {
          "anyOf": [
            {
              "$ref": "#/$defs/AdvisorCircuit"
            },
            {
              "type": "null"
            }
          ],
          "description": "The open circuit, when there is one."
        },
        "credential": {
          "description": "The name of the credential variable its adapter reads — a name, never a value.",
          "type": [
            "string",
            "null"
          ]
        },
        "executable": {
          "description": "The executable its adapter runs, when it runs one.",
          "type": [
            "string",
            "null"
          ]
        },
        "id": {
          "description": "The advisor id (a peer is `peer:<runtime>`).",
          "type": "string"
        },
        "model": {
          "description": "The model it asks, when the catalogue names one: what its adapter sends.",
          "type": [
            "string",
            "null"
          ]
        },
        "probe": {
          "description": "What was observed, for a person: which executable, which variable (never a value).",
          "type": "string"
        },
        "reason": {
          "description": "Why, as one machine word: `present`, `executable_not_found`, `credential_absent`,\n`mode_ci`, `mode_offline`, `disabled_by_configuration`, `consecutive_failures`,\n`rate_limited`, `authentication_failed`, `peer_linked`.",
          "type": "string"
        },
        "recovering": {
          "default": false,
          "description": "Available again after an open circuit's cooldown: the next consultation is its test.",
          "type": "boolean"
        },
        "status": {
          "$ref": "#/$defs/AdvisorStatus",
          "description": "Its standing."
        },
        "title": {
          "description": "The human name.",
          "type": "string"
        },
        "transport": {
          "$ref": "#/$defs/AdvisorTransport",
          "description": "How it is reached."
        }
      },
      "required": [
        "id",
        "title",
        "transport",
        "adapter",
        "capabilities",
        "status",
        "reason",
        "probe"
      ],
      "type": "object"
    },
    "AdvisorStatus": {
      "description": "An advisor's standing: whether it may be asked now and, when not, which kind of\nreason keeps it out. Only `available` advisors enter a plan.\n\n```\nuse majordomus_cli::reasoning::availability::AdvisorStatus;\n\nassert_eq!(serde_json::to_value(AdvisorStatus::NotConfigured).unwrap(), \"not_configured\");\nlet s: AdvisorStatus = serde_json::from_str(\"\\\"rate_limited\\\"\").unwrap();\nassert_eq!(s, AdvisorStatus::RateLimited);\n```",
      "oneOf": [
        {
          "const": "available",
          "description": "It may be asked. Presence was observed; whether it answers is learned by asking.",
          "type": "string"
        },
        {
          "const": "unavailable",
          "description": "Not installed: its executable is not on `PATH`.",
          "type": "string"
        },
        {
          "const": "not_configured",
          "description": "Installed or reachable in principle, but its credential is not configured.",
          "type": "string"
        },
        {
          "const": "disabled",
          "description": "Left out by the mode or by an explicit disable.",
          "type": "string"
        },
        {
          "const": "temporarily_failed",
          "description": "Its recent consultations failed; its circuit is open until the cooldown passes.",
          "type": "string"
        },
        {
          "const": "rate_limited",
          "description": "It answered with a rate limit; not asked again until the limit passes.",
          "type": "string"
        }
      ]
    },
    "AdvisorTransport": {
      "description": "How an advisor is reached. The transport decides how its presence is probed (a\ncredential variable, an executable, a mesh link) and whether `offline` mode admits it.\n\n```\nuse majordomus_cli::reasoning::catalogue::AdvisorTransport;\n\nlet t: AdvisorTransport = serde_json::from_str(\"\\\"local_runtime\\\"\").unwrap();\nassert_eq!(t, AdvisorTransport::LocalRuntime);\nassert!(!t.is_remote());\n```",
      "oneOf": [
        {
          "const": "api",
          "description": "A remote API; present when its vendor's credential variable is set.",
          "type": "string"
        },
        {
          "const": "cli",
          "description": "A client tool run as a process; present when its executable is on `PATH`.",
          "type": "string"
        },
        {
          "const": "local_runtime",
          "description": "A model runtime on this machine; present when its executable is on `PATH`.",
          "type": "string"
        },
        {
          "const": "peer",
          "description": "A linked mesh runtime carrying the review feature; present while linked.",
          "type": "string"
        }
      ]
    },
    "AdvisorUsage": {
      "additionalProperties": false,
      "description": "Token counts an adapter reported. Absent when the transport reports none; never\nestimated.\n\nThe state sums these into its totals. A missing count reads as zero, so an adapter\nthat reports only one of the two still records what it reported.\n\n```\nuse majordomus_cli::reasoning::record::AdvisorUsage;\n\nlet u: AdvisorUsage = serde_json::from_str(r#\"{\"input_tokens\": 120}\"#).unwrap();\nassert_eq!(u, AdvisorUsage { input_tokens: 120, output_tokens: 0 });\n```",
      "properties": {
        "input_tokens": {
          "default": 0,
          "description": "Input tokens.",
          "format": "uint64",
          "minimum": 0,
          "type": "integer"
        },
        "output_tokens": {
          "default": 0,
          "description": "Output tokens.",
          "format": "uint64",
          "minimum": 0,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "ConsultationStatus": {
      "description": "How a consultation ended, as the adapter classified it.\n\nOnly a completed consultation carries advice and counts as review; every other status\nis a degradation that is recorded so the state can report it, never hidden. The wire\nform is the snake_case word that `ConsultationStatus::as_str` returns.\n\n```\nuse majordomus_cli::reasoning::record::ConsultationStatus;\n\nlet s: ConsultationStatus = serde_json::from_str(\"\\\"rate_limited\\\"\").unwrap();\nassert_eq!(s, ConsultationStatus::RateLimited);\nassert!(!s.is_transient());\nassert!(ConsultationStatus::Timeout.is_transient());\n```",
      "oneOf": [
        {
          "const": "completed",
          "description": "An answer was received and normalised.",
          "type": "string"
        },
        {
          "const": "timeout",
          "description": "No answer within the time allowed.",
          "type": "string"
        },
        {
          "const": "rate_limited",
          "description": "The advisor refused for rate.",
          "type": "string"
        },
        {
          "const": "auth_failed",
          "description": "The credential was refused.",
          "type": "string"
        },
        {
          "const": "malformed",
          "description": "An answer arrived that could not be normalised.",
          "type": "string"
        },
        {
          "const": "empty",
          "description": "An answer arrived with nothing in it.",
          "type": "string"
        },
        {
          "const": "unavailable",
          "description": "The advisor could not be reached: not running, not answering, gone.",
          "type": "string"
        },
        {
          "const": "cancelled",
          "description": "The session withdrew the request.",
          "type": "string"
        },
        {
          "const": "error",
          "description": "Anything else the adapter could not classify.",
          "type": "string"
        }
      ]
    },
    "DisagreementPosition": {
      "additionalProperties": false,
      "description": "One side of a disagreement: whose position it is, and the position in one line.\n\nThe source is `primary` for the executor, or the id of a completed consultation; the\nstore refuses a position sourced from a consultation that did not complete.\n\n```\nuse majordomus_cli::reasoning::record::DisagreementPosition;\n\nlet p = DisagreementPosition { source: \"primary\".into(), position: \"keep the lock\".into() };\nlet json = serde_json::to_value(&p).unwrap();\nassert_eq!(json, serde_json::json!({ \"source\": \"primary\", \"position\": \"keep the lock\" }));\n```",
      "properties": {
        "position": {
          "description": "The position, in one line.",
          "type": "string"
        },
        "source": {
          "description": "Whose position: `primary`, or a completed consultation's record id.",
          "type": "string"
        }
      },
      "required": [
        "source",
        "position"
      ],
      "type": "object"
    },
    "ExcludedAdvisor": {
      "description": "One advisor left out of the plan, its standing when the plan was made, and why: its\nstatus, a capability it does not offer, or a budget already spent.\n\n```\nuse majordomus_cli::reasoning::availability::{AdvisorState, AdvisorStatus, ModeResolution, ReasoningMode};\nuse majordomus_cli::reasoning::policy::{plan, ExcludedAdvisor, Materiality, PlanRequest};\n\nfn advisor(id: &str, adapter: &str, status: &str) -> AdvisorState {\n    serde_json::from_value(serde_json::json!({\n        \"id\": id, \"title\": id, \"transport\": \"api\", \"adapter\": adapter,\n        \"capabilities\": [\"independent_reasoning\"], \"status\": status,\n        \"reason\": \"present\", \"probe\": \"\",\n    }))\n    .unwrap()\n}\nlet mode = ModeResolution { mode: ReasoningMode::Standard, source: \"default\".into() };\nlet request = PlanRequest { materiality: Materiality::Material, ..Default::default() };\nlet states = [advisor(\"a\", \"x-api\", \"available\"), advisor(\"b\", \"y-api\", \"available\")];\nlet p = plan(&request, &mode, &states);\nlet left: &ExcludedAdvisor = &p.excluded[0];\nassert_eq!((left.advisor.as_str(), left.status), (\"b\", AdvisorStatus::Available));\nassert!(left.reason.contains(\"budget was spent\"));\n```",
      "properties": {
        "advisor": {
          "description": "The advisor id.",
          "type": "string"
        },
        "reason": {
          "description": "Why it is not in the plan.",
          "type": "string"
        },
        "status": {
          "$ref": "#/$defs/AdvisorStatus",
          "description": "Its standing when the plan was made."
        }
      },
      "required": [
        "advisor",
        "status",
        "reason"
      ],
      "type": "object"
    },
    "Materiality": {
      "description": "How much the uncertain decision could matter. Ordered from `trivial` to `critical`:\nwith the mode it sets the review budget, and from `material` up a decision taken alone\ncarries the structured local review.\n\n```\nuse majordomus_cli::reasoning::policy::Materiality;\n\nassert_eq!(Materiality::default(), Materiality::Low);\nassert!(Materiality::Material < Materiality::Critical);\nlet m: Materiality = serde_json::from_str(\"\\\"high\\\"\").unwrap();\nassert_eq!(m, Materiality::High);\n```",
      "oneOf": [
        {
          "const": "trivial",
          "description": "A name, a format, an obvious convention: never reviewed.",
          "type": "string"
        },
        {
          "const": "low",
          "description": "Local and reversible.",
          "type": "string"
        },
        {
          "const": "material",
          "description": "Could affect correctness, an interface, persistent data, concurrency, operations.",
          "type": "string"
        },
        {
          "const": "high",
          "description": "Architecture, security, compatibility or a public contract.",
          "type": "string"
        },
        {
          "const": "critical",
          "description": "Irreversible or destructive, or repository governance itself.",
          "type": "string"
        }
      ]
    },
    "PlanOutcome": {
      "description": "What the plan decided: consult the selected advisors, decide on local evidence, or\nreuse a standing conclusion. Deciding locally is an ordinary outcome, not a failure.\n\n```\nuse majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};\nuse majordomus_cli::reasoning::policy::{plan, Materiality, PlanOutcome, PlanRequest};\n\nlet mode = ModeResolution { mode: ReasoningMode::Ci, source: \"CI\".into() };\nlet request = PlanRequest { materiality: Materiality::Critical, ..Default::default() };\nlet outcome: PlanOutcome = plan(&request, &mode, &[]).outcome;\nassert_eq!(outcome, PlanOutcome::DecideLocally);\nassert_eq!(serde_json::to_value(outcome).unwrap(), \"decide_locally\");\n```",
      "oneOf": [
        {
          "const": "consult",
          "description": "Consult the selected advisors, then conclude.",
          "type": "string"
        },
        {
          "const": "decide_locally",
          "description": "Decide on local evidence; no independent review is called for or none is available.",
          "type": "string"
        },
        {
          "const": "reuse_prior",
          "description": "A standing conclusion already answers this; reuse it rather than ask again.",
          "type": "string"
        }
      ]
    },
    "ReasoningBody": {
      "description": "A stored record's body: the admitted input, with whatever the writer computed.\n\nIt mirrors `ReasoningInput` variant for variant, except that a plan is stored as a\n`StoredPlan` and a conclusion as a `StoredConclusion`. Only the store produces one,\nby admitting an input; its JSON form is tagged by `kind` like the input's.\n\n```\nuse majordomus_cli::reasoning::record::{AssessmentInput, ReasoningBody};\n\nlet body = ReasoningBody::Assessment(AssessmentInput {\n    subject: \"lock scope\".into(),\n    ..Default::default()\n});\nassert_eq!(body.kind(), \"assessment\");\nassert_eq!(serde_json::to_value(&body).unwrap()[\"kind\"], \"assessment\");\n```",
      "oneOf": [
        {
          "additionalProperties": false,
          "description": "A material uncertainty.",
          "properties": {
            "affects": {
              "description": "What the decision could affect: `public_api`, `persistent_data`, `security`,\n`concurrency`, `architecture`, ...",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "assumptions": {
              "description": "What is assumed.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "capabilities": {
              "description": "The advisory capabilities review would need; empty means `independent_reasoning`.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "confidence": {
              "$ref": "#/$defs/ReasoningConfidence",
              "default": "medium",
              "description": "How sure the executor is of its hypothesis."
            },
            "evidence": {
              "description": "The evidence gathered locally.",
              "items": {
                "$ref": "#/$defs/ReasoningEvidence"
              },
              "type": "array"
            },
            "facts": {
              "description": "What is known.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "hypothesis": {
              "description": "The current hypothesis.",
              "type": [
                "string",
                "null"
              ]
            },
            "kind": {
              "const": "assessment",
              "type": "string"
            },
            "materiality": {
              "$ref": "#/$defs/Materiality",
              "default": "low",
              "description": "How much the decision could matter."
            },
            "new_evidence": {
              "default": false,
              "description": "The assessment brings evidence a standing conclusion on the subject did not have,\nso that conclusion does not answer it.",
              "type": "boolean"
            },
            "questions": {
              "description": "What is still open.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "subject": {
              "description": "What is uncertain, as one line. Later assessments of the same subject find the\nconclusions of earlier ones through it.",
              "type": "string"
            }
          },
          "required": [
            "kind",
            "subject"
          ],
          "type": "object"
        },
        {
          "$ref": "#/$defs/StoredPlan",
          "description": "A plan, with its availability snapshot.",
          "properties": {
            "kind": {
              "const": "plan",
              "type": "string"
            }
          },
          "required": [
            "kind"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "One advisor exchange.",
          "properties": {
            "actions": {
              "description": "Actions it recommended.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "advisor": {
              "description": "The advisor asked.",
              "type": "string"
            },
            "assumptions": {
              "description": "Assumptions it identified.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "conclusion": {
              "description": "The advisor's conclusion, summarised. Required when completed, refused otherwise.",
              "type": [
                "string",
                "null"
              ]
            },
            "confidence": {
              "anyOf": [
                {
                  "$ref": "#/$defs/ReasoningConfidence"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Its stated confidence."
            },
            "diagnostic": {
              "description": "The adapter's diagnostic for a failure: a class and a sentence, never a payload.",
              "type": [
                "string",
                "null"
              ]
            },
            "duration_ms": {
              "description": "How long it took, milliseconds.",
              "format": "uint64",
              "minimum": 0,
              "type": [
                "integer",
                "null"
              ]
            },
            "evidence": {
              "description": "The evidence the question carried.",
              "items": {
                "$ref": "#/$defs/ReasoningEvidence"
              },
              "type": "array"
            },
            "falsifiers": {
              "description": "What would falsify its conclusion.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "kind": {
              "const": "consultation",
              "type": "string"
            },
            "plan": {
              "description": "The recorded plan that selected this advisor.",
              "type": "string"
            },
            "question": {
              "description": "The question asked, in one line (the full prompt is not kept).",
              "type": [
                "string",
                "null"
              ]
            },
            "retry_after_seconds": {
              "description": "A rate limit's retry-after, seconds.",
              "format": "uint64",
              "minimum": 0,
              "type": [
                "integer",
                "null"
              ]
            },
            "risks": {
              "description": "Risks it identified.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "stance": {
              "anyOf": [
                {
                  "$ref": "#/$defs/Stance"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Where it stands relative to the hypothesis."
            },
            "status": {
              "$ref": "#/$defs/ConsultationStatus",
              "description": "How it ended."
            },
            "usage": {
              "anyOf": [
                {
                  "$ref": "#/$defs/AdvisorUsage"
                },
                {
                  "type": "null"
                }
              ],
              "description": "What the transport reported it cost."
            }
          },
          "required": [
            "kind",
            "plan",
            "advisor",
            "status"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "A disagreement.",
          "properties": {
            "assessment": {
              "description": "The assessment it is about.",
              "type": "string"
            },
            "discriminating_question": {
              "description": "The question whose answer decides between them.",
              "type": "string"
            },
            "divergent_assumptions": {
              "description": "The assumptions the positions divide on.",
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "experiment": {
              "description": "The experiment proposed to answer it.",
              "type": [
                "string",
                "null"
              ]
            },
            "kind": {
              "const": "disagreement",
              "type": "string"
            },
            "positions": {
              "description": "The positions; at least two.",
              "items": {
                "$ref": "#/$defs/DisagreementPosition"
              },
              "type": "array"
            }
          },
          "required": [
            "kind",
            "assessment",
            "positions",
            "discriminating_question"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "A disagreement settled by evidence.",
          "properties": {
            "disagreement": {
              "description": "The disagreement it settles.",
              "type": "string"
            },
            "evidence": {
              "description": "The evidence it produced; at least one reference.",
              "items": {
                "$ref": "#/$defs/ReasoningEvidence"
              },
              "type": "array"
            },
            "experiment": {
              "description": "The experiment performed.",
              "type": "string"
            },
            "favours": {
              "description": "The position it favours: a `source` of the disagreement, or `neither`.",
              "type": "string"
            },
            "kind": {
              "const": "resolution",
              "type": "string"
            },
            "outcome": {
              "description": "What it showed.",
              "type": "string"
            }
          },
          "required": [
            "kind",
            "disagreement",
            "experiment",
            "outcome",
            "favours",
            "evidence"
          ],
          "type": "object"
        },
        {
          "$ref": "#/$defs/StoredConclusion",
          "description": "An engineering conclusion, with its computed review.",
          "properties": {
            "kind": {
              "const": "conclusion",
              "type": "string"
            }
          },
          "required": [
            "kind"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "A validation step performed.",
          "properties": {
            "check": {
              "description": "What was checked, in one line.",
              "type": "string"
            },
            "command": {
              "description": "The command that checked it.",
              "type": [
                "string",
                "null"
              ]
            },
            "conclusion": {
              "description": "The conclusion validated.",
              "type": "string"
            },
            "evidence": {
              "description": "What it produced.",
              "items": {
                "$ref": "#/$defs/ReasoningEvidence"
              },
              "type": "array"
            },
            "kind": {
              "const": "validation",
              "type": "string"
            },
            "outcome": {
              "$ref": "#/$defs/ValidationOutcome",
              "description": "How it came out."
            }
          },
          "required": [
            "kind",
            "conclusion",
            "check",
            "outcome"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "description": "A failed attempt.",
          "properties": {
            "assessment": {
              "description": "The assessment it bears on, when there is one.",
              "type": [
                "string",
                "null"
              ]
            },
            "assumption_invalidated": {
              "description": "The assumption the failure invalidated.",
              "type": [
                "string",
                "null"
              ]
            },
            "attempt": {
              "description": "What was tried.",
              "type": "string"
            },
            "evidence": {
              "description": "Evidence the failure produced.",
              "items": {
                "$ref": "#/$defs/ReasoningEvidence"
              },
              "type": "array"
            },
            "kind": {
              "const": "attempt",
              "type": "string"
            },
            "observed_failure": {
              "description": "What failed, observed.",
              "type": "string"
            },
            "updated_hypothesis": {
              "description": "The hypothesis now.",
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "kind",
            "attempt",
            "observed_failure"
          ],
          "type": "object"
        }
      ]
    },
    "ReasoningConfidence": {
      "description": "How sure the primary executor is of its current hypothesis. `high` lowers the review\nbudget by one; the other levels leave it as the mode and materiality set it.\n\n```\nuse majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};\nuse majordomus_cli::reasoning::policy::{plan, Materiality, PlanRequest, ReasoningConfidence};\n\nlet mode = ModeResolution { mode: ReasoningMode::Strict, source: \"default\".into() };\nlet budget = |confidence: ReasoningConfidence| {\n    let request = PlanRequest { materiality: Materiality::Critical, confidence, ..Default::default() };\n    plan(&request, &mode, &[]).budget\n};\nassert_eq!(budget(ReasoningConfidence::Medium), 3);\nassert_eq!(budget(ReasoningConfidence::High), 2);\n```",
      "oneOf": [
        {
          "const": "low",
          "description": "A guess the evidence does not yet support.",
          "type": "string"
        },
        {
          "const": "medium",
          "description": "Supported, with open questions.",
          "type": "string"
        },
        {
          "const": "high",
          "description": "Supported by evidence that would be hard to overturn.",
          "type": "string"
        }
      ]
    },
    "ReasoningEvidence": {
      "additionalProperties": false,
      "description": "A reference to something that supports a claim.\n\nEvidence is a pointer, never a copy: a path, a case, an id or a command line, with an\noptional one-line note of what it shows. Unknown fields are refused, so a misspelt\nfield is an error rather than a silently dropped claim.\n\n```\nuse majordomus_cli::reasoning::record::{ReasoningEvidence, ReasoningEvidenceKind};\n\nlet e: ReasoningEvidence = serde_json::from_value(serde_json::json!({\n    \"kind\": \"file\",\n    \"reference\": \"src/worker.rs:42\",\n}))\n.unwrap();\nassert_eq!(e.kind, ReasoningEvidenceKind::File);\nassert_eq!(e.note, None);\n\nlet typo = serde_json::from_value::<ReasoningEvidence>(serde_json::json!({\n    \"kind\": \"file\", \"reference\": \"x\", \"notes\": \"misspelt\",\n}));\nassert!(typo.is_err());\n```",
      "properties": {
        "kind": {
          "$ref": "#/$defs/ReasoningEvidenceKind",
          "description": "What it is."
        },
        "note": {
          "description": "What it shows, in one line.",
          "type": [
            "string",
            "null"
          ]
        },
        "reference": {
          "description": "Where it is: a path, a case, an id, a command line.",
          "type": "string"
        }
      },
      "required": [
        "kind",
        "reference"
      ],
      "type": "object"
    },
    "ReasoningEvidenceKind": {
      "description": "What a piece of evidence is.\n\nThe kind tells a reader how to follow the reference: open a file, run a test, read an\nADR or a rule, show a commit. A prior external opinion is a kind of its own so that an\nadvisor's earlier conclusion, handed to another advisor, is never read as a fact.\n\n```\nuse majordomus_cli::reasoning::record::ReasoningEvidenceKind;\n\nlet kind: ReasoningEvidenceKind = serde_json::from_str(\"\\\"prior_external_opinion\\\"\").unwrap();\nassert_eq!(kind, ReasoningEvidenceKind::PriorExternalOpinion);\nassert_eq!(serde_json::to_string(&ReasoningEvidenceKind::Adr).unwrap(), \"\\\"adr\\\"\");\n```",
      "oneOf": [
        {
          "const": "file",
          "description": "A file of the repository, optionally with a line: `src/x.rs:42`.",
          "type": "string"
        },
        {
          "const": "test",
          "description": "A test case or test name.",
          "type": "string"
        },
        {
          "const": "adr",
          "description": "An architecture decision record.",
          "type": "string"
        },
        {
          "const": "rule",
          "description": "A rule of the layer.",
          "type": "string"
        },
        {
          "const": "commit",
          "description": "A commit.",
          "type": "string"
        },
        {
          "const": "command",
          "description": "A command that was run, and what it showed.",
          "type": "string"
        },
        {
          "const": "record",
          "description": "Another reasoning record.",
          "type": "string"
        },
        {
          "const": "document",
          "description": "Documentation.",
          "type": "string"
        },
        {
          "const": "runtime",
          "description": "A runtime observation: a log, a measurement, a diagnostic.",
          "type": "string"
        },
        {
          "const": "prior_external_opinion",
          "description": "A prior external opinion: an advisor's conclusion handed to another advisor.\nMarked so it is never mistaken for a fact.",
          "type": "string"
        }
      ]
    },
    "ReasoningMode": {
      "description": "How much independent review a session may use, and where from. The policy reads it\nfor the review budget; availability reads it to leave advisors out (`ci` all of them,\n`offline` every one that leaves the machine). `standard` is the default.\n\n```\nuse majordomus_cli::reasoning::availability::ReasoningMode;\n\nassert_eq!(ReasoningMode::default(), ReasoningMode::Standard);\nassert_eq!(serde_json::to_value(ReasoningMode::Offline).unwrap(), \"offline\");\nlet m: ReasoningMode = serde_json::from_str(\"\\\"strict\\\"\").unwrap();\nassert_eq!(m, ReasoningMode::Strict);\n```",
      "oneOf": [
        {
          "const": "offline",
          "description": "No network: only advisors that stay on this machine.",
          "type": "string"
        },
        {
          "const": "ci",
          "description": "Deterministic: no advisor at all, whatever is installed.",
          "type": "string"
        },
        {
          "const": "fast",
          "description": "Review only where the blast radius is high.",
          "type": "string"
        },
        {
          "const": "standard",
          "description": "Review where uncertainty is material.",
          "type": "string"
        },
        {
          "const": "strict",
          "description": "Review wider, and complementary review where the stakes are highest.",
          "type": "string"
        }
      ]
    },
    "ReasoningPhase": {
      "description": "A phase of the reasoning timeline.\n\nEach record maps to one phase: a plan to consulting, local or reuse by its outcome, a\nconsultation to an advisor response or a degradation by its status, and every other\nkind to the phase of the same name.\n\n```\n# use majordomus_cli::reasoning::record::ReasoningRecord;\n# use serde_json::json;\n# fn rec(id: &str, n: u32, body: serde_json::Value) -> ReasoningRecord {\n#     serde_json::from_value(json!({\n#         \"schema\": \"majordomus/reasoning-record\", \"version\": 1, \"id\": id, \"task\": \"t\",\n#         \"recorded_at\": format!(\"2026-10-01T00:00:{n:02}Z\"), \"body\": body,\n#     }))\n#     .unwrap()\n# }\nuse majordomus_cli::reasoning::state::{derive, ReasoningPhase};\nuse majordomus_cli::reasoning::store::Loaded;\n\nlet mut loaded = Loaded::default();\nloaded.records.push(rec(\"consultation-1\", 1, json!({\n    \"kind\": \"consultation\", \"plan\": \"plan-0\", \"advisor\": \"alpha\", \"status\": \"unavailable\",\n})));\nlet phases: Vec<ReasoningPhase> =\n    derive(&loaded, None).timeline.iter().map(|s| s.phase).collect();\nassert_eq!(phases, [ReasoningPhase::Degradation]);\nlet word = serde_json::to_value(ReasoningPhase::AdvisorResponse).unwrap();\nassert_eq!(word, \"advisor_response\");\n```",
      "oneOf": [
        {
          "const": "uncertainty",
          "description": "Uncertainty stated with evidence.",
          "type": "string"
        },
        {
          "const": "consulting",
          "description": "Review planned.",
          "type": "string"
        },
        {
          "const": "local",
          "description": "Decided locally, by plan.",
          "type": "string"
        },
        {
          "const": "reuse",
          "description": "A standing conclusion reused.",
          "type": "string"
        },
        {
          "const": "advisor_response",
          "description": "An advisor answered.",
          "type": "string"
        },
        {
          "const": "degradation",
          "description": "An advisor could not answer.",
          "type": "string"
        },
        {
          "const": "disagreement",
          "description": "Positions diverged.",
          "type": "string"
        },
        {
          "const": "experiment",
          "description": "An experiment settled a disagreement.",
          "type": "string"
        },
        {
          "const": "conclusion",
          "description": "A conclusion.",
          "type": "string"
        },
        {
          "const": "validation",
          "description": "A validation step.",
          "type": "string"
        },
        {
          "const": "attempt",
          "description": "A failed attempt.",
          "type": "string"
        }
      ]
    },
    "ReasoningRecord": {
      "description": "A stored record: a body with the envelope only the writer stamps.\n\nThe envelope carries the schema and version, a unique id, the task, the time it was\nrecorded, the commit the checkout was on and the secret shapes redacted from its text.\nOne record is one JSON file in the store; the store reads back only records whose\nschema and version match.\n\n```\nuse majordomus_cli::reasoning::record::*;\n\nlet record = ReasoningRecord {\n    schema: RECORD_SCHEMA.into(),\n    version: RECORD_VERSION,\n    id: \"attempt-20261001T000000Z-abcdef\".into(),\n    task: \"untasked\".into(),\n    recorded_at: \"2026-10-01T00:00:00Z\".into(),\n    head: None,\n    redacted: vec![],\n    body: ReasoningBody::Attempt(AttemptInput {\n        assessment: None,\n        attempt: \"inline the call\".into(),\n        observed_failure: \"the test still fails\".into(),\n        assumption_invalidated: None,\n        evidence: vec![],\n        updated_hypothesis: None,\n    }),\n};\nlet text = serde_json::to_string(&record).unwrap();\nassert!(!text.contains(\"\\\"head\\\"\"), \"an absent head is not written\");\nlet back: ReasoningRecord = serde_json::from_str(&text).unwrap();\nassert_eq!(back.id, record.id);\nassert_eq!(back.body.kind(), \"attempt\");\n```",
      "properties": {
        "body": {
          "$ref": "#/$defs/ReasoningBody",
          "description": "The record."
        },
        "head": {
          "description": "The commit the checkout was on.",
          "type": [
            "string",
            "null"
          ]
        },
        "id": {
          "description": "`<kind>-<yyyymmddThhmmssZ>-<hex>`, unique in the store.",
          "type": "string"
        },
        "recorded_at": {
          "description": "When it was recorded, RFC 3339; stamped by the writer, never supplied.",
          "type": "string"
        },
        "redacted": {
          "description": "Secret shapes the writer removed from the text, by shape name.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "schema": {
          "description": "`RECORD_SCHEMA`.",
          "type": "string"
        },
        "task": {
          "description": "The task it was recorded under, or `untasked`.",
          "type": "string"
        },
        "version": {
          "description": "`RECORD_VERSION`.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "schema",
        "version",
        "id",
        "task",
        "recorded_at",
        "body"
      ],
      "type": "object"
    },
    "ReasoningStep": {
      "description": "One step of the timeline: when, which record, which phase, and one line saying what\nhappened.\n\nThe summary is cut to a single line of at most 140 characters, so a timeline renders\nthe same on a terminal, a page and a handover.\n\n```\n# use majordomus_cli::reasoning::record::ReasoningRecord;\n# use serde_json::json;\n# fn rec(id: &str, n: u32, body: serde_json::Value) -> ReasoningRecord {\n#     serde_json::from_value(json!({\n#         \"schema\": \"majordomus/reasoning-record\", \"version\": 1, \"id\": id, \"task\": \"t\",\n#         \"recorded_at\": format!(\"2026-10-01T00:00:{n:02}Z\"), \"body\": body,\n#     }))\n#     .unwrap()\n# }\nuse majordomus_cli::reasoning::state::{derive, ReasoningPhase, ReasoningStep};\nuse majordomus_cli::reasoning::store::Loaded;\n\nlet mut loaded = Loaded::default();\nloaded.records.push(rec(\"attempt-1\", 1, json!({\n    \"kind\": \"attempt\", \"attempt\": \"share the client\\nacross threads\",\n    \"observed_failure\": \"the handle is not Sync\",\n})));\nlet state = derive(&loaded, None);\nlet step: &ReasoningStep = &state.timeline[0];\nassert_eq!(step.at, \"2026-10-01T00:00:01Z\");\nassert_eq!(step.phase, ReasoningPhase::Attempt);\nassert_eq!(step.summary, \"share the client failed: the handle is not Sync\");\n```",
      "properties": {
        "at": {
          "description": "When.",
          "type": "string"
        },
        "id": {
          "description": "The record.",
          "type": "string"
        },
        "phase": {
          "$ref": "#/$defs/ReasoningPhase",
          "description": "The phase."
        },
        "summary": {
          "description": "One line.",
          "type": "string"
        }
      },
      "required": [
        "at",
        "id",
        "phase",
        "summary"
      ],
      "type": "object"
    },
    "ReviewPlan": {
      "description": "The plan: the decision with its reasons attached. It carries what it answered (mode,\nmateriality, confidence, capabilities), the budget, the outcome with one sentence of\nwhy, every advisor selected or excluded, and the local review when one is due.\n\n```\nuse majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};\nuse majordomus_cli::reasoning::policy::{plan, Materiality, PlanRequest, ReviewPlan, LOCAL_REVIEW};\n\nlet mode = ModeResolution { mode: ReasoningMode::Offline, source: \"MAJORDOMUS_REASONING_MODE\".into() };\nlet request = PlanRequest { materiality: Materiality::Material, ..Default::default() };\nlet p: ReviewPlan = plan(&request, &mode, &[]);\nassert_eq!(p.mode_source, \"MAJORDOMUS_REASONING_MODE\");\nassert_eq!(p.capabilities, [\"independent_reasoning\"]);\nassert_eq!((p.budget, p.available), (1, 0));\nassert_eq!(p.local_review.len(), LOCAL_REVIEW.len());\nassert!(p.reason.starts_with(\"no available advisor offers\"));\n```",
      "properties": {
        "available": {
          "description": "Advisors available when the plan was made, whatever was selected.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "budget": {
          "description": "How many advisors the mode and materiality allow.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "capabilities": {
          "description": "The capabilities review was asked for.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "confidence": {
          "$ref": "#/$defs/ReasoningConfidence",
          "description": "The confidence it answered."
        },
        "excluded": {
          "description": "Every advisor not selected, with its reason.",
          "items": {
            "$ref": "#/$defs/ExcludedAdvisor"
          },
          "type": "array"
        },
        "local_review": {
          "description": "The structured local review to perform, when material uncertainty meets no advisor.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "materiality": {
          "$ref": "#/$defs/Materiality",
          "description": "The materiality it answered."
        },
        "mode": {
          "$ref": "#/$defs/ReasoningMode",
          "description": "The mode it was made under."
        },
        "mode_source": {
          "description": "What decided the mode.",
          "type": "string"
        },
        "outcome": {
          "$ref": "#/$defs/PlanOutcome",
          "description": "What to do."
        },
        "reason": {
          "description": "Why, in one sentence.",
          "type": "string"
        },
        "selected": {
          "description": "The advisors to consult, in selection order.",
          "items": {
            "$ref": "#/$defs/SelectedAdvisor"
          },
          "type": "array"
        }
      },
      "required": [
        "mode",
        "mode_source",
        "materiality",
        "confidence",
        "capabilities",
        "budget",
        "outcome",
        "reason",
        "selected",
        "excluded",
        "available"
      ],
      "type": "object"
    },
    "SelectedAdvisor": {
      "description": "One selected advisor, the requested capabilities it covers, and why the greedy\nselection chose it at its position.\n\n```\nuse majordomus_cli::reasoning::availability::{AdvisorState, ModeResolution, ReasoningMode};\nuse majordomus_cli::reasoning::policy::{plan, Materiality, PlanRequest, SelectedAdvisor};\n\nfn advisor(id: &str, adapter: &str, status: &str) -> AdvisorState {\n    serde_json::from_value(serde_json::json!({\n        \"id\": id, \"title\": id, \"transport\": \"api\", \"adapter\": adapter,\n        \"capabilities\": [\"independent_reasoning\"], \"status\": status,\n        \"reason\": \"present\", \"probe\": \"\",\n    }))\n    .unwrap()\n}\nlet mode = ModeResolution { mode: ReasoningMode::Standard, source: \"default\".into() };\nlet request = PlanRequest { materiality: Materiality::Material, ..Default::default() };\nlet p = plan(&request, &mode, &[advisor(\"a\", \"x-api\", \"available\")]);\nlet chosen: &SelectedAdvisor = &p.selected[0];\nassert_eq!(chosen.advisor, \"a\");\nassert_eq!(chosen.covers, [\"independent_reasoning\"]);\nassert!(chosen.why.starts_with(\"the first available advisor\"));\n```",
      "properties": {
        "advisor": {
          "description": "The advisor id.",
          "type": "string"
        },
        "covers": {
          "description": "The requested capabilities it covers.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "why": {
          "description": "Why it was chosen.",
          "type": "string"
        }
      },
      "required": [
        "advisor",
        "covers",
        "why"
      ],
      "type": "object"
    },
    "Stance": {
      "description": "Where an advisor's answer stands relative to the executor's hypothesis.\n\nA completed consultation must state its stance; the store refuses one without it. The\nstance is a label for the timeline, not a vote: agreement settles nothing.\n\n```\nuse majordomus_cli::reasoning::record::Stance;\n\nlet s: Stance = serde_json::from_str(\"\\\"alternative\\\"\").unwrap();\nassert_eq!(s, Stance::Alternative);\nassert!(serde_json::from_str::<Stance>(\"\\\"agrees\\\"\").is_err());\n```",
      "oneOf": [
        {
          "const": "supports",
          "description": "It supports the hypothesis.",
          "type": "string"
        },
        {
          "const": "opposes",
          "description": "It argues against it.",
          "type": "string"
        },
        {
          "const": "alternative",
          "description": "It proposes something else.",
          "type": "string"
        },
        {
          "const": "inconclusive",
          "description": "It does not decide.",
          "type": "string"
        }
      ]
    },
    "StoredConclusion": {
      "description": "A conclusion as stored: the input and what only the writer computes.\n\nThe input is flattened, so a stored conclusion reads as the input plus two fields:\nthe advisors whose completed consultations it cites, each once and in canonical\norder, and their count. Both are computed at admission and checked again by\n`reasoning.check`, so a hand-edited count is reported.\n\n```\nuse majordomus_cli::reasoning::record::{ConclusionInput, StoredConclusion};\n\nlet stored = StoredConclusion {\n    input: ConclusionInput {\n        assessment: \"assessment-1\".into(),\n        decision: \"keep the lock\".into(),\n        rationale: \"measured\".into(),\n        ..Default::default()\n    },\n    reviewed_by: vec![\"alpha\".into()],\n    independent_review_count: 1,\n};\nlet json = serde_json::to_value(&stored).unwrap();\nassert_eq!(json[\"decision\"], \"keep the lock\");\nassert_eq!(json[\"independent_review_count\"], 1);\n```",
      "properties": {
        "assessment": {
          "description": "The assessment it concludes.",
          "type": "string"
        },
        "assumptions": {
          "description": "Assumptions it still depends on.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "confidence": {
          "$ref": "#/$defs/ReasoningConfidence",
          "default": "medium",
          "description": "Confidence in it."
        },
        "consultations": {
          "description": "The completed consultations it weighed.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "decision": {
          "description": "The decision.",
          "type": "string"
        },
        "disagreements": {
          "description": "The resolved disagreements it rests on.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "evidence": {
          "description": "The evidence it rests on. Required for material uncertainty.",
          "items": {
            "$ref": "#/$defs/ReasoningEvidence"
          },
          "type": "array"
        },
        "independent_review_count": {
          "description": "How many independent advisors reviewed it: `reviewed_by`'s length. Computed.",
          "format": "uint",
          "minimum": 0,
          "type": "integer"
        },
        "rationale": {
          "description": "Why, from the evidence.",
          "type": "string"
        },
        "rejected": {
          "description": "Alternatives considered and rejected, each with why.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "reviewed_by": {
          "description": "The advisors whose completed consultations it cites, each once. Computed.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "risks": {
          "description": "Risks that remain.",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "supersedes": {
          "description": "An earlier conclusion this one replaces, because new evidence overturned it.",
          "type": [
            "string",
            "null"
          ]
        },
        "validation_plan": {
          "description": "How the decision will be proven. Required for material uncertainty.",
          "items": {
            "type": "string"
          },
          "type": "array"
        }
      },
      "required": [
        "assessment",
        "decision",
        "rationale",
        "reviewed_by",
        "independent_review_count"
      ],
      "type": "object"
    },
    "StoredPlan": {
      "description": "A plan as stored: the decision and the availability it was made against.\n\nThe store builds it when it admits a `PlanInput`; nothing else does. The snapshot of\navailability is what a later consultation is admitted against, so an answer that\narrives after the advisor's circuit opened still belongs to the plan that asked for it.\n\n```\nuse majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};\nuse majordomus_cli::reasoning::policy::PlanOutcome;\nuse majordomus_cli::reasoning::record::*;\nuse majordomus_cli::reasoning::store::{admit, Admission, Loaded};\n\nlet mode = ModeResolution { mode: ReasoningMode::Standard, source: \"default\".into() };\nlet admission = Admission { mode: &mode, availability: &[] };\nlet mut loaded = Loaded::default();\nloaded.records.push(ReasoningRecord {\n    schema: RECORD_SCHEMA.into(),\n    version: RECORD_VERSION,\n    id: \"assessment-1\".into(),\n    task: \"t\".into(),\n    recorded_at: \"2026-10-01T00:00:01Z\".into(),\n    head: None,\n    redacted: vec![],\n    body: ReasoningBody::Assessment(AssessmentInput {\n        subject: \"a name\".into(),\n        ..Default::default()\n    }),\n});\nlet input = ReasoningInput::Plan(PlanInput { assessment: \"assessment-1\".into() });\nlet ReasoningBody::Plan(stored) = admit(input, &loaded, &admission).unwrap() else {\n    panic!(\"a plan input is stored as a plan\");\n};\nlet stored: StoredPlan = stored;\nassert_eq!(stored.assessment, \"assessment-1\");\nassert_eq!(stored.plan.outcome, PlanOutcome::DecideLocally);\nassert!(stored.availability.is_empty());\n```",
      "properties": {
        "assessment": {
          "description": "The assessment it answers.",
          "type": "string"
        },
        "availability": {
          "description": "Every advisor's standing at the moment of the plan: the snapshot a later\nconsultation is admitted against.",
          "items": {
            "$ref": "#/$defs/AdvisorState"
          },
          "type": "array"
        },
        "plan": {
          "$ref": "#/$defs/ReviewPlan",
          "description": "The decision."
        }
      },
      "required": [
        "assessment",
        "plan",
        "availability"
      ],
      "type": "object"
    },
    "ValidationOutcome": {
      "description": "Whether a performed validation step passed or failed.\n\nOne failed validation is enough to mark the assessment's standing as\n`validation_failed` in the derived state, whatever else passed.\n\n```\nuse majordomus_cli::reasoning::record::ValidationOutcome;\n\nlet o: ValidationOutcome = serde_json::from_str(\"\\\"fail\\\"\").unwrap();\nassert_eq!(o, ValidationOutcome::Fail);\nassert_eq!(serde_json::to_string(&ValidationOutcome::Pass).unwrap(), \"\\\"pass\\\"\");\n```",
      "oneOf": [
        {
          "const": "pass",
          "description": "It passed.",
          "type": "string"
        },
        {
          "const": "fail",
          "description": "It failed.",
          "type": "string"
        }
      ]
    }
  },
  "description": "A record with everything it rests on and everything that rests on it.\n\nIt carries the record itself, the assessment it belongs to, and that assessment's\nwhole provenance chain as timeline steps in order. A record that belongs to no\nassessment has a chain of itself alone.\n\n```\n# use majordomus_cli::reasoning::record::ReasoningRecord;\n# use serde_json::json;\n# fn rec(id: &str, n: u32, body: serde_json::Value) -> ReasoningRecord {\n#     serde_json::from_value(json!({\n#         \"schema\": \"majordomus/reasoning-record\", \"version\": 1, \"id\": id, \"task\": \"t\",\n#         \"recorded_at\": format!(\"2026-10-01T00:00:{n:02}Z\"), \"body\": body,\n#     }))\n#     .unwrap()\n# }\nuse majordomus_cli::reasoning::state::{explain, ReasoningExplanation};\nuse majordomus_cli::reasoning::store::Loaded;\n\nlet mut loaded = Loaded::default();\nloaded.records.push(rec(\"attempt-1\", 1, json!({\n    \"kind\": \"attempt\", \"attempt\": \"inline it\", \"observed_failure\": \"still slow\",\n})));\nlet e: ReasoningExplanation = explain(&loaded, \"attempt-1\").unwrap();\nassert_eq!(e.record.id, \"attempt-1\");\nassert_eq!(e.assessment, None);\nassert_eq!(e.chain.len(), 1);\n```",
  "properties": {
    "assessment": {
      "description": "The assessment it belongs to, when it belongs to one.",
      "type": [
        "string",
        "null"
      ]
    },
    "chain": {
      "description": "Every record of that assessment, in order: its provenance chain.",
      "items": {
        "$ref": "#/$defs/ReasoningStep"
      },
      "type": "array"
    },
    "record": {
      "$ref": "#/$defs/ReasoningRecord",
      "description": "The record asked about."
    }
  },
  "required": [
    "record",
    "chain"
  ],
  "title": "ReasoningExplanation",
  "type": "object"
}

Policies

benchmark
waived — waived: transient_state
cache
disabled — every call runs the handler

Benchmark targets

Derived from the registry for this repository: one requirement per transport, and the cases the input type provides. The whole matrix is on the benchmarks page.

transportstatecasestargets
directwaived (transient_state)0
mcpwaived (transient_state)0
httpwaived (transient_state)0

Searches the titles and descriptions of every page this site publishes.