feat(#61): named leaders — assassination / death / appointment with succession (v0.38.0)
CI / build + unit + e2e (pull_request) Successful in 2m33s
CI / build + unit + e2e (pull_request) Successful in 2m33s
Per-nation named leaders (Nation.leader) and a required TurnResult.leaders
lever ({ changes: [{ target, name, cause }] }). Each change sets the target
nation's leader and applies a deterministic stability dip by cause
(assassination -15, death -3, appointed 0) mirrored to its regions and
re-derived into its stats, plus a narration event (military for an
assassination, political for a death/appointment). An assassination/death
requires the target to already have a leader (a leaderless target is
dropped); an appointment always creates/sets one. Unknown/ambiguous targets
are dropped, never thrown.
- shared/types.ts: optional Nation.leader
- shared/protocol.ts: LeaderCause/LeaderChange/LeaderOps, LEADER_STABILITY_EFFECT,
TurnResult.leaders (required, between nuclear and markers), leader in nationForPrompt
- server/engine.ts: validateLeaderOps, applyLeaderChange, the applyTurnResult
leader block (after nuclear, before markers), isMeaningful, system-prompt
contract + constraint, validateTurnResult + runTurn fallback
- server/stub.ts: leaders always { changes: [] } (e2e unaffected)
- tests: 15 engine.test.ts leader tests + 2 db.test.ts round-trips
- version 0.37.0 -> 0.38.0, CHANGELOG entry
This commit is contained in:
+10
-1
@@ -16,9 +16,17 @@ export interface StubPayload {
|
||||
// `nuclear` (v0.37.0, #60) is the per-nation nuclear capability stamped by
|
||||
// the engine (its `nuclear` flag OR a `rocket` marker); the stub ignores
|
||||
// it — it never arms or strikes (see deterministicTurn).
|
||||
// `leader` (v0.38.0, #61) is the per-nation named leader stamped by the
|
||||
// engine; the stub ignores it — it never changes a leader (see
|
||||
// deterministicTurn).
|
||||
nations: Record<
|
||||
string,
|
||||
{ stats: Record<string, number>; territory?: string[]; nuclear?: boolean }
|
||||
{
|
||||
stats: Record<string, number>;
|
||||
territory?: string[];
|
||||
nuclear?: boolean;
|
||||
leader?: { name: string };
|
||||
}
|
||||
>;
|
||||
};
|
||||
/** The raw pending round the engine emitted (one entry per queued item). */
|
||||
@@ -224,6 +232,7 @@ export function deterministicTurn(p: StubPayload): TurnResult {
|
||||
economy: { trade: [], embargo: [] }, // the stub never touches trades/embargoes (see doc comment)
|
||||
industry: { projects: [] }, // the stub never declares industry projects (see doc comment)
|
||||
nuclear: { arm: [], strikes: [] }, // the stub never arms or strikes (see doc comment)
|
||||
leaders: { changes: [] }, // the stub never changes leaders (see doc comment)
|
||||
markers: { add: [], remove: [] }, // the stub never touches markers (see doc comment)
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user