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:
@@ -137,7 +137,14 @@ func (VolitionHook) AfterCycle(ctx context.Context, c *brain.Cycle, emitted []ev
|
||||
}
|
||||
}
|
||||
}
|
||||
// Commitments in id order, so the events a cycle emits do not depend on
|
||||
// map iteration order.
|
||||
live := make([]volition.Commitment, 0, len(dctx.Commitments))
|
||||
for _, cm := range dctx.Commitments {
|
||||
live = append(live, cm)
|
||||
}
|
||||
sort.Slice(live, func(i, j int) bool { return live[i].ID < live[j].ID })
|
||||
for _, cm := range live {
|
||||
switch volition.Assess(cm, c.State.Now) {
|
||||
case volition.StateDue:
|
||||
if err := vs.MarkDue(ctx, r, cm); err != nil {
|
||||
@@ -159,10 +166,6 @@ func (VolitionHook) AfterCycle(ctx context.Context, c *brain.Cycle, emitted []ev
|
||||
}
|
||||
}
|
||||
}
|
||||
var live []volition.Commitment
|
||||
for _, cm := range dctx.Commitments {
|
||||
live = append(live, cm)
|
||||
}
|
||||
for _, cf := range volition.CommitmentConflicts(live, c.State.Now) {
|
||||
key := pairKey(cf.A.ID, cf.B.ID)
|
||||
if recentlyRaised(ctx, c, events.CommitmentConflict, "pair", key) {
|
||||
|
||||
Reference in New Issue
Block a user