feat(beliefs): state what a score means; gated calibration; primary uncertainty

Every breakdown now carries its meaning: an uncalibrated epistemic score
derived from recorded evidence, not a probability of truth. Belief detail
adds a calibrated estimate read from the mind's resolved predictions when
at least twenty were decided in the score's range, and otherwise says why
none is shown; and names the primary uncertainty deterministically (no live
evidence, conflicting evidence, second-hand only, unclear reading, a single
source family, little evidence). The belief list heading becomes Score.
This commit is contained in:
Andy Dixon
2026-08-09 19:14:53 +01:00
parent 08a265f0fa
commit b661496128
8 changed files with 167 additions and 3 deletions
+10
View File
@@ -139,6 +139,10 @@ type BeliefDetail struct {
Events []events.Event `json:"events"`
Origin *events.Event `json:"origin,omitempty"`
Assertions []epistemics.Assertion `json:"assertions"` // who stated this proposition, with what stance
// Score semantics: the raw number, its empirical reading where prediction
// outcomes allow one, and the strongest deterministic reason to doubt it.
Calibration beliefs.Calibrated `json:"calibration"`
PrimaryUncertainty string `json:"primary_uncertainty"`
}
// BeliefDetail assembles the detail; shared with the UI.
@@ -164,6 +168,12 @@ func (s *Server) BeliefDetail(r *http.Request, mind, id ids.ID) (BeliefDetail, e
if d.Assertions == nil {
d.Assertions = []epistemics.Assertion{}
}
if s.deps.Predictions != nil {
d.Calibration = s.deps.Predictions.CalibratedScore(ctx, mind, b.Confidence)
} else {
d.Calibration = beliefs.CalibrateWith(b.Confidence, nil)
}
d.PrimaryUncertainty = beliefs.PrimaryUncertainty(d.Breakdown, d.Evidence)
d.Events, _ = s.deps.Events.DerivedFrom(ctx, "belief", string(id), 100)
if !b.OriginEvent.IsZero() {
if e, err := s.deps.Events.Get(ctx, b.OriginEvent); err == nil {