Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

HTTP API: reasoning

Uvažování nezávislé na provideru (ADR 0098): které volitelné poradce lze oslovit a co nabízejí, co si žádá podstatná nejistota, typované záznamy uvažování relace — posouzení, plány, konzultace, neshody, vyřešení, závěry, validace, pokusy — a stav, časová osa a původ, které z nich vyplývají. Nic zde s poradcem nemluví a nic ho nepotřebuje: když žádný není k dispozici, plán je strukturovaná lokální revize a relace uzavírá podle vlastních důkazů.

Vykresleno z docs/generated/openapi.json, který spustitelný soubor generuje ze svého registru schopností a CI jej odmítne, je-li zastaralý. Surový dokument je na /openapi.json; běžící server servíruje stejný dokument na vlastní /openapi.json a Swagger UI na /swagger.

reasoning

Uvažování nezávislé na provideru (ADR 0098): které volitelné poradce lze oslovit a co nabízejí, co si žádá podstatná nejistota, typované záznamy uvažování relace — posouzení, plány, konzultace, neshody, vyřešení, závěry, validace, pokusy — a stav, časová osa a původ, které z nich vyplývají. Nic zde s poradcem nemluví a nic ho nepotřebuje: když žádný není k dispozici, plán je strukturovaná lokální revize a relace uzavírá podle vlastních důkazů.

GET /api/v1/reasoning reasoning.status

Stav uvažování relace

Stav uvažování otevřené úlohy (nebo pojmenované, nebo všech): posouzení a kde každé stojí, konzultace a jak každá skončila, neshody a co je rozhodlo, závěry s jejich vypočtenou revizí a validací, časová osa, součty tokenů, které adaptéry ohlásily, a Markdown zpráva, kterou nese předávka. Odvozeno pouze ze záznamů, deterministicky.

  • query
  • experimentální
  • vyžaduje se měření výkonu
  • cache vypnuta
  • Nástroj MCP majordomus_reasoning
  • Zdroj MCP {"name": "reasoning", "uri": "majordomus://reasoning"}
  • $ reasoning status

Parametry dotazu

názevtyppovinnépopispříklady
úloha string ne Id úlohy, nebo `all`; bez hodnoty otevřená úloha. all: "all"

Vyzkoušejte

Port je ten, který server zalogoval; 8741 je ten, o který žádá jako první. Hodnoty jsou první příklad operace.

curl -s "http://127.0.0.1:8741/api/v1/reasoning?task=all"

Testováno v apps/majordomus-cli/tests/http_serve.rs, který přehrává routu s těmito hodnotami proti serveru na skutečném socketu.

Odpovědi

statustělovýznam
200 ReasoningStatus Stav uvažování relace: výsledek.
400 ErrorBody invalid_input: Vstup neodpovídá schématu: parametr špatného typu, neznámý parametr nebo hodnota, kterou schopnost odmítne.
404 ErrorBody not_found: Vstup pojmenovává něco, co repozitář nemá.
500 ErrorBody internal: Schopnost selhala z vlastního důvodu; zpráva ho pojmenovává.
výchozí ErrorBody Jakékoli jiné selhání, které transport hlásí: 405 method_not_allowed pro jinou metodu na této cestě, 400 invalid_input pro tělo, které není objektem JSON.
GET /api/v1/reasoning/advisors reasoning.advisors

Poradci a co umějí nyní

Každý deklarovaný poradce — pak každý propojený peer mesh nesoucí funkci review — s jeho stavem (available, unavailable, not_configured, disabled, temporarily_failed, rate_limited) a důvodem, jen z přítomnosti (spustitelný soubor v PATH, nastavená proměnná s přihlašovacím údajem; nikdy hodnota), režimem uvažování a zaznamenanými výsledky dřívějších konzultací. Plus kapacita na poradní schopnost. Žádný poradce je běžná odpověď: uvažování je provozní tak či tak.

  • query
  • experimentální
  • vyžaduje se měření výkonu
  • cache vypnuta
  • Nástroj MCP majordomus_reasoning_advisors
  • zdroj MCP {"name": "reasoning-advisors", "uri": "majordomus://reasoning/advisors"}
  • $ reasoning advisors

Žádné parametry.

Vyzkoušejte

Port je ten, který server zalogoval; 8741 je ten, o který žádá jako první. Hodnoty jsou první příklad operace.

curl -s "http://127.0.0.1:8741/api/v1/reasoning/advisors"

Testováno v apps/majordomus-cli/tests/http_serve.rs, který přehrává routu s těmito hodnotami proti serveru na skutečném socketu.

Odpovědi

statustělovýznam
200 AdvisorsReport Poradci a co nyní mohou dělat: výsledek.
400 ErrorBody invalid_input: Vstup neodpovídá schématu: parametr špatného typu, neznámý parametr nebo hodnota, kterou schopnost odmítne.
404 ErrorBody not_found: Vstup pojmenovává něco, co repozitář nemá.
500 ErrorBody internal: Schopnost selhala z vlastního důvodu; zpráva ho pojmenovává.
výchozí ErrorBody Jakékoli jiné selhání, které transport hlásí: 405 method_not_allowed pro jinou metodu na této cestě, 400 invalid_input pro tělo, které není objektem JSON.
GET /api/v1/reasoning/check reasoning.check

Zkontrolovat, že uvažování zůstává nezávislé na provideru

Spustitelná polovina pravidel advisors-are-optional a review-is-recorded-not-claimed: katalog poradců se vyřeší proti tabulce providerů a katalogu modelů; každý adaptér, který pojmenovává, má svůj transportní modul; žádný zdroj nezávislý na provideru nepojmenovává poradce; žádný CI workflow ani kontrola nepojmenovává přihlašovací údaj modelu; žádný dokument netvrdí odmítnuté tvrzení; každá uložená konzultace pojmenovává poradce, kterého její plán vybral, a revize každého závěru odpovídá tomu, co cituje. Kontroly CI a tvrzení posuzují, co říkají vlastní workflow a dokumenty tohoto repozitáře, takže platí jen tam, kde je pravidlo advisors-are-optional deklarováno; adopter se poměřuje tím, co přijal.

  • query
  • experimentální
  • vyžaduje se měření výkonu
  • cache vypnuta
  • nástroj MCP majordomus_reasoning_check
  • $ reasoning check

Žádné parametry.

Vyzkoušejte

Port je ten, který server zalogoval; 8741 je ten, o který žádá jako první. Hodnoty jsou první příklad operace.

curl -s "http://127.0.0.1:8741/api/v1/reasoning/check"

Testováno v apps/majordomus-cli/tests/http_serve.rs, který přehrává routu s těmito hodnotami proti serveru na skutečném socketu.

Odpovědi

statustělovýznam
200 ReasoningCheck Zkontrolovat, že uvažování zůstává nezávislé na provideru: výsledek.
400 ErrorBody invalid_input: Vstup neodpovídá schématu: parametr špatného typu, neznámý parametr nebo hodnota, kterou schopnost odmítne.
404 ErrorBody not_found: Vstup pojmenovává něco, co repozitář nemá.
500 ErrorBody internal: Schopnost selhala z vlastního důvodu; zpráva ho pojmenovává.
výchozí ErrorBody Jakékoli jiné selhání, které transport hlásí: 405 method_not_allowed pro jinou metodu na této cestě, 400 invalid_input pro tělo, které není objektem JSON.
GET /api/v1/reasoning/explain reasoning.explain

Proč bylo učiněno rozhodnutí

Jeden záznam uvažování s celým řetězcem jeho posouzení: nejistota a její důkazy, plán a koho vybral nebo proč nikoho, každá konzultace, každá neshoda a experiment, který ji rozřešil, závěr a jeho validace — původ rozhodnutí bez konverzace, která jej vyvolala.

  • query
  • experimentální
  • měření výkonu prominuto: transient_state
  • cache vypnuta
  • nástroj MCP majordomus_reasoning_explain
  • $ reasoning explain

Parametry dotazu

názevtyppovinnépopispříklady
id string ano Id záznamu: obvykle závěru. chybí: "conclusion-benchmark-absent"

Vyzkoušejte

Port je ten, který server zalogoval; 8741 je ten, o který žádá jako první. Hodnoty jsou první příklad operace.

curl -s "http://127.0.0.1:8741/api/v1/reasoning/explain?id=conclusion-benchmark-absent"

Testováno v apps/majordomus-cli/tests/http_serve.rs, který přehrává routu s těmito hodnotami proti serveru na skutečném socketu.

Odpovědi

statustělovýznam
200 ReasoningExplanation Proč bylo rozhodnutí učiněno: výsledek.
400 ErrorBody invalid_input: Vstup neodpovídá schématu: parametr špatného typu, neznámý parametr nebo hodnota, kterou schopnost odmítne.
404 ErrorBody not_found: Vstup pojmenovává něco, co repozitář nemá.
500 ErrorBody internal: Schopnost selhala z vlastního důvodu; zpráva ho pojmenovává.
výchozí ErrorBody Jakékoli jiné selhání, které transport hlásí: 405 method_not_allowed pro jinou metodu na této cestě, 400 invalid_input pro tělo, které není objektem JSON.
GET /api/v1/reasoning/plan reasoning.plan

Co nejistota vyžaduje

