═══════════════════════════════════════════════════════════════════════════════
KINGDOM STATEMENT RULESET v2.0
═══════════════════════════════════════════════════════════════════════════════

PURPOSE
───────
This ruleset governs how to write and structure every kingdom political statement
record so the parser never outputs "[No response]", "None", or mismatched
actions/targets.

A "statement record" is the single JSON object saved into diplomatic_statements.json.


═══════════════════════════════════════════════════════════════════════════════
CORE OUTPUT REQUIREMENTS
═══════════════════════════════════════════════════════════════════════════════

✓ ALWAYS OUTPUT A VALID STATEMENT RECORD
    - Never time out
    - Never output "[No response]"
    - Never omit statement_text

✓ ALWAYS KEEP FIELDS CONSISTENT
    - action MUST match actions[0] (the primary action)
    - statement_text MUST match the action(s)
    - target_kingdom_id / target_kingdom_ids MUST match the action(s)

✓ USE SNAKE_CASE ACTION NAMES ONLY (NO CAMELCASE)


═══════════════════════════════════════════════════════════════════════════════
ALLOWED ACTIONS (SNAKE_CASE ONLY)
═══════════════════════════════════════════════════════════════════════════════

DIPLOMATIC:
    - none
    - declare_war
    - propose_peace
    - accept_peace
    - reject_peace
    - propose_alliance
    - accept_alliance
    - reject_alliance
    - propose_trade_agreement
    - accept_trade_agreement
    - reject_trade_agreement
    - demand_tribute
    - reject_tribute
    - demand_reparations
    - reject_reparations

VALIDATION: Action must exist in this list. No abbreviations or variations allowed.


═══════════════════════════════════════════════════════════════════════════════
FIELD RULES (STRICT)
═══════════════════════════════════════════════════════════════════════════════

A) kingdom_id
     ─────────
     REQUIRED. Type: string
     Must be the speaker's kingdom id exactly (ex: "new_kingdom", "volantis",
     "bravos", etc).
     
     VALIDATION: Must match a known kingdom in the game state.

B) statement_text
     ───────────────
     REQUIRED. Type: string
     Must be the actual public message.
     Must NOT contradict the action(s).

     EXAMPLES (DO NOT DO):
     ✗ Action: reject_alliance → statement: "we accept your alliance"
     ✗ Action: accept_trade_agreement → statement: "we reject trade"

     If prompt includes character/length cap: stay under it.
     VALIDATION: Proofread for contradictions. Run against action mapping table.

C) action + actions
     ────────────────
     action: REQUIRED string, MUST be snake_case from allowed list.
     actions: REQUIRED list of strings, each snake_case from allowed list.

     MAPPING RULES:
     ✓ actions[0] is the PRIMARY action
     ✓ action MUST EQUAL actions[0]
     ✓ No duplicates in actions (no repeated "propose_peace", etc)
     ✓ actions must NEVER be null or empty
     
     VALIDATION: len(actions) >= 1, action in actions, action == actions[0]

D) target_kingdom_id + target_kingdom_ids
     ──────────────────────────────────────
     Three scenarios:

     SCENARIO 1: Single action, single target
     ├─ target_kingdom_id: set to that kingdom id
     └─ target_kingdom_ids: set to [that same kingdom id]

     SCENARIO 2: Multiple actions OR multiple targets
     ├─ target_kingdom_id: MUST be null
     ├─ target_kingdom_ids: list every target exactly once, SAME ORDER as actions
     └─ CONSTRAINT: len(actions) == len(target_kingdom_ids)
                                    Each action maps 1:1 to target at same index

     SCENARIO 3: Action is "none" (announcement only)
     ├─ target_kingdom_id: MUST be null
     └─ target_kingdom_ids: MUST be []

     VALIDATION: Check array lengths match. Verify no target appears without action.

E) target_clan_id
     ───────────────
     OPTIONAL. Type: string or null
     Use only when statement is explicitly directed at a specific clan (rare).
     Otherwise null.
     
     VALIDATION: If set, must match a known clan id.

