Pierre questioned the current selected-action memory after #12: an individual may report selected Move despite remaining in place. This issue records a proposed next model decision. The rules below are not approved or implemented. The presentation-only work in #13 can continue independently.
Problem and proposed contract
The current last_action explicitly records the last selected action, not an accepted event. That is useful attempt history, but it should not be the only representation of what the individual did. Spatial choice also currently includes start-occupied destinations, producing avoidable failed attempts.
Proposed next increment:
- Read the unchanged starting neighbourhood and identify empty destinations. Keep the existing Copy tendency scaling by the fraction of empty neighbours. Move and Copy, if selected, target uniformly among the start-empty neighbours.
- When there are no empty neighbours, transfer the unavailable Move share to Wait (Copy is already transferred to Wait by the existing crowding rule). Keep the total action weight unchanged. This fallback is part of the proposed rule, not a hidden resampling loop.
- Resolve all claims synchronously as today: a start-empty cell with exactly one affordable claim succeeds; competing Move/Copy claims all fail. No retries, priority winner or entry into same-tick vacated cells.
- Commit the individual's executed state from the resolution: accepted Move → Move; accepted Copy → Copy; Repair → Repair; Wait or a blocked attempt → Wait. Keep the attempted action and its outcome separately, so a blocked Move is distinguishable from a chosen Wait. Initially/newborn: no prior attempt/outcome; newborns first act next tick.
- Retain existing upkeep and attempted action wear initially, including a contested attempt that fails. No available destination means the individual actually chooses Wait and pays only upkeep. Failure to survive upkeep/wear follows the existing removal rule. Pierre can choose a different cost for conflict, but it must be explicit.
A compact outcome record could distinguish applied, blocked-by-occupancy and blocked-by-conflict, alongside the attempted action. The guarded autonomous chooser normally avoids occupied targets; the generic transition engine still needs defined results for manually supplied invalid-for-success targets. Keep ordinary structs/enums and the existing shared decision/resolution boundary. A future policy can read the outcome without adding a separate Blocked state for every possible attempted action.
Worked examples
- Seven occupied neighbours and one empty neighbour: selecting Move targets the single empty square. With one claim and enough integrity, the individual moves and its executed state is Move.
- Two individuals choose the same start-empty square: both pay the existing attempted wear, neither moves, both have executed state Wait and last outcome blocked-by-conflict for an attempted Move. An attempted Copy can participate in the same conflict.
- Eight occupied neighbours: spatial tendencies transfer to Wait; no destination draw or attempted spatial wear. Ordinary Wait/Repair choice remains possible according to the resulting weights.
- A neighbour fails upkeep this tick: its starting square still counts occupied. It becomes eligible on the following tick only.
Trade-offs and decision boundary
This prevents attempts at known occupied destinations and removes the ambiguity between intended and executed action. It does not guarantee every spatial attempt succeeds: independent synchronous decisions can still collide. Eliminating those collisions would require a different coordination/resolution rule, which is outside this proposal.
This changes destination probabilities, RNG draw bounds and wear frequency, so population trajectories will change. It is a new model protocol; retain existing v3 fixtures/evidence rather than silently rewriting earlier expected results. No property tuning, new resources, reaction-to-failure preferences or state-specific transition weights are included yet.
Before implementation, Pierre must choose this guarded-selection/outcome approach and whether contested attempts retain their current wear. After approval, turn this into one bounded model PR with exact worked-case tests, atomic rejection and newborn checks, grouping/identity/count invariants, observation independence, and explicit intent-versus-outcome browser/headless output. Do not mix it into the UI PR.
Pierre questioned the current selected-action memory after #12: an individual may report selected Move despite remaining in place. This issue records a proposed next model decision. The rules below are not approved or implemented. The presentation-only work in #13 can continue independently.
Problem and proposed contract
The current
last_actionexplicitly records the last selected action, not an accepted event. That is useful attempt history, but it should not be the only representation of what the individual did. Spatial choice also currently includes start-occupied destinations, producing avoidable failed attempts.Proposed next increment:
A compact outcome record could distinguish applied, blocked-by-occupancy and blocked-by-conflict, alongside the attempted action. The guarded autonomous chooser normally avoids occupied targets; the generic transition engine still needs defined results for manually supplied invalid-for-success targets. Keep ordinary structs/enums and the existing shared decision/resolution boundary. A future policy can read the outcome without adding a separate Blocked state for every possible attempted action.
Worked examples
Trade-offs and decision boundary
This prevents attempts at known occupied destinations and removes the ambiguity between intended and executed action. It does not guarantee every spatial attempt succeeds: independent synchronous decisions can still collide. Eliminating those collisions would require a different coordination/resolution rule, which is outside this proposal.
This changes destination probabilities, RNG draw bounds and wear frequency, so population trajectories will change. It is a new model protocol; retain existing v3 fixtures/evidence rather than silently rewriting earlier expected results. No property tuning, new resources, reaction-to-failure preferences or state-specific transition weights are included yet.
Before implementation, Pierre must choose this guarded-selection/outcome approach and whether contested attempts retain their current wear. After approval, turn this into one bounded model PR with exact worked-case tests, atomic rejection and newborn checks, grouping/identity/count invariants, observation independence, and explicit intent-versus-outcome browser/headless output. Do not mix it into the UI PR.