Rozhodnout, aniž by se cokoli zaznamenalo, zda uvedená nejistota zaslouží nezávislou revizi, kolik povoluje režim a které dostupné poradce by výběr řízený schopnostmi oslovil — s každým vynechaným poradcem a proč. Triviální a nízká nejistota se rozhoduje lokálně; podstatná nejistota bez vhodného poradce dostane strukturovanou lokální revizi. Čistá funkce nad katalogem, dostupností a vstupem.

  • query
  • experimentální
  • vyžaduje se měření výkonu
  • cache vypnuta
  • nástroj MCP majordomus_reasoning_plan
  • $ reasoning plan

Parametry dotazu

názevtyppovinnépopispříklady
podstatnost Materiality | null ne `trivial`, `low`, `material`, `high` nebo `critical`. material: "material"
jistota ReasoningConfidence | null ne `low`, `medium` nebo `high`. material: "medium"
capabilities string ne Poradní schopnosti, které review potřebuje, oddělené čárkou. podstatné: "independent_reasoning,code_review"

Vyzkoušejte

Port je ten, který server zalogoval; 8741 je ten, o který žádá jako první. Hodnoty jsou první příklad operace.

curl -s "http://127.0.0.1:8741/api/v1/reasoning/plan?materiality=material&confidence=medium&capabilities=independent_reasoning%2Ccode_review"

Testováno v apps/majordomus-cli/tests/http_serve.rs, který přehrává routu s těmito hodnotami proti serveru na skutečném socketu.

Odpovědi

statustělovýznam
200 ReviewPlan K čemu nejistota volá: výsledek.
400 ErrorBody invalid_input: Vstup neodpovídá schématu: parametr špatného typu, neznámý parametr nebo hodnota, kterou schopnost odmítne.
404 ErrorBody not_found: Vstup pojmenovává něco, co repozitář nemá.
500 ErrorBody internal: Schopnost selhala z vlastního důvodu; zpráva ho pojmenovává.
výchozí ErrorBody Jakékoli jiné selhání, které transport hlásí: 405 method_not_allowed pro jinou metodu na této cestě, 400 invalid_input pro tělo, které není objektem JSON.
POST /api/v1/reasoning/records reasoning.record

Zaznamenat krok uvažování

Zapsat jeden typovaný záznam uvažování otevřené úlohy pod .ai/local/state/reasoning/: posouzení (s jeho důkazy), plán (vypočtený zde z dostupnosti tohoto okamžiku, nikdy dodaný), konzultaci (jen poradce, kterého vybral její plán), neshodu, rozřešení (důkazy, nikdy počet), závěr (jeho počet revizí se počítá z konzultací, které cituje; odmítnut, dokud je neshoda nad jeho posouzením nevyřešená), validaci nebo neúspěšný pokus. Tvary tajemství se před jakýmkoli zápisem zakryjí.

  • command
  • experimentální
  • vyžaduje se měření výkonu
  • cache vypnuta
  • MCP nástroj majordomus_reasoning_record
  • $ reasoning record

Tělo požadavku — ReasoningRecordInput, JSON

příklad odmítnuto

{"record":{"kind":"plan","assessment":"assessment-benchmark-absent"}}

Vyzkoušejte

Port je ten, který server zalogoval; 8741 je ten, o který žádá jako první. Hodnoty jsou první příklad operace.

curl -s -X POST "http://127.0.0.1:8741/api/v1/reasoning/records" -H "content-type: application/json" -d '{"record":{"kind":"plan","assessment":"assessment-benchmark-absent"}}'

Testováno v apps/majordomus-cli/tests/http_serve.rs, který přehrává routu s těmito hodnotami proti serveru na skutečném socketu.

Odpovědi

statustělovýznam
200 ReasoningRecorded Zaznamenat krok uvažování: výsledek.
400 ErrorBody invalid_input: Vstup neodpovídá schématu: parametr špatného typu, neznámý parametr nebo hodnota, kterou schopnost odmítne.
404 ErrorBody not_found: Vstup pojmenovává něco, co repozitář nemá.
422 ErrorBody refused: Příkaz byl srozumitelný a byl odmítnut z důvodu, který uvádí zpráva.
500 ErrorBody internal: Schopnost selhala z vlastního důvodu; zpráva ho pojmenovává.
výchozí ErrorBody Jakékoli jiné selhání, které transport hlásí: 405 method_not_allowed pro jinou metodu na této cestě, 400 invalid_input pro tělo, které není objektem JSON.

Schémata

Komponenty, které používají jen operace tohoto tagu. Každý řádek je pole daného typu, jeho doc komentář je popis; typ vlastněný jinou stránkou na ni odkazuje.

AdvisorCapacity

object
Jedna poradní schopnost a kdo ji nyní může poskytnout: řádek tabulky kapacity, kterou hlásí reasoning.advisors. Prázdné available obslouží lokální recenze.

use majordomus_cli::capability::builtin::reasoning::AdvisorCapacity;

let row: AdvisorCapacity = serde_json::from_value(serde_json::json!({
    "capability": "code_review", "description": "Critique of a change.", "available": [],
})).unwrap();
assert_eq!(row.capability, "code_review");
assert!(row.available.is_empty());
vlastnosttyppovinnépopis
schopnost string ano Slovo schopnosti.
popis string ano Co to znamená.
dostupné array of string ano Dostupní advisoři, kteří to nabízejí, v pořadí preference.

Používá AdvisorsReport

AdvisorCircuit

object
Otevřený jistič: konzultace, která jej otevřela, selhání za ním a kdy se zavře. Odvozeno ze záznamů a hodin, nikdy neuloženo.

use majordomus_cli::reasoning::availability::*;
use majordomus_cli::reasoning::catalogue::{AdvisorCatalogue, References};
use majordomus_cli::reasoning::record::ConsultationStatus;

struct All;
impl Presence for All {
    fn executable(&self, _: &str) -> bool { true }
    fn variable(&self, _: &str) -> bool { true }
}
let c: AdvisorCatalogue = majordomus_cli::metadata::yaml::parse_into(
    "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",
).unwrap();
let limited = [Outcome {
    id: "consultation-1".into(), advisor: "a".into(),
    status: ConsultationStatus::RateLimited, at: 0, retry_after: Some(60),
}];
let refs = References::default();
let states = derive_availability(&c, &Inputs {
    refs: &refs, presence: &All, mode: ReasoningMode::Standard, disabled: &[],
    history: &limited, peers: &[], now: 10, cooldown: None,
});
let circuit: &AdvisorCircuit = states[0].circuit.as_ref().unwrap();
assert_eq!(circuit.opened_by, "consultation-1");
assert_eq!(circuit.until, "1970-01-01T00:01:00Z");
vlastnosttyppovinnépopis
opened_by string ano Výsledek konzultace, který ji otevřel.
selhání integer (uint32) ano Po sobě jdoucí selhání za ním.
do string ano Kdy se opět uzavře, RFC 3339.

Používá AdvisorState

AdvisorState

object
Jeden advisor tak, jak právě stojí: co o něm deklaruje katalog, jeho stav, jediné strojové slovo, které říká proč, a co bylo sondováno. Řádek, který hlásí reasoning.advisors a nad kterým plánuje politika.

use majordomus_cli::reasoning::availability::*;
use majordomus_cli::reasoning::catalogue::{AdvisorCatalogue, References};

struct Nothing;
impl Presence for Nothing {
    fn executable(&self, _: &str) -> bool { false }
    fn variable(&self, _: &str) -> bool { false }
}
let c: AdvisorCatalogue = majordomus_cli::metadata::yaml::parse_into(
    "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",
).unwrap();
let refs = References::default();
let state: AdvisorState = derive_availability(&c, &Inputs {
    refs: &refs, presence: &Nothing, mode: ReasoningMode::Standard, disabled: &[],
    history: &[], peers: &[], now: 0, cooldown: None,
})
.remove(0);
assert_eq!((state.id.as_str(), state.status), ("a", AdvisorStatus::Unavailable));
assert_eq!(state.probe, "executable rt on PATH");
assert!(state.circuit.is_none() && !state.recovering);
vlastnosttyppovinnépopis
id string ano Id poradce (peer je peer:<runtime>).
název string ano Lidský název.
transport AdvisorTransport → AdvisorTransport ano Jak se k tomu dostat.
adaptér string ano Adaptér, který s ním mluví.
capabilities array of string ano Poradní schopnosti, které nabízí.
model string | null ne Model, na který se ptá, když jej katalog jmenuje: co posílá jeho adaptér.
spustitelný soubor string | null ne Spustitelný soubor, který jeho adaptér spouští, pokud nějaký spouští.
přihlašovací údaj string | null ne Jméno proměnné s přihlašovacími údaji, kterou čte jeho adaptér — jméno, nikdy hodnota.
status AdvisorStatus → AdvisorStatus ano Jeho postavení.
důvod string ano Proč, jako jedno strojové slovo: present, executable_not_found, credential_absent, mode_ci, mode_offline, disabled_by_configuration, consecutive_failures, rate_limited, authentication_failed, peer_linked.
probe string ano Co bylo pozorováno, pro člověka: který spustitelný soubor, která proměnná (nikdy hodnota).
obnovuje se boolean ne Znovu dostupný po vychladnutí otevřeného jističe: další konzultace je jeho test.
jistič AdvisorCircuit | null → AdvisorCircuit ne Otevřený okruh, pokud nějaký je.

Používá AdvisorsReport StoredPlan

AdvisorStatus

