Implement the 005-set-initiative feature that adds initiative values to combatants with automatic descending sort and active turn preservation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
57
specs/005-set-initiative/contracts/domain-api.md
Normal file
57
specs/005-set-initiative/contracts/domain-api.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Domain API Contract: Set Initiative
|
||||
|
||||
## Function Signature
|
||||
|
||||
```
|
||||
setInitiative(encounter, combatantId, value) → Success | DomainError
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| encounter | Encounter | Current encounter state |
|
||||
| combatantId | CombatantId | Target combatant to update |
|
||||
| value | integer or undefined | New initiative value, or undefined to clear |
|
||||
|
||||
### Success Result
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| encounter | Encounter | New encounter with updated combatant and reordered list |
|
||||
| events | DomainEvent[] | Array containing one `InitiativeSet` event |
|
||||
|
||||
### Error Codes
|
||||
|
||||
| Code | Condition |
|
||||
|------|-----------|
|
||||
| `combatant-not-found` | No combatant with the given id exists |
|
||||
| `invalid-initiative` | Value is defined but not an integer |
|
||||
|
||||
### Ordering Contract
|
||||
|
||||
After a successful call, `encounter.combatants` is sorted such that:
|
||||
1. All combatants with `initiative !== undefined` come before those with `initiative === undefined`
|
||||
2. Within the "has initiative" group: sorted descending by initiative value
|
||||
3. Within the "no initiative" group: original relative order preserved
|
||||
4. Equal initiative values: original relative order preserved (stable sort)
|
||||
|
||||
### Active Turn Contract
|
||||
|
||||
The combatant who was active before the call remains active after:
|
||||
- `encounter.activeIndex` points to the same combatant (by identity) in the new order
|
||||
- This holds even if the active combatant's own initiative changes
|
||||
|
||||
### Invariants Preserved
|
||||
|
||||
- INV-1: Empty encounters remain valid (0 combatants allowed)
|
||||
- INV-2: `activeIndex` remains in bounds after reorder
|
||||
- INV-3: `roundNumber` is never changed by `setInitiative`
|
||||
|
||||
## Use Case Signature
|
||||
|
||||
```
|
||||
setInitiativeUseCase(store, combatantId, value) → DomainEvent[] | DomainError
|
||||
```
|
||||
|
||||
Follows the standard use case pattern: get encounter from store, call domain function, save on success, return events or error.
|
||||
Reference in New Issue
Block a user