fix(cognition): decisions and cycle output no longer depend on map order
Formation summed its terms by ranging over a map, so the score could differ in the last bit between runs of the same state; the volition hook assessed commitments, metacognition raised repeated-failure candidates and the forensic explanation listed commitments in map iteration order, so the events a cycle emits and an explanation's order varied between runs. Each now iterates in sorted order, as replay determinism (PLAN §1 R3) requires.
This commit is contained in:
@@ -688,9 +688,16 @@ func Form(in FormationInput) Formation {
|
||||
case w.CommitmentID != "":
|
||||
f.Kind = IntentFulfilCommitment
|
||||
}
|
||||
// Summed in key order: floating-point addition is not associative, and a
|
||||
// decision must not depend on map iteration order.
|
||||
keys := make([]string, 0, len(t))
|
||||
for k := range t {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
score := 0.0
|
||||
for _, v := range t {
|
||||
score += v
|
||||
for _, k := range keys {
|
||||
score += t[k]
|
||||
}
|
||||
f.Score = round3(score)
|
||||
t["score"] = f.Score
|
||||
|
||||
Reference in New Issue
Block a user