pub struct Candidate {
pub uri: String,
pub kind: String,
pub title: Option<String>,
pub tier: Tier,
pub relevance: f64,
pub depth: usize,
pub discovered_by: Vec<Discovery>,
pub object: Option<usize>,
pub path: Option<String>,
pub status: Option<String>,
pub facts: BTreeMap<String, String>,
}Expand description
One thing the compiler reached, before any budget was spent on it. The compiler folds
every path that reached the same identifier into one of these, which is where
deduplication happens: the Candidate is the unit, and discovered_by is the
evidence of how many ways there were to find it.
The three scalar fields are folded rather than overwritten as paths arrive, and each
keeps the best value any path gave: the highest relevance, the shortest depth, and
the strongest tier. Strongest means lowest, because Tier is ordered by authority —
so a thing reached once as a seed and again three hops out along a weak edge is still a
Task-tier entry at relevance 1 and depth 0. Nothing a later path says can demote it.
object and path are the two ways a candidate can have a body: object indexes into
the index’s own objects, and path names a file the layer pointed at without indexing.
Both can be absent, for something the layer names and this repository does not hold.
use std::collections::BTreeMap;
use majordomus_cli::devcontext::select::Candidate;
use majordomus_cli::devcontext::{Discovery, Selector, Tier};
let way = |selector: Selector, depth: usize, confidence: f64| Discovery {
selector,
reason: "for the sake of the example".into(),
via: None,
edge: None,
depth,
confidence,
weight: 1.0,
};
// one thing, found twice: named in the request, and again by matching the intent
let c = Candidate {
uri: "majordomus://adr/0052".into(),
kind: "adr".into(),
title: Some("The episode is the boundary".into()),
tier: Tier::Task,
relevance: 1.0,
depth: 0,
discovered_by: vec![
way(Selector::Seed, 0, 1.0),
way(Selector::IntentMatch, 2, 0.4),
],
object: None,
path: None,
status: None,
facts: BTreeMap::new(),
};
// two recorded paths is the fact worth keeping, not something to hide
assert_eq!(c.discovered_by.len(), 2);
// and the entry is trusted as far as its *best* path, not averaged down by its worst
assert_eq!(c.confidence(), 1.0);Fields§
§uri: StringThe canonical identifier.
kind: StringThe kind, as the layer declared it.
title: Option<String>The title, when there is one.
tier: TierThe tier its cost comes out of.
relevance: f64The best relevance any path gave it.
depth: usizeThe shortest depth any path reached it at.
discovered_by: Vec<Discovery>Every path that reached it.
object: Option<usize>The object, when the index holds one under this identifier.
path: Option<String>The file the thing lives in, when it is not an object of the index.
status: Option<String>The status word the object declares.
facts: BTreeMap<String, String>Facts worth carrying.
Implementations§
Source§impl Candidate
impl Candidate
Sourcepub fn confidence(&self) -> f64
pub fn confidence(&self) -> f64
The confidence of the most trusted path that reached it: the maximum, not the mean.
Averaging would be wrong in a way that matters. Confidence here is about the provenance of the selection — 1.0 when the repository declared the path, less when the compiler inferred it from words — and a thing the layer explicitly declares does not become less certain because a weaker guess also found it. Finding more ways to something can only raise this number.
A candidate with no recorded path is 0.0 rather than an error, which is also right: nothing vouches for it.
use std::collections::BTreeMap;
use majordomus_cli::devcontext::select::Candidate;
use majordomus_cli::devcontext::{Discovery, Selector, Tier};
let mut c = Candidate {
uri: "majordomus://rule/project.x@1".into(),
kind: "rule".into(),
title: None,
tier: Tier::Governance,
relevance: 0.6,
depth: 1,
discovered_by: Vec::new(),
object: None,
path: None,
status: None,
facts: BTreeMap::new(),
};
// nothing vouches for it yet
assert_eq!(c.confidence(), 0.0);
// an inferred path: the words of the intent occurred in its own words
c.discovered_by.push(Discovery {
selector: Selector::IntentMatch,
reason: "the intent's words occur in it".into(),
via: None,
edge: None,
depth: 1,
confidence: 0.4,
weight: 0.5,
});
assert_eq!(c.confidence(), 0.4);
// and then a declared one, which the guess cannot dilute
c.discovered_by.push(Discovery {
selector: Selector::Governance,
reason: "a rule the layer applies to everything".into(),
via: None,
edge: None,
depth: 0,
confidence: 1.0,
weight: 1.0,
});
assert_eq!(c.confidence(), 1.0, "the best path decides, never the average");