feat: #66 contested regions / frontlines — 12th ability (v0.44.0)
CI / build + unit + e2e (pull_request) Successful in 2m10s

A third region state (contested frontline): a region in no nation's territory and not in unowned, opened/resolved by the LLM, tied to an active war. Sole-ownership invariant preserved. Durable GameState.contested; contested-inert stub; map legend stays at 7.
This commit is contained in:
2026-10-16 15:21:45 +00:00
parent d946fdf0d7
commit 5477336537
27 changed files with 1743 additions and 80 deletions
+15 -3
View File
@@ -1,8 +1,8 @@
// The ordered LLM-ability registry.
//
// `ABILITIES` is the single source of truth for the 11 per-feature LLM abilities.
// `ABILITIES` is the single source of truth for the 12 per-feature LLM abilities.
// The engine iterates it in this order:
// takeovers → wars → hybrid → economy → industry → nuclear → leaders → ideology → disasters → migration → sea
// takeovers → wars → hybrid → economy → industry → nuclear → leaders → ideology → disasters → migration → sea → contested
// for (a) the system-prompt schema lines + constraint bullets, (b) the per-ability
// validate calls inside validateTurnResult, (c) the payload fields in buildUserPrompt,
// (d) the ordered apply block inside applyTurnResult, (e) the isMeaningful check,
@@ -25,10 +25,11 @@ import { ideology } from './ideology';
import { disasters } from './disasters';
import { migration } from './migration';
import { sea } from './sea';
import { contested } from './contested';
import type { Ability, AbilityField } from './types';
/**
* The 11 per-feature LLM abilities in their canonical apply order.
* The 12 per-feature LLM abilities in their canonical apply order.
* The order matters: it determines the order of the schema lines in the
* system prompt, the order of the validate calls, the order of the apply
* steps, and the order of the payload fields in the user prompt. New
@@ -47,6 +48,7 @@ export const ABILITIES: readonly Ability<AbilityField>[] = [
disasters,
migration,
sea,
contested,
];
// ── type re-exports ────────────────────────────────────────────────────────────
@@ -173,3 +175,13 @@ export {
isSeaZoneId,
seaZoneName,
} from './sea';
// ── contested (frontlines) ───────────────────────────────────────────────────
export {
validateContestedOps,
applyContested,
CONTESTED_FILL,
CONTESTED_STROKE,
contestedTooltipLabel,
} from './contested';