reasoning.plan
Decide, without recording anything, whether a stated uncertainty warrants independent review, how much the mode allows, and which available advisors a capability-driven selection would ask — with every advisor left out and why. Trivial and low uncertainty is decided locally; material uncertainty with no suitable advisor gets the structured local review instead. Pure over the catalogue, the availability and the input.
Decide, without recording anything, whether a stated uncertainty warrants independent review, how much the mode allows, and which available advisors a capability-driven selection would ask — with every advisor left out and why. Trivial and low uncertainty is decided locally; material uncertainty with no suitable advisor gets the structured local review instead. Pure over the catalogue, the availability and the input.
- query
- experimental
- module reasoning
- #reasoning
- #policy
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_reasoning_plan |
| HTTP | GET /api/v1/reasoning/plan operationId reasoning.plan |
| command line | majordomus reasoning plan |
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 · PlanPreviewInput
reasoning.plan: a stated uncertainty, in transport-friendly scalars.
Nothing is recorded; reasoning.record with a plan records one.
use majordomus_cli::capability::builtin::reasoning::PlanPreviewInput;
use majordomus_cli::reasoning::Materiality;
let input: PlanPreviewInput = serde_json::from_value(serde_json::json!({
"materiality": "high", "capabilities": "code_review,security_review",
})).unwrap();
assert_eq!(input.materiality, Some(Materiality::High));
assert!(input.confidence.is_none(), "an absent field takes the policy's default");
assert!(serde_json::from_value::<PlanPreviewInput>(serde_json::json!({ "quorum": 2 })).is_err());| property | type | required | description |
|---|---|---|---|
| capabilities | string | null | no | Advisory capabilities review needs, comma-separated. |
| confidence | one of 2 | no | low, medium or high. |
| materiality | one of 2 | no | trivial, low, material, high or critical. |
JSON Schema
{
"$defs": {
"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"
}
]
},
"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"
}
]
}
},
"additionalProperties": false,
"description": "The input of `reasoning.plan`: a stated uncertainty, in transport-friendly scalars.\nNothing is recorded; `reasoning.record` with a `plan` records one.\n\n```\nuse majordomus_cli::capability::builtin::reasoning::PlanPreviewInput;\nuse majordomus_cli::reasoning::Materiality;\n\nlet input: PlanPreviewInput = serde_json::from_value(serde_json::json!({\n \"materiality\": \"high\", \"capabilities\": \"code_review,security_review\",\n})).unwrap();\nassert_eq!(input.materiality, Some(Materiality::High));\nassert!(input.confidence.is_none(), \"an absent field takes the policy's default\");\nassert!(serde_json::from_value::<PlanPreviewInput>(serde_json::json!({ \"quorum\": 2 })).is_err());\n```",
"properties": {
"capabilities": {
"description": "Advisory capabilities review needs, comma-separated.",
"type": [
"string",
"null"
]
},
"confidence": {
"anyOf": [
{
"$ref": "#/$defs/ReasoningConfidence"
},
{
"type": "null"
}
],
"description": "`low`, `medium` or `high`."
},
"materiality": {
"anyOf": [
{
"$ref": "#/$defs/Materiality"
},
{
"type": "null"
}
],
"description": "`trivial`, `low`, `material`, `high` or `critical`."
}
},
"title": "PlanPreviewInput",
"type": "object"
}output · ReviewPlan
use majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};
use majordomus_cli::reasoning::policy::{plan, Materiality, PlanRequest, ReviewPlan, LOCAL_REVIEW};
let mode = ModeResolution { mode: ReasoningMode::Offline, source: "MAJORDOMUS_REASONING_MODE".into() };
let request = PlanRequest { materiality: Materiality::Material, ..Default::default() };
let p: ReviewPlan = plan(&request, &mode, &[]);
assert_eq!(p.mode_source, "MAJORDOMUS_REASONING_MODE");
assert_eq!(p.capabilities, ["independent_reasoning"]);
assert_eq!((p.budget, p.available), (1, 0));
assert_eq!(p.local_review.len(), LOCAL_REVIEW.len());
assert!(p.reason.starts_with("no available advisor offers"));| property | type | required | description |
|---|---|---|---|
| available | integer | yes | Advisors available when the plan was made, whatever was selected. |
| budget | integer | yes | How many advisors the mode and materiality allow. |
| capabilities | array | yes | The capabilities review was asked for. |
| confidence | reference | yes | The confidence it answered. |
| excluded | array | yes | Every advisor not selected, with its reason. |
| local_review | array | no | The structured local review to perform, when material uncertainty meets no advisor. |
| materiality | reference | yes | The materiality it answered. |
| mode | reference | yes | The mode it was made under. |
| mode_source | string | yes | What decided the mode. |
| outcome | reference | yes | What to do. |
| reason | string | yes | Why, in one sentence. |
| selected | array | yes | The advisors to consult, in selection order. |
JSON Schema
{
"$defs": {
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
]
},
"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"
}
},
"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"
],
"title": "ReviewPlan",
"type": "object"
}Policies
- benchmark
- required — a target on every transport the exposure declares; the cases are the input type's
- 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.