F) reason
     ───────
     REQUIRED. Type: string
     Short, factual explanation of why statement was made.
     Do not roleplay here—be analytical.
     
     VALIDATION: Must reference actionable political/economic factors.


═══════════════════════════════════════════════════════════════════════════════
CONTENT-TO-ACTION MAPPING TABLE
═══════════════════════════════════════════════════════════════════════════════

WAR
───
declare_war
    ✓ MUST: Explicitly state war is declared
    ✓ MAY: Include casus belli or justification
    ✗ MUST NOT: Propose terms (use propose_peace for that)

propose_peace
    ✓ MUST: Explicitly propose peace
    ✓ MAY: Include optional terms (duration, reparations, territory)
    ✗ MUST NOT: Demand without mutual framing

accept_peace
    ✓ MUST: Explicitly accept peace already offered
    ✗ MUST NOT: Imply this peace is rejected elsewhere

reject_peace
    ✓ MUST: Explicitly reject peace
    ✓ MAY: Explain reasons for rejection


ALLIANCES
─────────
propose_alliance
    ✓ MUST: Explicitly propose alliance (military pact / mutual defense)
    ✓ MAY: Include duration or specific trigger conditions
    ✗ MUST NOT: Frame as trade or tribute

accept_alliance
    ✓ MUST: Explicitly accept alliance
    ✗ MUST NOT: Reframe terms unilaterally

reject_alliance
    ✓ MUST: Explicitly decline alliance
    ✓ MAY: Explain reasons


TRADE
─────
propose_trade_agreement
    ✓ MUST: Explicitly propose trade deal
    ✓ MAY: Include duration if relevant
    ✗ MUST NOT: Demand payment (use demand_tribute/reparations for that)

accept_trade_agreement
    ✓ MUST: Explicitly accept trade deal
    ✗ MUST NOT: Change terms unilaterally

reject_trade_agreement
    ✓ MUST: Explicitly decline trade deal
    ✓ MAY: Explain reasons


TRIBUTE / REPARATIONS (KEEP THEM DISTINCT)
────────────────────────────────────────────
demand_tribute
    ✓ MUST: Demand ongoing payment as submission / coercion
    ✓ MUST: Include amount, frequency, duration in statement_text
    ✗ MUST NOT: Frame as compensation (use demand_reparations for that)

demand_reparations
    ✓ MUST: Demand payment framed as compensation for damages/wrongdoing
    ✓ MUST: Include amount, frequency, duration in statement_text
    ✗ MUST NOT: Frame as dominance (use demand_tribute for that)

reject_tribute
    ✓ MUST: Explicitly refuse tribute demand
    ✗ MUST NOT: Offer counter-tribute

reject_reparations
    ✓ MUST: Explicitly refuse reparations demand
    ✗ MUST NOT: Offer counter-payment


═══════════════════════════════════════════════════════════════════════════════
PAYMENT TERM RULES (WHEN DEMAND_TRIBUTE OR DEMAND_REPARATIONS)
═══════════════════════════════════════════════════════════════════════════════

If demanding payment, statement_text MUST INCLUDE ALL THREE:

    1. AMOUNT (number) — e.g., "500 gold"
    2. FREQUENCY (temporal unit) — e.g., "per day", "per month", "lump sum"
    3. DURATION (time limit) — e.g., "for 30 days", "indefinitely", "until peace"

EXAMPLES:
    ✓ "Pay 100 gold per day for 60 days"
    ✓ "500 gold lump sum as reparations"
    ✗ "Pay tribute" (missing amount, frequency, duration)

The record's reason field should reflect the same terms analytically.
VALIDATION: Regex check for amount + frequency + duration pattern.


═══════════════════════════════════════════════════════════════════════════════
MULTI-TARGET / MULTI-ACTION RULES
═══════════════════════════════════════════════════════════════════════════════

SCENARIO: You need to address multiple kingdoms with different intents.
EXAMPLE: accept_trade_agreement with Volantis, demand_tribute from Sarnor,
                 accept_trade_agreement with Reach