"available" | "unavailable" | "not_configured" | "disabled" | "temporarily_failed" | "rate_limited"
Postavení advisora: zda se ho lze ptát nyní a když ne, jaký druh důvodu ho vylučuje. Do plánu vstupují jen advisoři available.

use majordomus_cli::reasoning::availability::AdvisorStatus;

assert_eq!(serde_json::to_value(AdvisorStatus::NotConfigured).unwrap(), "not_configured");
let s: AdvisorStatus = serde_json::from_str("\"rate_limited\"").unwrap();
assert_eq!(s, AdvisorStatus::RateLimited);
  • availableLze se zeptat. Přítomnost byla pozorována; zda odpovídá, se zjistí dotazem.
  • unavailableNení nainstalováno: jeho spustitelný soubor není na PATH.
  • not_configuredNainstalováno nebo v zásadě dosažitelné, ale jeho credential není nakonfigurován.
  • disabledVynecháno režimem nebo explicitním vypnutím.
  • temporarily_failedJeho nedávné konzultace selhaly; jeho okruh je otevřený, dokud neuplyne doba ochlazení.
  • rate_limitedOdpověděl omezením četnosti; znovu se neptáme, dokud limit nevyprší.

Používá AdvisorState ExcludedAdvisor

AdvisorTransport

"api" | "cli" | "local_runtime" | "peer"
Jak se k poradci dostat. Transport rozhoduje, jak se zjišťuje jeho přítomnost (proměnná s přihlašovacím údajem, spustitelný soubor, odkaz meshe) a zda jej režim offline připouští.

use majordomus_cli::reasoning::catalogue::AdvisorTransport;

let t: AdvisorTransport = serde_json::from_str("\"local_runtime\"").unwrap();
assert_eq!(t, AdvisorTransport::LocalRuntime);
assert!(!t.is_remote());
  • apiVzdálené API; přítomno, když je nastavena proměnná s přihlašovacím údajem jeho dodavatele.
  • cliKlientský nástroj spouštěný jako proces; přítomen, když je jeho spustitelný soubor v PATH.
  • local_runtimeModelový runtime na tomto stroji; přítomen, když je jeho spustitelný soubor na PATH.
  • peerPropojený runtime mesh nesoucí funkci review; přítomen, dokud je propojen.

Používá AdvisorState

AdvisorUsage

object
Počty tokenů, které adaptér nahlásil. Chybí, když transport žádné nehlásí; nikdy se neodhadují.

Stav tyto hodnoty sčítá do svých součtů. Chybějící počet se čte jako nula, takže adaptér, který hlásí jen jednu ze dvou, přesto zaznamená, co hlásil.

use majordomus_cli::reasoning::record::AdvisorUsage;

let u: AdvisorUsage = serde_json::from_str(r#"{"input_tokens": 120}"#).unwrap();
assert_eq!(u, AdvisorUsage { input_tokens: 120, output_tokens: 0 });
vlastnosttyppovinnépopis
input_tokens integer (uint64) ne Vstupní tokeny.
output_tokens integer (uint64) ne Výstupní tokeny.

Používá ReasoningBody ReasoningInput

AdvisorsReport

object
Odpověď reasoning.advisors: platný režim, kolik poradců se smí a nesmí oslovit, stav každého poradce, kapacita na poradní schopnost a vlastní zjištění katalogu. operational je true bez ohledu na počty.

use majordomus_cli::capability::builtin::reasoning::AdvisorsReport;

let report: AdvisorsReport = serde_json::from_value(serde_json::json!({
    "operational": true,
    "mode": { "mode": "ci", "source": "CI" },
    "available": 0, "unavailable": 0, "advisors": [], "capacity": [],
})).unwrap();
assert!(report.operational && report.advisors.is_empty());
assert_eq!(report.mode.source, "CI");
assert!(report.diagnostics.is_empty(), "absent findings are the ordinary case");
vlastnosttyppovinnépopis
provozní boolean ano Uvažování funguje, ať jsou poradci jacíkoli: vždy true, uvedeno tak, aby to čtenář nemusel dovozovat z počtu.
režim ModeResolution → ModeResolution ano Platný režim a co o něm rozhodlo.
dostupné integer (uint) ano Poradci, kterých se lze nyní zeptat.
nedostupné integer (uint) ano Poradci, kteří nesmějí, každý volitelný.
advisors pole AdvisorState → AdvisorState ano Každý poradce, deklarovaní v pořadí preference, pak propojení peeři.
kapacita pole AdvisorCapacity → AdvisorCapacity ano Pro každou poradní schopnost, kdo ji může nyní poskytnout. Řádek bez nikoho obslouží lokální cesta review.
diagnostika array of string ne Vlastní zjištění katalogu.

Používá reasoning.advisors

AssessmentStanding

"open" | "planned" | "disputed" | "concluded" | "validated" | "validation_failed"
Kde posouzení stojí, od otevřeného po validované.

Postavení se odvozuje, nikdy neukládá: nevyřešený spor jej činí sporným, ať je zaznamenáno cokoli jiného; jinak o něm rozhodují jeho platný závěr a validace tohoto závěru, a bez závěru jej zaznamenaný plán činí plánovaným.

#### 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::{derive, AssessmentStanding};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("assessment-1", 1, json!({ "kind": "assessment", "subject": "s" })));
assert_eq!(derive(&loaded, None).assessments[0].standing, AssessmentStanding::Open);

loaded.records.push(rec("disagreement-2", 2, json!({
    "kind": "disagreement", "assessment": "assessment-1",
    "positions": [
        { "source": "primary", "position": "A" },
        { "source": "consultation-9", "position": "B" },
    ],
    "discriminating_question": "do callers retry?",
})));
assert_eq!(derive(&loaded, None).assessments[0].standing, AssessmentStanding::Disputed);
  • openUvedeno; zatím bez plánu.
  • plannedNaplánováno; zatím žádný závěr.
  • disputedNesouhlas o tom je nevyřešený.
  • concludedUzavřeno; zatím neověřeno.
  • validatedUzavřeno a každá zaznamenaná validace prošla.
  • validation_failedUzavřeno a validace selhala.

Používá AssessmentView

AssessmentView

object
Jedno posouzení a kde stojí.

Pohled nese to, co čtenář potřebuje, aby práci převzal: subjekt, jeho podstatnost, jeho odvozené postavení, závěr, který za něj platí, a otázky, které zanechal otevřené.

#### 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::policy::Materiality;
use majordomus_cli::reasoning::state::{derive, AssessmentView};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("assessment-1", 1, json!({
    "kind": "assessment", "subject": "lock scope", "materiality": "trivial",
    "questions": ["is it held across an await?"],
})));
let state = derive(&loaded, None);
let view: &AssessmentView = &state.assessments[0];
assert_eq!((view.id.as_str(), view.task.as_str()), ("assessment-1", "t"));
assert_eq!(view.materiality, Materiality::Trivial);
assert_eq!(view.conclusion, None);
assert_eq!(view.questions, ["is it held across an await?"]);
vlastnosttyppovinnépopis
id string ano Id záznamu.
úloha string ano Úloha, pod kterou byl zaznamenán.
předmět string ano Co je nejisté.
podstatnost Podstatnost → Materiality ano Jak moc na tom záleží.
postavení AssessmentStanding → AssessmentStanding ano Jak to stojí.
závěr string | null ne Jeho trvalý závěr.
otázky array of string ne Otázky, které nechala otevřené.

Používá ReasoningState

ConclusionView

object
Jeden závěr, jak ho hlásí stav.

Vedle rozhodnutí a jeho vypočteného review pohled počítá validace zaznamenané proti závěru a jmenuje pozdější závěr, který jej nahradil, pokud nějaký je. Nahrazený závěr zůstává v seznamu; report ho vynechává.

#### 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::{derive, ConclusionView};
use majordomus_cli::reasoning::store::Loaded;

let conclusion = |decision: &str, supersedes: Option<&str>| {
    json!({
        "kind": "conclusion", "assessment": "assessment-0", "decision": decision,
        "rationale": "r", "supersedes": supersedes,
        "reviewed_by": [], "independent_review_count": 0,
    })
};
let mut loaded = Loaded::default();
loaded.records.push(rec("conclusion-1", 1, conclusion("A", None)));
loaded.records.push(rec("validation-2", 2, json!({
    "kind": "validation", "conclusion": "conclusion-1", "check": "x", "outcome": "fail",
})));
loaded.records.push(rec("conclusion-3", 3, conclusion("B", Some("conclusion-1"))));

let state = derive(&loaded, None);
let first: &ConclusionView = &state.conclusions[0];
assert_eq!((first.validations_passed, first.validations_failed), (0, 1));
assert_eq!(first.superseded_by.as_deref(), Some("conclusion-3"));
assert_eq!(state.conclusions[1].superseded_by, None);
vlastnosttyppovinnépopis
id string ano Id záznamu.
posouzení string ano Posouzení, k jakému dospívá.
rozhodnutí string ano Rozhodnutí.
reviewed_by array of string ano Poradci, jejichž odpovědi zvážil.
independent_review_count integer (uint) ano Kolik.
validations_passed integer (uint) ano Zaznamenaná ověření: prošla, selhala.
validations_failed integer (uint) ano Validace selhaly.
superseded_by string | null ne Nahrazeno pozdějším závěrem.
validation_plan array of string ano Jeho plán validace.
rizika array of string ne Rizika, která zůstávají.

Používá ReasoningState

ConsultationStatus

"completed" | "timeout" | "rate_limited" | "auth_failed" | "malformed" | "empty" | "unavailable" | "cancelled" | "error"
Jak konzultace skončila, jak ji klasifikoval adaptér.

Radu nese a jako review se počítá jen dokončená konzultace; každý jiný stav je degradace, která se zaznamená, aby ji stav mohl hlásit, nikdy skrývat. Drátová podoba je slovo v snake_case, které vrací ConsultationStatus::as_str.

use majordomus_cli::reasoning::record::ConsultationStatus;

let s: ConsultationStatus = serde_json::from_str("\"rate_limited\"").unwrap();
assert_eq!(s, ConsultationStatus::RateLimited);
assert!(!s.is_transient());
assert!(ConsultationStatus::Timeout.is_transient());
  • completedOdpověď byla přijata a normalizována.
  • timeoutŽádná odpověď v povoleném čase.
  • rate_limitedPoradce odmítl kvůli rychlostnímu limitu.
  • auth_failedPřihlašovací údaj byl odmítnut.
  • malformedDorazila odpověď, kterou nebylo možné normalizovat.
  • emptyOdpověď dorazila bez jakéhokoli obsahu.
  • unavailablePoradce nebylo možné oslovit: neběží, neodpovídá, zmizel.
  • cancelledRelace žádost stáhla.
  • errorCokoli jiného, co adaptér nedokázal klasifikovat.

Používá ConsultationView ReasoningBody ReasoningInput

ConsultationView

object
Jedna konzultace, jak ji stav hlásí.

Selhaná konzultace se hlásí stejně prostě jako dokončená: její stav a diagnostika adaptéru stojí tam, kde by stála rada, takže degradace je viditelná, ne tiše chybějící.

#### 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::record::ConsultationStatus;
use majordomus_cli::reasoning::state::{derive, ConsultationView};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("consultation-1", 1, json!({
    "kind": "consultation", "plan": "plan-0", "advisor": "alpha",
    "status": "timeout", "diagnostic": "timeout: no answer in 60s",
})));
let state = derive(&loaded, None);
let view: &ConsultationView = &state.consultations[0];
assert_eq!(view.status, ConsultationStatus::Timeout);
assert_eq!(view.conclusion, None);
assert_eq!(view.diagnostic.as_deref(), Some("timeout: no answer in 60s"));
assert_eq!(state.totals.consultations_failed, 1);
vlastnosttyppovinnépopis
id string ano Id záznamu.
plan string ano Plán, který jej vybral.
poradce string ano Poradce.
status ConsultationStatus → ConsultationStatus ano Jak skončila.
postoj Stance | null → Stance ne Kde stojí rada.
závěr string | null ne Rada, shrnutě.
diagnostika string | null ne Diagnostika adaptéru při selhání.

Používá ReasoningState

DisagreementPosition

object
Jedna strana nesouhlasu: čí je to stanovisko a stanovisko v jedné větě.

Zdrojem je primary pro executora nebo id dokončené konzultace; úložiště odmítne pozici, jejímž zdrojem je konzultace, která nebyla dokončena.

use majordomus_cli::reasoning::record::DisagreementPosition;

let p = DisagreementPosition { source: "primary".into(), position: "keep the lock".into() };
let json = serde_json::to_value(&p).unwrap();
assert_eq!(json, serde_json::json!({ "source": "primary", "position": "keep the lock" }));
vlastnosttyppovinnépopis
zdroj string ano Čí pozice: primary, nebo id záznamu dokončené konzultace.
pozice string ano Pozice na jednom řádku.

Používá ReasoningBody ReasoningInput

DisagreementView

object
Jeden rozpor, tak jak jej stav hlásí.

Pohled jmenuje otázku, která rozpor rozhoduje, a po zaznamenání rozřešení i rozřešení a pozici, kterou jeho důkazy favorizovaly. Pohled bez rozřešení je nevyřešený rozpor, který blokuje jeho posouzení.

#### 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::{derive, DisagreementView};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("disagreement-1", 1, json!({
    "kind": "disagreement", "assessment": "assessment-0",
    "positions": [
        { "source": "primary", "position": "A" },
        { "source": "consultation-9", "position": "B" },
    ],
    "discriminating_question": "do callers retry?",
})));
loaded.records.push(rec("resolution-2", 2, json!({
    "kind": "resolution", "disagreement": "disagreement-1",
    "experiment": "read the callers", "outcome": "none retries",
    "favours": "consultation-9",
    "evidence": [{ "kind": "file", "reference": "src/caller.rs" }],
})));
let state = derive(&loaded, None);
let view: &DisagreementView = &state.disagreements[0];
assert_eq!(view.discriminating_question, "do callers retry?");
assert_eq!(view.resolution.as_deref(), Some("resolution-2"));
assert_eq!(view.favours.as_deref(), Some("consultation-9"));
vlastnosttyppovinnépopis
id string ano Id záznamu.
posouzení string ano Posouzení.
discriminating_question string ano Otázka, která rozhoduje.
rozlišení string | null ne Rozřešení, když je ustáleno.
upřednostňuje string | null ne Pozice, kterou důkazy upřednostnily.

Používá ReasoningState

ExcludedAdvisor

object
Jeden poradce vynechaný z plánu, jeho stav v době sestavení plánu a proč: jeho stav, schopnost, kterou nenabízí, nebo už vyčerpaný rozpočet.

use majordomus_cli::reasoning::availability::{AdvisorState, AdvisorStatus, ModeResolution, ReasoningMode};
use majordomus_cli::reasoning::policy::{plan, ExcludedAdvisor, Materiality, PlanRequest};

fn advisor(id: &str, adapter: &str, status: &str) -> AdvisorState {
    serde_json::from_value(serde_json::json!({
        "id": id, "title": id, "transport": "api", "adapter": adapter,
        "capabilities": ["independent_reasoning"], "status": status,
        "reason": "present", "probe": "",
    }))
    .unwrap()
}
let mode = ModeResolution { mode: ReasoningMode::Standard, source: "default".into() };
let request = PlanRequest { materiality: Materiality::Material, ..Default::default() };
let states = [advisor("a", "x-api", "available"), advisor("b", "y-api", "available")];
let p = plan(&request, &mode, &states);
let left: &ExcludedAdvisor = &p.excluded[0];
assert_eq!((left.advisor.as_str(), left.status), ("b", AdvisorStatus::Available));
assert!(left.reason.contains("budget was spent"));
vlastnosttyppovinnépopis
poradce string ano Id poradce.
status AdvisorStatus → AdvisorStatus ano Jeho stav, když byl plán vytvořen.
důvod string ano Proč není v plánu.

Používá ReviewPlan

Podstatnost

"trivial" | "low" | "material" | "high" | "critical"
Jak moc by nejisté rozhodnutí mohlo záležet. Seřazeno od trivial po critical: s režimem nastavuje rozpočet review a od material výše nese rozhodnutí učiněné samostatně strukturované lokální review.

use majordomus_cli::reasoning::policy::Materiality;

assert_eq!(Materiality::default(), Materiality::Low);
assert!(Materiality::Material < Materiality::Critical);
let m: Materiality = serde_json::from_str("\"high\"").unwrap();
assert_eq!(m, Materiality::High);
  • trivialNázev, formát, zřejmá konvence: nikdy se neposuzuje.
  • lowLokální a vratné.
  • materialMohlo by ovlivnit správnost, rozhraní, perzistentní data, souběžnost, provoz.
  • highArchitektura, bezpečnost, kompatibilita nebo veřejný kontrakt.
  • criticalNevratné nebo destruktivní, nebo samotná governance repozitáře.

Používá reasoning.plan AssessmentView ReasoningBody ReasoningInput ReviewPlan

ModeResolution

object
Platný režim a co o něm rozhodlo, tak jak ho vrací resolve_mode. Plán i zpráva nesou zdroj vedle režimu, takže čtenář zjistí, proč je režim takový, jaký je.

use majordomus_cli::reasoning::availability::{resolve_mode, ModeResolution, ReasoningMode};

let r: ModeResolution = resolve_mode(None, true, None);
assert_eq!(r, ModeResolution { mode: ReasoningMode::Ci, source: "CI".into() });
vlastnosttyppovinnépopis
režim ReasoningMode → ReasoningMode ano Režim.
zdroj string ano Co rozhodlo: MAJORDOMUS_REASONING_MODE, CI, profile <name> nebo default.

Používá AdvisorsReport ReasoningStatus

PlanOutcome

"consult" | "decide_locally" | "reuse_prior"
O čem plán rozhodl: konzultovat vybrané poradce, rozhodnout na lokálních důkazech, nebo znovu použít platný závěr. Rozhodnutí lokálně je běžný výsledek, ne selhání.

use majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};
use majordomus_cli::reasoning::policy::{plan, Materiality, PlanOutcome, PlanRequest};

let mode = ModeResolution { mode: ReasoningMode::Ci, source: "CI".into() };
let request = PlanRequest { materiality: Materiality::Critical, ..Default::default() };
let outcome: PlanOutcome = plan(&request, &mode, &[]).outcome;
assert_eq!(outcome, PlanOutcome::DecideLocally);
assert_eq!(serde_json::to_value(outcome).unwrap(), "decide_locally");
  • consultPoraďte se s vybranými poradci, poté uzavřete.
  • decide_locallyRozhodnout na lokálních důkazech; nezávislé review se nevyžaduje, nebo není k dispozici.
  • reuse_priorTrvalý závěr už na to odpovídá; použijte ho místo opětovného ptaní.

Používá ReviewPlan

ReasoningBody

jedna z 8 variant
Tělo uloženého záznamu: přijatý vstup s tím, co zapisovatel vypočetl.

Zrcadlí ReasoningInput variantu po variantě, až na to, že plán se ukládá jako StoredPlan a závěr jako StoredConclusion. Vyrábí ho jen úložiště, když přijme vstup; jeho forma JSON je označena kind stejně jako vstup.

use majordomus_cli::reasoning::record::{AssessmentInput, ReasoningBody};

let body = ReasoningBody::Assessment(AssessmentInput {
    subject: "lock scope".into(),
    ..Default::default()
});
assert_eq!(body.kind(), "assessment");
assert_eq!(serde_json::to_value(&body).unwrap()["kind"], "assessment");
variant Podstatná nejistota.
předmětstringanoCo je nejisté, jednou řádkou. Pozdější posouzení téhož subjektu skrze ni nacházejí závěry dřívějších.
podstatnostPodstatnost → MaterialityneJak moc na rozhodnutí může záležet.
jistotaReasoningConfidence → ReasoningConfidenceneJak si je executor jistý svou hypotézou.
hypotézastring | nullneAktuální hypotéza.
ovlivňujearray of stringneČeho by se rozhodnutí mohlo týkat: public_api, persistent_data, security, concurrency, architecture, ...
faktaarray of stringneCo je známo.
předpokladyarray of stringneCo se předpokládá.
otázkyarray of stringneCo je stále otevřené.
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy shromážděné lokálně.
capabilitiesarray of stringneAdvisory schopnosti, které by recenze potřebovala; prázdné znamená independent_reasoning.
new_evidencebooleannePosouzení přináší důkazy, které stávající závěr o subjektu neměl, takže na ně tento závěr neodpovídá.
druh"assessment"ano
varianta Plán se snímkem dostupnosti.
druh"plan"ano
variant Jedna výměna s poradcem.
planstringanoZaznamenaný plán, který vybral tohoto poradce.
poradcestringanoDotazovaný poradce.
statusConsultationStatus → ConsultationStatusanoJak skončila.
otázkastring | nullnePoložená otázka na jeden řádek (celý prompt se neuchovává).
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy, které dotaz nesl.
závěrstring | nullneShrnutí závěru poradce. Povinné při completed, jinak odmítnuto.
postojStance | null → StanceneKde stojí vzhledem k hypotéze.
předpokladyarray of stringnePředpoklady, které identifikoval.
rizikaarray of stringneRizika, která identifikovala.
akcearray of stringneAkce, které doporučila.
vyvracející podmínkyarray of stringneCo by jeho závěr vyvrátilo.
jistotaReasoningConfidence | null → ReasoningConfidenceneJejí uváděná důvěra.
duration_msinteger | nullneJak dlouho to trvalo, milisekundy.
použitíAdvisorUsage | null → AdvisorUsageneKolik transport ohlásil, že to stálo.
diagnostikastring | nullneDiagnostika adaptéru pro selhání: třída a věta, nikdy ne obsah.
retry_after_secondsinteger | nullneRetry-after limitu četnosti, v sekundách.
druh"consultation"ano
variant Neshoda.
posouzenístringanoPosouzení, o kterém se mluví.
pozicepole DisagreementPosition → DisagreementPositionanoPozice; alespoň dvě.
divergent_assumptionsarray of stringnePředpoklady, v nichž se pozice dělí.
discriminating_questionstringanoOtázka, jejíž odpověď mezi nimi rozhoduje.
experimentstring | nullneExperiment navržený k zodpovězení.
druh"disagreement"ano
varianta Neshoda rozhodnutá důkazem.
neshodastringanoSpor, který rozhoduje.
experimentstringanoProvedený pokus.
výsledekstringanoCo ukázala.
upřednostňujestringanoPozice, kterou preferuje: source neshody, nebo neither.
evidencepole ReasoningEvidence → ReasoningEvidenceanoDůkazy, které vytvořila; alespoň jedna reference.
druh"resolution"ano
varianta Inženýrský závěr s jeho vypočteným review.
druh"conclusion"ano
variant Provedený validační krok.
závěrstringanoZávěr je ověřen.
checkstringanoCo bylo zkontrolováno, na jeden řádek.
commandstring | nullnePříkaz, který to zkontroloval.
výsledekValidationOutcome → ValidationOutcomeanoJak to dopadlo.
evidencepole ReasoningEvidence → ReasoningEvidenceneCo vyprodukovalo.
druh"validation"ano
variant Neúspěšný pokus.
posouzenístring | nullnePosouzení, kterého se týká, pokud nějaké je.
pokusstringanoCo se zkoušelo.
observed_failurestringanoCo selhalo, pozorováno.
assumption_invalidatedstring | nullnePředpoklad, který selhání zneplatnilo.
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy, které selhání vyprodukovalo.
updated_hypothesisstring | nullneHypotéza nyní.
druh"attempt"ano

Používá ReasoningRecord

ReasoningCheck

object
Odpověď reasoning.check: zda je čistý, provedené kontroly v pořadí a každý nález. ok je true právě tehdy, když je findings prázdné.

use majordomus_cli::capability::builtin::reasoning::ReasoningCheck;

let clean: ReasoningCheck = serde_json::from_value(serde_json::json!({
    "ok": true, "checks": ["catalogue"], "findings": [],
})).unwrap();
assert!(clean.ok && clean.findings.is_empty());
assert_eq!(clean.checks, ["catalogue"]);
vlastnosttyppovinnépopis
ok boolean ano Žádný nález.
kontroly array of string ano Provedené kontroly, v pořadí.
zjištění pole ReasoningFinding → ReasoningFinding ano Co našly.

Používá reasoning.check

ReasoningConfidence

"low" | "medium" | "high"
Jak si je primární executor jistý svou aktuální hypotézou. high snižuje rozpočet review o jedna; ostatní úrovně ho nechávají tak, jak ho nastavují režim a významnost.

use majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};
use majordomus_cli::reasoning::policy::{plan, Materiality, PlanRequest, ReasoningConfidence};

let mode = ModeResolution { mode: ReasoningMode::Strict, source: "default".into() };
let budget = |confidence: ReasoningConfidence| {
    let request = PlanRequest { materiality: Materiality::Critical, confidence, ..Default::default() };
    plan(&request, &mode, &[]).budget
};
assert_eq!(budget(ReasoningConfidence::Medium), 3);
assert_eq!(budget(ReasoningConfidence::High), 2);
  • lowOdhad, který důkazy zatím nepodporují.
  • mediumPodporováno, s otevřenými otázkami.
  • highPodloženo důkazy, které by bylo těžké vyvrátit.

Používá reasoning.plan ReasoningBody ReasoningInput ReviewPlan StoredConclusion

ReasoningEvidence

object
Odkaz na něco, co podporuje tvrzení.

Důkaz je ukazatel, nikdy kopie: cesta, případ, id nebo příkazová řádka, s volitelnou jednořádkovou poznámkou, co ukazuje. Neznámá pole se odmítají, takže chybně napsané pole je chyba, ne tiše zahozené tvrzení.

use majordomus_cli::reasoning::record::{ReasoningEvidence, ReasoningEvidenceKind};

let e: ReasoningEvidence = serde_json::from_value(serde_json::json!({
    "kind": "file",
    "reference": "src/worker.rs:42",
}))
.unwrap();
assert_eq!(e.kind, ReasoningEvidenceKind::File);
assert_eq!(e.note, None);

let typo = serde_json::from_value::<ReasoningEvidence>(serde_json::json!({
    "kind": "file", "reference": "x", "notes": "misspelt",
}));
assert!(typo.is_err());
vlastnosttyppovinnépopis
druh ReasoningEvidenceKind → ReasoningEvidenceKind ano Co to je.
reference string ano Kde to je: cesta, případ, id, příkazový řádek.
poznámka string | null ne Co ukazuje, v jednom řádku.

Používá ReasoningBody ReasoningInput StoredConclusion

ReasoningEvidenceKind

"file" | "test" | "adr" | "rule" | "commit" | "command" | "record" | "document" | "runtime" | "prior_external_opinion"
Co je důkaz.

Druh říká čtenáři, jak odkaz sledovat: otevřít soubor, spustit test, přečíst ADR nebo pravidlo, ukázat commit. Dřívější externí názor je samostatný druh, aby dřívější závěr poradce, předaný jinému poradci, nebyl nikdy čten jako fakt.

use majordomus_cli::reasoning::record::ReasoningEvidenceKind;

let kind: ReasoningEvidenceKind = serde_json::from_str("\"prior_external_opinion\"").unwrap();
assert_eq!(kind, ReasoningEvidenceKind::PriorExternalOpinion);
assert_eq!(serde_json::to_string(&ReasoningEvidenceKind::Adr).unwrap(), "\"adr\"");
  • fileSoubor repozitáře, volitelně s řádkem: src/x.rs:42.
  • testTestovací případ nebo název testu.
  • adrZáznam architektonického rozhodnutí.
  • rulePravidlo vrstvy.
  • commitCommit.
  • commandPříkaz, který byl spuštěn, a co ukázal.
  • recordDalší záznam úvahy.
  • documentDocumentation.
  • runtimePozorování za běhu: log, měření, diagnostika.
  • prior_external_opinionPředchozí externí názor: závěr jednoho poradce předaný jinému poradci. Označeno tak, aby se nikdy nezaměnilo za fakt.

Používá ReasoningEvidence

ReasoningExplanation

object
Záznam se vším, na čem stojí, a vším, co stojí na něm.

Nese samotný záznam, posouzení, ke kterému patří, a celý řetězec původu tohoto posouzení jako kroky časové osy v pořadí. Záznam, který nepatří k žádnému posouzení, má řetězec jen sám ze sebe.

#### 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);
vlastnosttyppovinnépopis
record ReasoningRecord → ReasoningRecord ano Záznam, na který se dotaz vztahuje.
posouzení string | null ne Posouzení, do kterého patří, pokud do nějakého patří.
řetěz pole ReasoningStep → ReasoningStep ano Každý záznam tohoto posouzení v pořadí: jeho řetěz původu.

Používá reasoning.explain

ReasoningFinding

object
Jeden nález reasoning check: která kontrola, kde a co je špatně.

check je jedno z CHECKS; subject je cesta relativní k repozitáři, id záznamu nebo advisor; message je jedna věta, která říká, co pravidlo zamítá. Zjištění se hlásí, nikdy neopravují.

use majordomus_cli::reasoning::catalogue::{AdvisorCatalogue, References};
use majordomus_cli::reasoning::check::{run, ReasoningFinding, CHECKS};
use majordomus_cli::reasoning::store::Loaded;

let root = tempfile::tempdir().unwrap();
let loaded = Loaded { records: vec![], unreadable: vec!["t/broken.json".into()] };
let found = run(root.path(), &AdvisorCatalogue::default(), &References::default(), &loaded);
let expected = ReasoningFinding {
    check: "records".into(),
    subject: "t/broken.json".into(),
    message: "a reasoning record that does not parse".into(),
};
assert_eq!(found, [expected]);
assert!(CHECKS.contains(&found[0].check.as_str()));
vlastnosttyppovinnépopis
check string ano Kontrola, která to našla.
předmět string ano Kde: soubor, záznam, poradce.
zpráva string ano Co je špatně.

Používá ReasoningCheck

ReasoningInput

jedna z 8 variant
Cokoli, co relace zaznamenává, tak jak bylo napsáno.

Forma JSON je označena pomocí kind, s poli varianty vedle značky. To přijímají povrchy CLI, HTTP a MCP; crate::reasoning::store::admit ji promění v uložené ReasoningBody, nebo ji odmítne.

use majordomus_cli::reasoning::record::ReasoningInput;

let input: ReasoningInput = serde_json::from_value(serde_json::json!({
    "kind": "plan",
    "assessment": "assessment-1",
}))
.unwrap();
assert!(matches!(input, ReasoningInput::Plan(ref p) if p.assessment == "assessment-1"));
let unknown = serde_json::json!({ "kind": "opinion", "text": "x" });
assert!(serde_json::from_value::<ReasoningInput>(unknown).is_err());
variant Podstatná nejistota.
předmětstringanoCo je nejisté, jednou řádkou. Pozdější posouzení téhož subjektu skrze ni nacházejí závěry dřívějších.
podstatnostPodstatnost → MaterialityneJak moc na rozhodnutí může záležet.
jistotaReasoningConfidence → ReasoningConfidenceneJak si je executor jistý svou hypotézou.
hypotézastring | nullneAktuální hypotéza.
ovlivňujearray of stringneČeho by se rozhodnutí mohlo týkat: public_api, persistent_data, security, concurrency, architecture, ...
faktaarray of stringneCo je známo.
předpokladyarray of stringneCo se předpokládá.
otázkyarray of stringneCo je stále otevřené.
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy shromážděné lokálně.
capabilitiesarray of stringneAdvisory schopnosti, které by recenze potřebovala; prázdné znamená independent_reasoning.
new_evidencebooleannePosouzení přináší důkazy, které stávající závěr o subjektu neměl, takže na ně tento závěr neodpovídá.
druh"assessment"ano
variant Vytvořit a zaznamenat plán pro posouzení.
posouzenístringanoPosouzení, na které plán odpovídá.
druh"plan"ano
variant Jedna výměna s poradcem.
planstringanoZaznamenaný plán, který vybral tohoto poradce.
poradcestringanoDotazovaný poradce.
statusConsultationStatus → ConsultationStatusanoJak skončila.
otázkastring | nullnePoložená otázka na jeden řádek (celý prompt se neuchovává).
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy, které dotaz nesl.
závěrstring | nullneShrnutí závěru poradce. Povinné při completed, jinak odmítnuto.
postojStance | null → StanceneKde stojí vzhledem k hypotéze.
předpokladyarray of stringnePředpoklady, které identifikoval.
rizikaarray of stringneRizika, která identifikovala.
akcearray of stringneAkce, které doporučila.
vyvracející podmínkyarray of stringneCo by jeho závěr vyvrátilo.
jistotaReasoningConfidence | null → ReasoningConfidenceneJejí uváděná důvěra.
duration_msinteger | nullneJak dlouho to trvalo, milisekundy.
použitíAdvisorUsage | null → AdvisorUsageneKolik transport ohlásil, že to stálo.
diagnostikastring | nullneDiagnostika adaptéru pro selhání: třída a věta, nikdy ne obsah.
retry_after_secondsinteger | nullneRetry-after limitu četnosti, v sekundách.
druh"consultation"ano
variant Neshoda.
posouzenístringanoPosouzení, o kterém se mluví.
pozicepole DisagreementPosition → DisagreementPositionanoPozice; alespoň dvě.
divergent_assumptionsarray of stringnePředpoklady, v nichž se pozice dělí.
discriminating_questionstringanoOtázka, jejíž odpověď mezi nimi rozhoduje.
experimentstring | nullneExperiment navržený k zodpovězení.
druh"disagreement"ano
varianta Neshoda rozhodnutá důkazem.
neshodastringanoSpor, který rozhoduje.
experimentstringanoProvedený pokus.
výsledekstringanoCo ukázala.
upřednostňujestringanoPozice, kterou preferuje: source neshody, nebo neither.
evidencepole ReasoningEvidence → ReasoningEvidenceanoDůkazy, které vytvořila; alespoň jedna reference.
druh"resolution"ano
variant Inženýrský závěr.
posouzenístringanoPosouzení, k jakému dospívá.
rozhodnutístringanoRozhodnutí.
zdůvodněnístringanoProč, z důkazů.
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy, o které se opírá. Vyžadováno pro podstatnou nejistotu.
konzultacearray of stringneDokončené konzultace, které zvážila.
nesrovnalostiarray of stringneVyřešené neshody, na nichž spočívá.
zamítnutoarray of stringneZvažované a zamítnuté alternativy, každá s důvodem.
předpokladyarray of stringnePředpoklady, na nichž stále závisí.
rizikaarray of stringneRizika, která zůstávají.
validation_planarray of stringneJak bude rozhodnutí prokázáno. Vyžadováno pro podstatnou nejistotu.
jistotaReasoningConfidence → ReasoningConfidenceneDůvěra v něj.
supersedesstring | nullneDřívější závěr, který tento nahrazuje, protože ho nové důkazy vyvrátily.
druh"conclusion"ano
variant Provedený validační krok.
závěrstringanoZávěr je ověřen.
checkstringanoCo bylo zkontrolováno, na jeden řádek.
commandstring | nullnePříkaz, který to zkontroloval.
výsledekValidationOutcome → ValidationOutcomeanoJak to dopadlo.
evidencepole ReasoningEvidence → ReasoningEvidenceneCo vyprodukovalo.
druh"validation"ano
variant Neúspěšný pokus.
posouzenístring | nullnePosouzení, kterého se týká, pokud nějaké je.
pokusstringanoCo se zkoušelo.
observed_failurestringanoCo selhalo, pozorováno.
assumption_invalidatedstring | nullnePředpoklad, který selhání zneplatnilo.
evidencepole ReasoningEvidence → ReasoningEvidenceneDůkazy, které selhání vyprodukovalo.
updated_hypothesisstring | nullneHypotéza nyní.
druh"attempt"ano

Používá ReasoningRecordInput

ReasoningMode

"offline" | "ci" | "fast" | "standard" | "strict"
Kolik nezávislého posouzení smí relace použít a odkud. Politika z toho čte rozpočet na posouzení; dostupnost z toho čte, které poradce vynechat (ci všechny, offline každého, který opouští stroj). Výchozí je standard.

use majordomus_cli::reasoning::availability::ReasoningMode;

assert_eq!(ReasoningMode::default(), ReasoningMode::Standard);
assert_eq!(serde_json::to_value(ReasoningMode::Offline).unwrap(), "offline");
let m: ReasoningMode = serde_json::from_str("\"strict\"").unwrap();
assert_eq!(m, ReasoningMode::Strict);
  • offlineŽádná síť: jen poradci, kteří zůstávají na tomto stroji.
  • ciDeterministické: žádný poradce vůbec, ať je nainstalováno cokoli.
  • fastReview jen tam, kde je dosah škod vysoký.
  • standardReview tam, kde je nejistota podstatná.
  • strictRevize širší a doplňková revize tam, kde jsou sázky nejvyšší.

Používá ModeResolution ReviewPlan

ReasoningPhase

"uncertainty" | "consulting" | "local" | "reuse" | "advisor_response" | "degradation" | "disagreement" | "experiment" | "conclusion" | "validation" | "attempt"
Fáze časové osy uvažování.

Každý záznam se mapuje na jednu fázi: plán na consulting, local nebo reuse podle jeho výsledku, konzultace na odpověď poradce nebo degradaci podle jejího stavu a každý jiný druh na fázi stejného jména.

#### 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::{derive, ReasoningPhase};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("consultation-1", 1, json!({
    "kind": "consultation", "plan": "plan-0", "advisor": "alpha", "status": "unavailable",
})));
let phases: Vec<ReasoningPhase> =
    derive(&loaded, None).timeline.iter().map(|s| s.phase).collect();
assert_eq!(phases, [ReasoningPhase::Degradation]);
let word = serde_json::to_value(ReasoningPhase::AdvisorResponse).unwrap();
assert_eq!(word, "advisor_response");
  • uncertaintyNejistota vyslovená s důkazy.
  • consultingRevize plánována.
  • localRozhodnuto lokálně, podle plánu.
  • reuseTrvalý závěr, použitý znovu.
  • advisor_responsePoradce odpověděl.
  • degradationPoradce nemohl odpovědět.
  • disagreementPozice se rozešly.
  • experimentExperiment rozhodl spor.
  • conclusionZávěr.
  • validationKrok validace.
  • attemptNeúspěšný pokus.

Používá ReasoningStep

ReasoningRecord

object
Uložený záznam: tělo s obálkou, kterou razítkuje jen zapisovatel.

Obálka nese schéma a verzi, jedinečné id, úlohu, čas zaznamenání, commit, na kterém checkout byl, a tvary tajemství vyredigované z jejího textu. Jeden záznam je jeden soubor JSON v úložišti; úložiště čte zpět jen záznamy, jejichž schéma a verze odpovídají.

use majordomus_cli::reasoning::record::*;

let record = ReasoningRecord {
    schema: RECORD_SCHEMA.into(),
    version: RECORD_VERSION,
    id: "attempt-20261001T000000Z-abcdef".into(),
    task: "untasked".into(),
    recorded_at: "2026-10-01T00:00:00Z".into(),
    head: None,
    redacted: vec![],
    body: ReasoningBody::Attempt(AttemptInput {
        assessment: None,
        attempt: "inline the call".into(),
        observed_failure: "the test still fails".into(),
        assumption_invalidated: None,
        evidence: vec![],
        updated_hypothesis: None,
    }),
};
let text = serde_json::to_string(&record).unwrap();
assert!(!text.contains("\"head\""), "an absent head is not written");
let back: ReasoningRecord = serde_json::from_str(&text).unwrap();
assert_eq!(back.id, record.id);
assert_eq!(back.body.kind(), "attempt");
vlastnosttyppovinnépopis
schema string ano RECORD_SCHEMA.
verze integer (uint32) ano RECORD_VERSION.
id string ano <kind>-<yyyymmddThhmmssZ>-<hex>, jedinečné v úložišti.
úloha string ano Úloha, pod kterou byl zaznamenán, nebo untasked.
recorded_at string ano Kdy bylo zaznamenáno, RFC 3339; razítko doplňuje zapisovatel, nikdy se nedodává.
head string | null ne Commit, na kterém checkout byl.
zredigováno array of string ne Tvary tajemství, které zapisovatel z textu odstranil, podle názvu tvaru.
tělo ReasoningBody → ReasoningBody ano Záznam.

Používá ReasoningExplanation ReasoningRecorded

ReasoningRecordInput

object
Vstup reasoning.record: jeden záznam, jak je napsán, označený svým kind. Vše ostatní (id, úlohu, razítko, výběr plánu) si zapisovač vypočítá sám.

use majordomus_cli::capability::builtin::reasoning::ReasoningRecordInput;
use majordomus_cli::reasoning::record::ReasoningInput;

let input: ReasoningRecordInput = serde_json::from_value(serde_json::json!({
    "record": { "kind": "plan", "assessment": "assessment-1" },
})).unwrap();
assert!(matches!(input.record, ReasoningInput::Plan(ref p) if p.assessment == "assessment-1"));
vlastnosttyppovinnépopis
record ReasoningInput → ReasoningInput ano Záznam.

Používá reasoning.record

ReasoningRecorded

object
Odpověď reasoning.record: záznam tak, jak je uložen, kam byl zapsán, a krok časové osy, který přidává.

use majordomus_cli::capability::builtin::reasoning::ReasoningRecorded;

let schema = serde_json::to_value(schemars::schema_for!(ReasoningRecorded)).unwrap();
for field in ["record", "path", "step"] {
    assert!(schema["required"].as_array().unwrap().iter().any(|f| f == field), "{field}");
}
vlastnosttyppovinnépopis
record ReasoningRecord → ReasoningRecord ano Uložený záznam.
path string ano Kam byl zapsán, relativně k repozitáři.
krok ReasoningStep → ReasoningStep ano Krok, který přidává do časové osy: report, který ukazuje terminál nebo Cockpit.

Používá reasoning.record

ReasoningState

object
Stav uvažování úlohy (nebo každé úlohy).

Je to to, co hlásí každý povrch: posouzení, konzultace, spory a závěry úlohy, časová osa každého záznamu, součty a soubory úložiště, které nebylo možné přečíst. Odvozeno pomocí derive(), nikdy neukládáno.

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

let mut loaded = Loaded::default();
let assessment = |subject: &str| json!({ "kind": "assessment", "subject": subject });
loaded.records.push(rec("assessment-1", "t1", assessment("a")));
loaded.records.push(rec("assessment-2", "t2", assessment("b")));
loaded.unreadable.push("t2/broken.json".into());

let one: ReasoningState = derive(&loaded, Some("t1"));
assert_eq!((one.task.as_str(), one.assessments.len()), ("t1", 1));
let all = derive(&loaded, None);
assert_eq!((all.task.as_str(), all.totals.records), ("all", 2));
assert_eq!(all.unreadable, ["t2/broken.json"]);
vlastnosttyppovinnépopis
úloha string ano Hlášená úloha, nebo all.
posouzení pole AssessmentView → AssessmentView ano Posouzení.
konzultace pole ConsultationView → ConsultationView ano Konzultace.
nesrovnalosti pole DisagreementView → DisagreementView ano Rozpory.
závěry pole ConclusionView → ConclusionView ano Závěry.
časová osa pole ReasoningStep → ReasoningStep ano Časová osa.
součty ReasoningTotals → ReasoningTotals ano Totals.
nečitelné array of string ne Soubory úložiště, které nešlo přečíst.

Používá ReasoningStatus

ReasoningStatus

object
Odpověď reasoning.status: platný režim, počty poradců, stav, který záznamy odvozují, a tento stav vykreslený jako Markdown, který nese předávka.

use majordomus_cli::capability::builtin::reasoning::ReasoningStatus;

let schema = serde_json::to_value(schemars::schema_for!(ReasoningStatus)).unwrap();
for field in ["mode", "advisors_available", "advisors_unavailable", "state", "report"] {
    assert!(schema["required"].as_array().unwrap().iter().any(|f| f == field), "{field}");
}
vlastnosttyppovinnépopis
režim ModeResolution → ModeResolution ano Platný režim.
advisors_available integer (uint) ano Aktuálně dostupní poradci.
advisors_unavailable integer (uint) ano Poradci, kteří teď nejsou k dispozici, každý nepovinný.
state ReasoningState → ReasoningState ano Stav.
report string ano Stav jako Markdown: co nese předávka.

Používá reasoning.status

ReasoningStep

object
Jeden krok časové osy: kdy, který záznam, která fáze a jedna řádka o tom, co se stalo.

Shrnutí se ořízne na jediný řádek o nejvýše 140 znacích, takže časová osa se vykreslí stejně v terminálu, na stránce i v předávce.

#### 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::{derive, ReasoningPhase, ReasoningStep};
use majordomus_cli::reasoning::store::Loaded;

let mut loaded = Loaded::default();
loaded.records.push(rec("attempt-1", 1, json!({
    "kind": "attempt", "attempt": "share the client\nacross threads",
    "observed_failure": "the handle is not Sync",
})));
let state = derive(&loaded, None);
let step: &ReasoningStep = &state.timeline[0];
assert_eq!(step.at, "2026-10-01T00:00:01Z");
assert_eq!(step.phase, ReasoningPhase::Attempt);
assert_eq!(step.summary, "share the client failed: the handle is not Sync");
vlastnosttyppovinnépopis
v string ano When.
id string ano Záznam.
fáze ReasoningPhase → ReasoningPhase ano Fáze.
summary string ano Jedna řádka.

Používá ReasoningExplanation ReasoningRecorded ReasoningState

ReasoningTotals

object
Součty přes záznamy odvozené úlohy: počty, recenzenti a hlášené tokeny.

Nezávislí recenzenti jsou odlišní poradci s alespoň jednou dokončenou konzultací; počty tokenů se sčítají jen z toho, co adaptéry nahlásily, nikdy se neodhadují.

#### 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::{derive, ReasoningTotals};
use majordomus_cli::reasoning::store::Loaded;

