From perception to Explain this¶
designed · Phase 1 (#31, #35–#38, #41) · PLAN §7.2–§7.4.2, §7.7, §13.5
The path one decision takes, with the component that owns each step and what it leaves behind for Explain this.
tick N, Agency phase
┌──────────────────┐ perceived_entities, perceived_danger, perceived_warmth (attributes)
│ PerceptionSystem │──▶ knows edges: {food_value: {value, observed_at, provenance}} ─┐
└──────────────────┘ │ graph
┌──────────────────┐ hunger += PerTick(hunger_rate_per_day) │
│ HungerSystem │──▶ ─┘
└──────────────────┘
tick N+1, Agency phase (reads what the above wrote)
┌──────────────────┐ Option(actor, "move", target, Need:"safety", Score, Reason, Inputs{…})
│ BaselineOptions │──▶ Option(actor, "eat", bush, Need:"hunger", …) ──▶ ctx.Options (bus, transient)
└──────────────────┘ Option(actor, "fetch_water", bucket, Need:"safety", …)
┌──────────────────┐ per actor: × personality weight → argmax, StableHash tiebreak
│ DecisionSystem │──▶ SetAttribute(current_action, _target, _reason) ──▶ graph
└──────────────────┘ decision record {winner, runners-up[3], inputs, weights} ──▶ trace
tick N+2, Agency phase
┌──────────────────┐ move: RemoveEdge(contains old) + AddEdge(contains new)
│ ActionSystem │──▶ eat: Delta(hunger, −meal_value) + Delta(bush.food_value, −bite_size) ──▶ batch
└──────────────────┘ intents carry Inputs where a reader would ask why
┌──────────────────┐ sums deltas, priority for sets, one container per node, bounds
│ IntentResolver │──▶ intent_applied / intent_conflict events ──▶ graph + trace
└──────────────────┘
┌──────────────────┐ Explain(eventId): event → intent (ordinal) → source (system:Decision)
│ Causal trace │ → decision record → its Inputs (perceived_danger=0.8, caution=0.8)
└──────────────────┘ → WhyChanged(kira, perceived_danger, gen) → PerceptionSystem intent
→ its Inputs (inn.temperature=310) → WhyChanged(inn, temperature, gen)
→ FireSystem propagation → ignition intent → … → player:harness action
┌──────────────────┐
│ Viewer │──▶ "Kira left the square because the inn was burning and she is cautious.
└──────────────────┘ The inn caught fire because the smithy's heat crossed 250°. The smithy was set alight by you."
The contracts along the way¶
| Step | Owner | Writes | Reads | PLAN |
|---|---|---|---|---|
| Sense | PerceptionSystem | perceived_*, knows edges |
containment, permeability.light/sound, salient attributes |
§7.2, §7.3 |
| Need | HungerSystem | hunger |
hunger_rate_per_day |
§7.4.1 |
| Offer | BaselineOptions | options (bus) | perceived_*, hunger, energy, view.Facts/Known — never a target's live attributes |
§7.4.1, §7.4.2 |
| Choose | DecisionSystem | current_action*; decision record |
ctx.Options, personality_* |
§7.4.2, §7.6 |
| Do | ActionSystem | intents per §7.7 | current_action* |
§7.7 |
| Apply | Resolver | graph; events | batch | §18.1, §18.6 |
| Remember | Causal trace | records | applied intents, decisions, events | §13.5 |
| Tell | Viewer (Explain this) | prose | Explain, History |
§13.4 |
What makes the chain possible¶
Three small things, each cheap, each required: every event has an id and the ordinal of the intent that produced it; every decision record keeps the runners-up and the inputs; and intents may carry Inputs — the snapshot values they were computed from — so that a physics link ("the inn caught fire because…") has a next hop. A system that omits Inputs ends the chain at itself, which is acceptable but shallower.
See also¶
The tick · Option bus · Causal trace · Player: Explain this