Coverage Summary for Class: BoardStatusModel (core.pipeline)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| BoardStatusModel |
100%
(1/1)
|
66.7%
(2/3)
|
55%
(11/20)
|
66.7%
(12/18)
|
62.8%
(93/148)
|
// FILE: core/src/main/kotlin/core/pipeline/BoardStatusModel.kt
package core.pipeline
import core.primitives.ActiveStatus
import core.primitives.BoardStatus
import core.primitives.ContractId
import core.state.ActiveContract
import core.state.BoardContract
/**
* Board status decision model.
*
* ## Semantic Ownership
* Answers: **Why board status changed to COMPLETED?**
*
* ## Stability Gradient
* STABLE: Pure decision logic with explicit rules.
*
* ## Determinism
* - No RNG usage. All inputs are explicit.
*
* ## Boundary Rules
* - Must NOT emit events.
* - Must NOT mutate state directly.
*/
object BoardStatusModel {
/**
* Determines if a board contract should be marked COMPLETED.
*
* A board becomes COMPLETED when all associated active contracts are CLOSED.
*
* @param boardContract The board contract to evaluate.
* @param activeContracts Current active contracts (after updates).
* @return [BoardStatusDecision] with result.
*/
fun shouldComplete(
boardContract: BoardContract?,
activeContracts: List<ActiveContract>
): BoardStatusDecision {
if (boardContract == null || boardContract.status != BoardStatus.LOCKED) {
return BoardStatusDecision(shouldComplete = false)
}
val hasNonClosedActives = activeContracts.any {
it.boardContractId == boardContract.id && it.status != ActiveStatus.CLOSED
}
return BoardStatusDecision(shouldComplete = !hasNonClosedActives)
}
/**
* Updates board list, marking the specified board as COMPLETED if applicable.
*
* @param boards Current board contracts.
* @param boardIdToComplete ID of board to potentially complete.
* @param activeContracts Current active contracts (for completion check).
* @return Updated board list.
*/
fun updateBoardStatus(
boards: List<BoardContract>,
boardIdToComplete: ContractId?,
activeContracts: List<ActiveContract>
): List<BoardContract> {
if (boardIdToComplete == null) return boards
val boardContract = boards.firstOrNull { it.id == boardIdToComplete }
val decision = shouldComplete(boardContract, activeContracts)
if (!decision.shouldComplete) return boards
return boards.map {
if (it.id == boardIdToComplete) it.copy(status = BoardStatus.COMPLETED) else it
}
}
/**
* Terminal completion helper: complete a single board contract and extract an archived snapshot.
*
* ## When to use this
* Use this function only when the board contract is **done forever** from a gameplay perspective:
* - auto-close on SUCCESS / FAIL / DEATH
* - final manual close (player `CloseReturn`) after a RETURN_READY contract
*
* In these cases the contract should no longer appear on the board, but we still want to retain
* a completed snapshot for audit/debug/replay.
*
* ## When NOT to use this
* Do **not** use this for in-place status transitions where the board entry must remain present.
* For example:
* - OPEN → LOCKED (taken)
* - LOCKED → OPEN (future feature: unlock)
*
* For those transitions use [updateBoardStatus] (or other status-only helpers) because they do not
* remove contracts from the board and do not create archive snapshots.
*
* ## State effects (pure / no mutation)
* This function is pure and returns values that the caller should apply to state:
* - the completed contract is removed from the returned `boards` list
* - a completed snapshot (status=COMPLETED) is returned in a separate list for appending to
* `ContractState.archive`
*
* ## Determinism contract
* - No RNG draws.
* - No time / wall-clock.
* - Result depends only on input arguments.
*
* @param boards Current board contracts.
* @param boardIdToComplete ID of board to potentially complete.
* @param activeContracts Current active contracts (for completion check).
*
* ## Return value semantics
* @return Pair(remainingBoards, archivedBoards)
* - `remainingBoards`: the input [boards] with [boardIdToComplete] removed (if completion occurred)
* - `archivedBoards`: empty if no completion occurred, otherwise a single-element list containing a
* snapshot of the completed board contract (status=COMPLETED)
*
* The snapshot is returned directly (instead of requiring callers to re-query) because the board
* entry will be removed as part of the same transition.
*/
fun completeBoardAndExtract(
boards: List<BoardContract>,
boardIdToComplete: ContractId?,
activeContracts: List<ActiveContract>
): Pair<List<BoardContract>, List<BoardContract>> {
if (boardIdToComplete == null) return Pair(boards, emptyList())
val boardContract = boards.firstOrNull { it.id == boardIdToComplete }
val decision = shouldComplete(boardContract, activeContracts)
if (!decision.shouldComplete || boardContract == null) return Pair(boards, emptyList())
// Mark completed and export to archive
val completed = boardContract.copy(status = BoardStatus.COMPLETED)
val remaining = boards.filter { it.id != boardIdToComplete }
return Pair(remaining, listOf(completed))
}
}
/**
* Result of board status check.
*/
data class BoardStatusDecision(
/** Whether the board should be marked COMPLETED. */
val shouldComplete: Boolean
)