Skip to content

feat(dynasty): add legitimacy signal from chronicle events - #35

Merged
csheldrick merged 1 commit into
mainfrom
claude/dynasty-legitimacy-signal-4f5jqs
Jun 25, 2026
Merged

csheldrick merged 1 commit into
mainfrom
claude/dynasty-legitimacy-signal-4f5jqs

Conversation

@csheldrick

Copy link
Copy Markdown
Owner

Summary

  • Adds dynastyLegitimacy(state, dynastyId) — a [-1, 1] score derived from a dynasty's recent historicalEventIds, requiring no new storage
  • Uses the score to shift the pretender revolt cohesion threshold by ±0.10 (range: 0.45–0.65), making dynasty history lightly influence future simulation behavior
  • Inspector now shows Legitimacy: Stable / Contested / Fragile above the Dynasty Chronicle
  • Headless report shows the top dynasty's legitimacy score alongside its prestige

Architecture answers (pre-implementation inspection)

Question Answer
Where are dynasties? state.dynasties: Record<Id, Dynasty> in GalaxyState; Dynasty.ts owns all logic
Where are chronicle events recorded? recordDynastyEvent() in Dynasty.ts — pushes into dynasty.historicalEventIds (capped at 12)
Where are revolt decisions made? maybePretenderRevolt() in Dynasty.ts, called from maybeLifeEvents()
Does dynasty prestige exist? Yes — dynasty.prestige (0–100), grows with long reigns, drops on coups/extinction
Is there a legitimacy/stability field? No prior field on Dynasty; Faction has one but is unrelated
Smallest deterministic change? Derive a score from existing historicalEventIds and shift the revolt threshold

Behavior

dynastyLegitimacy(state, dynastyId) — pure, derived, no new storage:

  • +1 per positive event: heir-born, succession, dynasty-restored, dynastic-marriage
  • −1 per negative event: heir-died, succession-crisis, pretender-revolt, dynasty-extinct
  • Normalized by chronicle length, clamped to [-1, 1]

Revolt threshold shift (was fixed at 0.55):

  • revoltThreshold = 0.55 − legitimacy × 0.10
  • High legitimacy (+1) → threshold 0.45 (revolt requires deeper instability)
  • Low legitimacy (−1) → threshold 0.65 (revolt can happen at higher cohesion)

Inspector label: Stable (green) / Contested (yellow) / Fragile (red) — shown when chronicle exists.

Headless report line (new):

- Careers: 18 promotions · 11 falls · top house: Jarax (prestige 51, legitimacy +1.00)

Test results

✓ tsc --build (no type errors)
✓ eslint . (no lint errors)
✓ npm run report (determinism check passed — identical replay from same seed)

Noet advisory layer

Noet was used in advisory/cognitive mode only (no Noet source modified). Mode recommendation: Implementer. The noet cognition digest confirmed the right constraints: stay model-agnostic, keep behavior deterministic, prefer derived signals over stored state.

Dogfood receipt

  • Repository root: /home/user/noet
  • Branch: claude/dynasty-legitimacy-signal-4f5jqs
  • Initial slice: slice-2026-06-25-032513 (advisory-only lane)
  • Files changed in Noet: (none)
  • Surface gate: ✓ PASS
  • Hash valid: ✓ yes
  • SERs: 0
  • Noet source modified: no

Generated by Claude Code

Adds dynastyLegitimacy(state, dynastyId) — a [-1, 1] score computed
from the dynasty's recent historicalEventIds. Positive events (heir-born,
succession, dynasty-restored, dynastic-marriage) push toward +1; negative
events (heir-died, succession-crisis, pretender-revolt, dynasty-extinct)
push toward -1.

The score lightly shifts the pretender revolt cohesion threshold by ±0.10:
- High legitimacy (+1) requires cohesion ≤ 0.45 before revolt can fire
- Low legitimacy (−1) allows revolt when cohesion ≤ 0.65

The inspector now shows "Legitimacy: Stable / Contested / Fragile" above the
Dynasty Chronicle when chronicle events exist. The headless report shows the
top dynasty's legitimacy score alongside its prestige.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPPpxsKfPvjTpLdZLBLC6V
@csheldrick
csheldrick merged commit 148e616 into main Jun 25, 2026
2 checks passed
@csheldrick
csheldrick deleted the claude/dynasty-legitimacy-signal-4f5jqs branch June 25, 2026 03:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants