knowledge_base.candidates
Každý znalostní záznam se stavem candidate ve zdrojové třídě kandidátů: jeho třída, tvrzení, epizoda, ze které vznikl, a branch této epizody a jak dlouho čeká — měřeno od derivace, která ho zapsala, pak od commitu, který ho přidal, a nakonec od jeho vlastního data — posuzováno podle session.freshness; proti limitu politiky. Kandidát, jehož epizodu tento checkout nezná, je uveden bez branche, nikoli skryt. Řazeno podle id.
Každý znalostní záznam se stavem candidate ve zdrojové třídě kandidátů: jeho třída, tvrzení, epizoda, ze které vznikl, a branch této epizody a jak dlouho čeká — měřeno od derivace, která ho zapsala, pak od commitu, který ho přidal, a nakonec od jeho vlastního data — posuzováno podle session.freshness; proti limitu politiky. Kandidát, jehož epizodu tento checkout nezná, je uveden bez branche, nikoli skryt. Řazeno podle id.
- query
- behaviorally_verified
- module knowledge_base
- #knowledge
- #continuity
Zpřístupnění
Kde je tato jedna definice dosažitelná. Absence je explicitní: povrch, který není uveden, ji nenese.
| povrch | jako |
|---|---|
| MCP | nástroj majordomus_knowledge_candidates zdroj majordomus://knowledge-candidates |
| HTTP | GET /api/v1/knowledge/candidates operationId knowledge_base.candidates |
| příkazová řádka | majordomus knowledge candidates |
Schémata
Kanonický vstup a výstup z typů Rustu; schéma nástroje MCP a parametry a odpovědi OpenAPI se odvozují z nich.
vstup · Prázdné
Žádné vlastnosti: schopnost nebere žádný vstup.
JSON Schema
{
"additionalProperties": false,
"description": "No input.",
"title": "Empty",
"type": "object"
}výstup · KnowledgeCandidates
use majordomus_cli::capability::builtin::knowledge_base::KnowledgeCandidates;
let empty: KnowledgeCandidates = serde_json::from_str(
r#"{"total":0,"on_this_branch":0,"unattributed":0,"branch":"master","candidates":[],"over_cap":false}"#,
).unwrap();
assert_eq!(empty.total, 0, "an empty queue is an answer");
assert_eq!(empty.cap, None, "and a policy without the key declares no cap");| vlastnost | typ | povinné | popis |
|---|---|---|---|
| větev | string | ano | Větev, jíž se tato odpověď týká, nebo DETACHED. |
| candidates | array | ne | Každý kandidát v kanonickém pořadí podle id. |
| cap | integer | null | ne | knowledge.candidates_max_files, když to politika deklaruje. |
| zjištění | array | ne | Co by měl čtenář vědět, než předchozímu uvěří: poškozený záznam, který byl přeskočen, překročený limit, politika, která žádný nedeklaruje. Prázdné je dobrý případ. |
| skupiny | array | ne | Kandidáti a zamítnuté záznamy odvozené z pozorování, seskupené podle toho, čeho se týkají, v pořadí podle předmětu. |
| on_this_branch | integer | ano | Kolik z nich pochází z epizody na větvi tohoto checkoutu. |
| over_cap | boolean | ano | Pravda, když total překročí cap. Nepravda, když není deklarován žádný strop: nikdo žádný nezapsal. |
| celkem | integer | ano | Kolik záznamů nese status: candidate ve třídě kandidátů. |
| nepřiřazeno | integer | ano | Kolik jich jmenuje epizodu, o které tento checkout nic neví. |
JSON Schema
{
"$defs": {
"AgeSource": {
"description": "Where the age of a candidate in the review queue was read from. A candidate's `date` is\nthe day of the evidence it came from, deliberately, so that the same evidence yields the\nsame bytes; the day it entered the queue is a different fact and is read from the ledger\nfirst, then from git, and only then from the record.\n\n```\nuse majordomus_cli::capability::builtin::knowledge_base::AgeSource;\nlet from_ledger: AgeSource = serde_json::from_str(r#\"\"derivation\"\"#).unwrap();\nassert_eq!(from_ledger, AgeSource::Derivation);\nassert!(AgeSource::Derivation < AgeSource::Date, \"the ledger is asked before the record\");\n```",
"oneOf": [
{
"const": "derivation",
"description": "The oldest `knowledge.derived` line in this checkout's ledger whose paths name it.",
"type": "string"
},
{
"const": "commit",
"description": "The commit that added the file to this history.",
"type": "string"
},
{
"const": "date",
"description": "The record's own `date`, at midnight UTC: the evidence day, not the queue day.",
"type": "string"
}
]
},
"Freshness": {
"description": "How old a record is, judged against `session.freshness` in the policy.\n\nThis is the second of two independent judgements every record carries, and it exists\nbecause the first one cannot answer this question. `Divergence` says where a record's\ncommit sits relative to HEAD; `advanced` means that commit is an ancestor of this one,\nwhich sounds like agreement and is identically true on the day the record is written and\na month later. Between 2026-09-05 and 2026-09-11 this repository served a handover that\nwas `advanced` and six days dead, and every surface that read this model — MCP, the HTTP\nAPI, the Cockpit — presented its `Next Action` as the thing to do (ADR 0052).\n\nThe thresholds are policy and are read, never restated here: a constant in this file\nwould be a second source of truth for a number the policy owns, and a repository whose\npolicy predates the key is reported as `Freshness::Unknown` naming the missing key\nrather than judged against a default nobody declared.\n\nThe five words divide into two groups, and the division is the one a caller acts on:\n`fresh` and `aging` are current and may be presented as the instruction, `stale` and\n`invalid` must be shown as history, and `unknown` is neither — a record nobody can date\nis not thereby an old record, and treating it as one would quietly discard a briefing\nthat is perfectly good. `Freshness::history` is that division, and it is the only\nplace it is decided.\n\n```\nuse majordomus_cli::capability::builtin::continuity::Freshness;\n\n// the two renderings are one value: the serialised word is the word `as_str` gives,\n// so a reader who met `stale` from MCP and from the command line met one fact\nlet stale = serde_json::to_value(Freshness::Stale).unwrap();\nassert_eq!(stale, serde_json::json!(\"stale\"));\nassert_eq!(stale.as_str(), Some(Freshness::Stale.as_str()));\n\n// and the division a caller acts on: absence of a judgement is not a bad judgement\nassert!(Freshness::Stale.history() && Freshness::Invalid.history());\nassert!(!Freshness::Unknown.history(), \"undated is not old\");\nassert!(!Freshness::Fresh.history() && !Freshness::Aging.history());\n```",
"oneOf": [
{
"const": "fresh",
"description": "Inside `session.freshness.fresh_minutes`. Current; act on it.",
"type": "string"
},
{
"const": "aging",
"description": "Between the two thresholds. Still current, but its age is worth stating.",
"type": "string"
},
{
"const": "stale",
"description": "At or beyond `session.freshness.stale_minutes`. History, never current.",
"type": "string"
},
{
"const": "unknown",
"description": "Nothing to judge it by: no timestamp, or no thresholds declared.",
"type": "string"
},
{
"const": "invalid",
"description": "A timestamp that does not parse, or one in the future.",
"type": "string"
}
]
},
"KnowledgeCandidate": {
"description": "One candidate record awaiting review: what a reader needs to decide whether to open it.\n\n```\nuse majordomus_cli::capability::builtin::knowledge_base::KnowledgeCandidate;\nlet c: KnowledgeCandidate = serde_json::from_str(r#\"{\n \"id\": \"e1-0123456789ab\", \"uri\": \"majordomus://knowledge/e1-0123456789ab\",\n \"path\": \".ai/repo/knowledge/candidates/e1-0123456789ab.md\", \"class\": \"convention\",\n \"status\": \"candidate\", \"epistemics\": \"decided\", \"title\": \"Tests run in disposable repositories\",\n \"date\": \"2026-09-12\", \"derived_from\": [\"session:e1\"], \"episode\": \"e1\",\n \"freshness\": \"unknown\", \"freshness_reason\": \"no timestamp\", \"age_source\": \"date\"\n}\"#).unwrap();\nassert_eq!(c.episode, \"e1\");\nassert_eq!(c.branch, None, \"an episode this checkout never saw has no branch, and says so\");\n```",
"properties": {
"about": {
"description": "What the observation it was derived from is about (ADR 0118); empty for a record\nderived from anything else.",
"type": "string"
},
"age_minutes": {
"description": "The wait in whole minutes, when it could be measured.",
"format": "int64",
"type": [
"integer",
"null"
]
},
"age_source": {
"$ref": "#/$defs/AgeSource",
"description": "Where the wait was read from."
},
"branch": {
"default": null,
"description": "The branch that episode ran on, joined to the tracked session record or, while that\nis not yet written, to the ledger's `session.started` line. `None` when this checkout\nknows nothing about the episode — named rather than hidden, so that a reader can tell\n\"not this branch\" from \"not known here\". Serialised as `null` in that case, never\nomitted.",
"type": [
"string",
"null"
]
},
"class": {
"description": "`fact`, `convention`, `constraint`, `memory` or `lesson`.",
"type": "string"
},
"date": {
"description": "The day of the evidence, `YYYY-MM-DD`.",
"type": "string"
},
"derived_from": {
"description": "The typed references the record names as its evidence, as declared.",
"items": {
"type": "string"
},
"type": "array"
},
"episode": {
"description": "The episode the record came from: the `session:` reference, or empty when it names none.",
"type": "string"
},
"epistemics": {
"description": "`observed`, `inferred` or `decided`.",
"type": "string"
},
"freshness": {
"$ref": "#/$defs/Freshness",
"description": "How long it has waited, judged against `session.freshness`."
},
"freshness_reason": {
"description": "Why it was judged that way, in one phrase. Never empty.",
"type": "string"
},
"id": {
"description": "The record id, which is also its file name.",
"type": "string"
},
"path": {
"description": "Repository-relative path.",
"type": "string"
},
"route": {
"description": "Which owner should look first, derived from `about`'s structure; empty without one.",
"type": "string"
},
"status": {
"description": "Always `candidate` here; carried so that a reader sees the same record shape as `record`.",
"type": "string"
},
"title": {
"description": "The assertion, in one line.",
"type": "string"
},
"uri": {
"description": "`majordomus://knowledge/<id>`.",
"type": "string"
}
},
"required": [
"id",
"uri",
"path",
"class",
"status",
"epistemics",
"title",
"date",
"freshness",
"freshness_reason",
"age_source"
],
"type": "object"
},
"KnowledgeGroup": {
"description": "The records under one subject: every candidate awaiting review and every rejected one,\nwith the episodes behind them (ADR 0118). Recurrence is read here, never written: each\nrecord stays one episode's own file, and a group is how several of them read as one thing.\n\n```\nuse majordomus_cli::capability::builtin::knowledge_base::KnowledgeGroup;\nlet g: KnowledgeGroup = serde_json::from_str(\n r#\"{\"about\":\"lib/a.sh\",\"route\":\"project\",\"candidates\":[\"e1-a\",\"e2-b\"],\"episodes\":[\"e1\",\"e2\"]}\"#,\n).unwrap();\nassert_eq!(g.episodes.len(), 2, \"two episodes observed it\");\nassert!(g.rejected.is_empty(), \"and nobody rejected it\");\n```",
"properties": {
"about": {
"description": "The subject, as written.",
"type": "string"
},
"candidates": {
"description": "The candidates awaiting review, by id.",
"items": {
"type": "string"
},
"type": "array"
},
"episodes": {
"description": "The episodes behind all of them, each once, in order.",
"items": {
"type": "string"
},
"type": "array"
},
"rejected": {
"description": "The records rejected and kept, by id.",
"items": {
"type": "string"
},
"type": "array"
},
"route": {
"description": "The route of its records.",
"type": "string"
}
},
"required": [
"about",
"route"
],
"type": "object"
}
},
"description": "The candidates awaiting review, against the policy's cap.\n\n```\nuse majordomus_cli::capability::builtin::knowledge_base::KnowledgeCandidates;\nlet empty: KnowledgeCandidates = serde_json::from_str(\n r#\"{\"total\":0,\"on_this_branch\":0,\"unattributed\":0,\"branch\":\"master\",\"candidates\":[],\"over_cap\":false}\"#,\n).unwrap();\nassert_eq!(empty.total, 0, \"an empty queue is an answer\");\nassert_eq!(empty.cap, None, \"and a policy without the key declares no cap\");\n```",
"properties": {
"branch": {
"description": "The branch this answer is about, or `DETACHED`.",
"type": "string"
},
"candidates": {
"description": "Every candidate, in canonical order of id.",
"items": {
"$ref": "#/$defs/KnowledgeCandidate"
},
"type": "array"
},
"cap": {
"description": "`knowledge.candidates_max_files`, when the policy declares it.",
"format": "uint",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"findings": {
"description": "What a reader should know before trusting the above: a malformed record that was\nskipped, a cap that was exceeded, a policy that declares none. Empty is the good case.",
"items": {
"type": "string"
},
"type": "array"
},
"groups": {
"description": "The candidates and rejected records derived from observations, grouped by what they\nare about, in order of subject.",
"items": {
"$ref": "#/$defs/KnowledgeGroup"
},
"type": "array"
},
"on_this_branch": {
"description": "How many of them came from an episode on this checkout's branch.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"over_cap": {
"description": "True when `total` exceeds `cap`. False when no cap is declared: nobody wrote one down.",
"type": "boolean"
},
"total": {
"description": "How many records carry `status: candidate` under the candidates class.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"unattributed": {
"description": "How many name an episode this checkout knows nothing about.",
"format": "uint",
"minimum": 0,
"type": "integer"
}
},
"required": [
"total",
"on_this_branch",
"unattributed",
"branch",
"over_cap"
],
"title": "KnowledgeCandidates",
"type": "object"
}Politiky
- benchmark
- povinné — cíl na každém transportu, který expozice deklaruje; případy jsou ty ze vstupního typu
- cache
- vypnuto — každé volání spustí handler
Cíle benchmarku
Odvozeno z registru pro tento repozitář: jeden požadavek na transport a případy, které poskytuje typ vstupu. Celá matice je na stránce měření výkonu.
Tvrzení implementovaná vedle ní
Připojeno souborem, který každé tvrzení implementuje; každé odkazuje na svou stránku s implementací a testem, který je dokazuje.