BEST PRACTICE → OPTION A (PREFERRED)
    Create SEPARATE statement records (one per target/action pair).
    This avoids confusion and ensures 1:1 clarity.

FALLBACK → OPTION B (ONLY IF SYSTEM REQUIRES ONE RECORD)
    Use actions + target_kingdom_ids with 1:1 mapping.
    Clearly segment statement_text: "To X: … To Y: …"
    Each "To" block must address only its corresponding action.

DO NOT:
    ✗ Set action="accept_trade_agreement" and also threaten destruction
        in the same "To X" block unless there is also a separate mapped
        demand/war action for that threatened kingdom.

    ✗ Mix peaceful proposals with war demands in a way that breaks 1:1 mapping.

VALIDATION: If len(actions) > 1, verify each action has a distinct target and
that statement_text clearly delineates "To X:" and "To Y:" sections.


═══════════════════════════════════════════════════════════════════════════════
ANTI-HALLUCINATION / ANTI-MISMATCH RULES
═══════════════════════════════════════════════════════════════════════════════

CONSTRAINT 1: No Unaddressed Targets in statement_text
    ✗ DO NOT mention a kingdom in statement_text as recipient if it is not
        in target_kingdom_ids.

CONSTRAINT 2: No Invisible Targets in target_kingdom_ids
    ✗ DO NOT set target_kingdom_ids to include a kingdom that is not
        addressed in statement_text.

CONSTRAINT 3: No Phantom Offers
    ✗ DO NOT claim acceptance/rejection of an offer unless that offer
        exists in the current event context.

CONSTRAINT 4: No Contradictory Claims
    ✗ DO NOT state "we accept peace" in one sentence and "we continue war"
        in another without clear action mapping.

VALIDATION: Three-way check:
    1. Every kingdom in target_kingdom_ids appears in statement_text
    2. Every kingdom in statement_text appears in target_kingdom_ids
    3. Every action/object pair in statement_text is defined in event context


═══════════════════════════════════════════════════════════════════════════════
DEFAULTS (TO PREVENT NULL/EMPTY BREAKAGE)
═══════════════════════════════════════════════════════════════════════════════

If no action is applicable:
    ├─ action = "none"
    ├─ actions = ["none"]
    ├─ target_kingdom_id = null
    ├─ target_kingdom_ids = []
    └─ statement_text = announcement / internal memo / status update

CONSTRAINT: actions must NEVER be null.
VALIDATION: Fallback to "none" action if stuck.


═══════════════════════════════════════════════════════════════════════════════
FORMATTING SAFETY
═══════════════════════════════════════════════════════════════════════════════

✓ Plain text only. No markdown.
✓ Avoid special formatting that could be stripped.
✓ Use UTF-8 standard characters.
✓ If RP items are ever included in kingdom statements, write with spaces
    around asterisks: * item * (but generally avoid RP items in kingdom
    statements unless explicitly requested).

VALIDATION: JSON must parse cleanly. No escape issues.


═══════════════════════════════════════════════════════════════════════════════
QUALITY CHECKLIST (PRE-SUBMISSION)
═══════════════════════════════════════════════════════════════════════════════

Before outputting a statement record, verify:

    ☐ action is in allowed actions list (snake_case)
    ☐ action == actions[0]
    ☐ statement_text exists and is not empty
    ☐ kingdom_id matches the speaker
    ☐ target_kingdom_ids length matches actions length
    ☐ Each kingdom in target_kingdom_ids appears in statement_text
    ☐ Each kingdom in statement_text is in target_kingdom_ids
    ☐ If demand_tribute or demand_reparations: amount + frequency + duration present
    ☐ No contradictions between action and statement_text
    ☐ reason field explains the political/economic motivation
    ☐ JSON parses without error
    ☐ No "[No response]" or "None" in output

═══════════════════════════════════════════════════════════════════════════════
END OF RULESET v2.0
═══════════════════════════════════════════════════════════════════════════════
