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:
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"github.com/andydixon/noema/internal/beliefs"
|
||||
"github.com/andydixon/noema/internal/storage"
|
||||
"github.com/andydixon/noema/pkg/events"
|
||||
"github.com/andydixon/noema/pkg/ids"
|
||||
@@ -454,3 +455,18 @@ func (s *Store) Stats(ctx context.Context, mind ids.ID) (map[string]int64, error
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// CalibratedScore reads a belief score against this mind's whole prediction
|
||||
// history. It is the only empirical calibration Noema offers, and it says
|
||||
// so when the sample is too small.
|
||||
func (s *Store) CalibratedScore(ctx context.Context, mind ids.ID, score float64) beliefs.Calibrated {
|
||||
c, err := s.Calibrate(ctx, mind, time.Time{})
|
||||
if err != nil {
|
||||
return beliefs.CalibrateWith(score, nil)
|
||||
}
|
||||
var buckets []beliefs.CalibrationBucket
|
||||
for _, b := range c.Buckets {
|
||||
buckets = append(buckets, beliefs.CalibrationBucket{Low: b.Low, High: b.High, Decided: b.Count, HitRate: b.HitRate})
|
||||
}
|
||||
return beliefs.CalibrateWith(score, buckets)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user