test(agency): the Part L incident scenario end to end, and failure modes

The full incident scenario now runs against the assembled daemon: an
operator goal becomes a want to reduce uncertainty, an investigation
intention and a diagnosis plan; telemetry is read; logs need authority,
so a scoped request with risk, mitigation and fallback is raised and the
intention is blocked until an operator grants it; the logs are read with
personal data masked and summarised back into cognition; the operator
supplies the judgement that a restart should help; a standing commitment
turns the restart into a request for approval; after approval the typed
capability runs and health is verified rather than assumed; the fault
persists, so a prediction error weakens the supporting belief, the plan
is replanned into an escalation that reuses the live log grant and does
not repeat the restart; once the database is fixed a second approved
restart verifies, the procedure is learnt, and "Why did you restart
atlas-worker?" is answered from the recorded chain and scores as
supported.

Changes the scenario exposed:
- New operator goals are raised by the goal monitor, so a cycle runs and
  wants are derived from them.
- Intentions link live beliefs about their action's target, so a failed
  expectation is evidence against the belief it rested on and the plan
  lists it as an assumption.
- Reconsideration reacts to a plan's own intention only; a subordinate
  "obtain approval" intention shares the plan and previously caused the
  parent's plan to be closed.
- The harness accepts a clock for the executor's verification windows.

Further failure-mode tests: a retracted assumption replans a waiting plan
away from the restart and withdraws its approval request; conflicting
commitments are raised once in a cycle while both stay represented.
This commit is contained in:
Andy Dixon
2026-09-27 23:34:43 +01:00
parent 212eef6b8c
commit 7d67745ff8
6 changed files with 359 additions and 3 deletions
+15
View File
@@ -44,6 +44,21 @@ func (g GoalMonitor) Observe(ctx context.Context, s *brain.State) ([]brain.Candi
Features: attention.Features{Salience: 0.4, GoalRelevance: gl.Priority, Consequence: 0.5 * gl.Priority, Urgency: 0.3, Confidence: 1}, Confidence: 1,
Evidence: []events.EvidenceRef{{Kind: "goal", ID: string(gl.ID)}}})
}
// A goal an operator just set deserves attention of its own.
for _, ev := range s.NewEvents {
if ev.Type != events.GoalCreated || ev.Source != "operator" {
continue
}
gid, _ := ev.Metadata["goal_id"].(string)
for _, gl := range s.Goals {
if string(gl.ID) == gid {
out = append(out, brain.Candidate{Kind: "goal", Subject: string(gl.ID) + ":new", Summary: "new goal from an operator: " + gl.Title,
Content: map[string]any{"goal_id": gid, "reason": "set by an operator", "ref": gid, "source_event": string(ev.ID)},
Features: attention.Features{Salience: 0.7, GoalRelevance: gl.Priority, Consequence: 0.6, Urgency: 0.5, Confidence: 1, OperatorPriority: 1}, Confidence: 1,
SourceEvents: []ids.ID{ev.ID}, Evidence: []events.EvidenceRef{{Kind: "goal", ID: gid}, {Kind: "event", ID: string(ev.ID)}}})
}
}
}
// New external events touching a goal's subject.
for _, ev := range s.NewEvents {
if strings.HasPrefix(ev.Source, "brain") || ev.Type != events.Observation {