let answer = |plan: &str| {
    json!({
        "kind": "consultation", "plan": plan, "advisor": "alpha", "status": "completed",
        "conclusion": "A", "stance": "supports",
        "usage": { "input_tokens": 100, "output_tokens": 20 },
    })
};
let mut loaded = Loaded::default();
loaded.records.push(rec("consultation-1", 1, answer("plan-a")));
loaded.records.push(rec("consultation-2", 2, answer("plan-b")));
let totals: ReasoningTotals = derive(&loaded, None).totals;
assert_eq!(totals.consultations_completed, 2);
assert_eq!(totals.independent_reviewers, 1, "one advisor, however often asked");
assert_eq!((totals.input_tokens, totals.output_tokens), (200, 40));
vlastnosttyppovinnépopis
records integer (uint) ano Records.
consultations_completed integer (uint) ano Dokončené konzultace.
consultations_failed integer (uint) ano Konzultace, které ne.
independent_reviewers integer (uint) ano Odlišní poradci, kteří odpověděli.
input_tokens integer (uint64) ano Vstupní tokeny, které adaptéry ohlásily.
output_tokens integer (uint64) ano Výstupní tokeny, které adaptéry hlásily.

Používá ReasoningState

ReviewPlan

object
Plán: rozhodnutí s přiloženými důvody. Nese to, na co odpovídalo (režim, významnost, jistota, schopnosti), rozpočet, výsledek s jednou větou proč, každého vybraného či vyloučeného advisora a lokální revizi, je-li na řadě.

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"));
vlastnosttyppovinnépopis
režim ReasoningMode → ReasoningMode ano Režim, ve kterém vznikl.
mode_source string ano Co rozhodlo o režimu.
podstatnost Podstatnost → Materiality ano Významnost, na kterou odpověděl.
jistota ReasoningConfidence → ReasoningConfidence ano Jistota, s níž odpověděl.
capabilities array of string ano Schopnosti, o jejichž recenzi se žádalo.
rozpočet integer (uint) ano Kolik poradců režim a podstatnost dovolují.
výsledek PlanOutcome → PlanOutcome ano Co dělat.
důvod string ano Proč, jednou větou.
vybráno pole SelectedAdvisor → SelectedAdvisor ano Poradci ke konzultaci, v pořadí výběru.
vyloučeno pole ExcludedAdvisor → ExcludedAdvisor ano Každý nevybraný poradce s důvodem.
dostupné integer (uint) ano Poradci dostupní v době tvorby plánu, ať byl vybrán kdokoli.
local_review array of string ne Strukturovaná lokální revize k provedení, když na materiální nejistotu nestačí žádný poradce.

Používá reasoning.plan StoredPlan

SelectedAdvisor

object
Jeden vybraný poradce, požadované schopnosti, které pokrývá, a proč ho chamtivý výběr zvolil na jeho pozici.

use majordomus_cli::reasoning::availability::{AdvisorState, ModeResolution, ReasoningMode};
use majordomus_cli::reasoning::policy::{plan, Materiality, PlanRequest, SelectedAdvisor};

fn advisor(id: &str, adapter: &str, status: &str) -> AdvisorState {
    serde_json::from_value(serde_json::json!({
        "id": id, "title": id, "transport": "api", "adapter": adapter,
        "capabilities": ["independent_reasoning"], "status": status,
        "reason": "present", "probe": "",
    }))
    .unwrap()
}
let mode = ModeResolution { mode: ReasoningMode::Standard, source: "default".into() };
let request = PlanRequest { materiality: Materiality::Material, ..Default::default() };
let p = plan(&request, &mode, &[advisor("a", "x-api", "available")]);
let chosen: &SelectedAdvisor = &p.selected[0];
assert_eq!(chosen.advisor, "a");
assert_eq!(chosen.covers, ["independent_reasoning"]);
assert!(chosen.why.starts_with("the first available advisor"));
vlastnosttyppovinnépopis
poradce string ano Id poradce.
pokrývá array of string ano Požadované schopnosti, které pokrývá.
why string ano Proč byl zvolen.

Používá ReviewPlan

Postoj

"supports" | "opposes" | "alternative" | "inconclusive"
Kde stojí odpověď advisora vůči hypotéze executoru.

Dokončená konzultace musí uvést svůj postoj; úložiště odmítne tu, která jej nemá. Postoj je štítek pro časovou osu, ne hlas: shoda nic nerozhoduje.

use majordomus_cli::reasoning::record::Stance;

let s: Stance = serde_json::from_str("\"alternative\"").unwrap();
assert_eq!(s, Stance::Alternative);
assert!(serde_json::from_str::<Stance>("\"agrees\"").is_err());
  • supportsPodporuje hypotézu.
  • opposesArgumentuje proti tomu.
  • alternativeNavrhuje něco jiného.
  • inconclusiveNerozhoduje.

Používá ConsultationView ReasoningBody ReasoningInput

StoredConclusion

object
Závěr tak, jak je uložen: vstup a to, co spočítá jen zapisovatel.

Vstup je zploštěn, takže uložený závěr se čte jako vstup plus dvě pole: poradci, jejichž dokončené konzultace cituje, každý jednou a v kanonickém pořadí, a jejich počet. Obě se počítají při přijetí a znovu je kontroluje reasoning.check, takže ručně upravený počet se ohlásí.

use majordomus_cli::reasoning::record::{ConclusionInput, StoredConclusion};

let stored = StoredConclusion {
    input: ConclusionInput {
        assessment: "assessment-1".into(),
        decision: "keep the lock".into(),
        rationale: "measured".into(),
        ..Default::default()
    },
    reviewed_by: vec!["alpha".into()],
    independent_review_count: 1,
};
let json = serde_json::to_value(&stored).unwrap();
assert_eq!(json["decision"], "keep the lock");
assert_eq!(json["independent_review_count"], 1);
vlastnosttyppovinnépopis
posouzení string ano Posouzení, k jakému dospívá.
rozhodnutí string ano Rozhodnutí.
zdůvodnění string ano Proč, z důkazů.
evidence pole ReasoningEvidence → ReasoningEvidence ne Důkazy, o které se opírá. Vyžadováno pro podstatnou nejistotu.
konzultace array of string ne Dokončené konzultace, které zvážila.
nesrovnalosti array of string ne Vyřešené neshody, na nichž spočívá.
zamítnuto array of string ne Zvažované a zamítnuté alternativy, každá s důvodem.
předpoklady array of string ne Předpoklady, na nichž stále závisí.
rizika array of string ne Rizika, která zůstávají.
validation_plan array of string ne Jak bude rozhodnutí prokázáno. Vyžadováno pro podstatnou nejistotu.
jistota ReasoningConfidence → ReasoningConfidence ne Důvěra v něj.
supersedes string | null ne Dřívější závěr, který tento nahrazuje, protože ho nové důkazy vyvrátily.
reviewed_by array of string ano Poradci, jejichž dokončené konzultace cituje, každý jednou. Vypočteno.
independent_review_count integer (uint) ano Kolik nezávislých poradců jej posoudilo: délka reviewed_by. Počítáno.

Používá ReasoningBody

StoredPlan

object
Plán tak, jak je uložen: rozhodnutí a dostupnost, proti níž bylo učiněno.

Store ji staví, když přijímá PlanInput; nic jiného ne. Snapshot dostupnosti je to, proti čemu se přijímá pozdější konzultace, takže odpověď, která dorazí po otevření okruhu poradce, stále patří plánu, který se na ni ptal.

use majordomus_cli::reasoning::availability::{ModeResolution, ReasoningMode};
use majordomus_cli::reasoning::policy::PlanOutcome;
use majordomus_cli::reasoning::record::*;
use majordomus_cli::reasoning::store::{admit, Admission, Loaded};

let mode = ModeResolution { mode: ReasoningMode::Standard, source: "default".into() };
let admission = Admission { mode: &mode, availability: &[] };
let mut loaded = Loaded::default();
loaded.records.push(ReasoningRecord {
    schema: RECORD_SCHEMA.into(),
    version: RECORD_VERSION,
    id: "assessment-1".into(),
    task: "t".into(),
    recorded_at: "2026-10-01T00:00:01Z".into(),
    head: None,
    redacted: vec![],
    body: ReasoningBody::Assessment(AssessmentInput {
        subject: "a name".into(),
        ..Default::default()
    }),
});
let input = ReasoningInput::Plan(PlanInput { assessment: "assessment-1".into() });
let ReasoningBody::Plan(stored) = admit(input, &loaded, &admission).unwrap() else {
    panic!("a plan input is stored as a plan");
};
let stored: StoredPlan = stored;
assert_eq!(stored.assessment, "assessment-1");
assert_eq!(stored.plan.outcome, PlanOutcome::DecideLocally);
assert!(stored.availability.is_empty());
vlastnosttyppovinnépopis
posouzení string ano Posouzení, na které odpovídá.
plan ReviewPlan → ReviewPlan ano Rozhodnutí.
dostupnost pole AdvisorState → AdvisorState ano Stav každého poradce v okamžiku plánu: snímek, proti kterému se přijímá pozdější konzultace.

Používá ReasoningBody

ValidationOutcome

"pass" | "fail"
Zda provedený krok validace prošel, nebo selhal.

Jedna neúspěšná validace stačí k tomu, aby se stav posouzení v odvozeném stavu označil jako validation_failed, ať prošlo cokoli jiného.

use majordomus_cli::reasoning::record::ValidationOutcome;

let o: ValidationOutcome = serde_json::from_str("\"fail\"").unwrap();
assert_eq!(o, ValidationOutcome::Fail);
assert_eq!(serde_json::to_string(&ValidationOutcome::Pass).unwrap(), "\"pass\"");
  • passProšlo to.
  • failSelhalo to.

Používá ReasoningBody ReasoningInput

Prohledává názvy a popisy všech stránek, které tento web publikuje.