Updates

Development changelog

22 released versions and 22 in-flight entries. Each update leads with what changed; the verbatim engineering record is attached underneath.

This is a development changelog — it records engine and content work in the order it shipped. Looking for what is actually in the game? Start with the world, the 25 classes or the Boss Codex.

Unreleased ANDY reconstruction integration (PR #8): D-606 Calamity system, Arsenal Level-3 + Cosmology activator, H-012 trigger, M30-CUR-003 resolution 2026-09-02

D-606 — engine Calamity system (user-approved 2026-09-02).

Full changelog entry (verbatim, engineering detail)
- **D-606 — engine Calamity system (user-approved 2026-09-02).**
  Optional per-battle `CalamityPolicy` (forms/chance/trigger
  exclusions/enabled) via `Battle.create(..., calamity_policy=...)`
  and `Battle.arm_calamity()`; inert by default (no policy armed =
  pre-D-606 behavior). On curse activation, AFTER the normal activation
  effects (and echo spread) resolve unchanged, an armed policy may
  ADDITIONALLY erupt one random rollable form — additive, never a
  replacement. Seeded/replayable RNG (`chance`, `choice`) with 0.0/1.0
  short-circuit; out-of-range chance rejected at construction
  (BTL-980). Cascade excluded; boss curses unrollable by construction;
  fail-closed everywhere; `CURSE_CALAMITY` emitted only when an
  eruption fires; forms are content-side data (no registry
  registration; D-017 preserved). Source-supported Blight Calamity form
  (uncapped mirror of the normal spawn); `DEFAULT_ERUPTION_CHANCE =
  0.15` (protected/source-derived Arsenal value; not armed in
  production by default). Not invented: Cascade/Haunt/boss Calamity
  forms stay Unknown / Not stated (M30-CUR-002 DEFERRED). Authoritative
  record: `MILESTONE_CALAMITY_SYSTEM_REPORT.md`; decision entry D-606
  added to DECISIONS.md post-merge. Tests:
  `tests/unit/test_calamity_system.py` (14).
- **Arsenal Level-3 authorized batch + Cosmology Calamity activator.**
  Authorized Level-3 content delivered (`human_level3` modules: 45
  abilities / 11 artifacts / 5 consumables / 17 statuses) including the
  Cosmology passive (`ability.human.cosmology`) that arms the Calamity
  policy at BATTLE_STARTED at the source-stated 15%, holder-scoped
  (opposite-side check before any RNG draw; first-armed wins;
  fail-closed). Registry totals: ability 144, total 469. Delivery
  record: `ARSENAL_L3_BATCH_REPORT.md`. Tests:
  `tests/unit/test_cosmology_calamity.py` (7) + `test_l3_arsenal_batch.py`.
- **H-012 — Battle Mage affinity-curse trigger completed.** The class
  map is wired to the Human namespace (`HUMAN_AFFINITY_CURSES`); the
  M19/M25 "no Human affinity content" blocker expired with M30's 16
  Human affinities + Human curses; D-524 unchanged (Divine bonds on
  Human beings still rejected). See `test_battle_mage_affinity_curse_triggers`.
- **M30-CUR-003 resolved — D-607 (user-approved).** H1: Hemorrhage is
  the ONE-SHOT production behavior (10% current HP + 10% potency loss,
  once per activation) — the descriptive "/turn" reading is REJECTED.
  M1: Madness is the self-attack through the existing damage pipeline
  (dodgeable, crit-eligible, DR applies) — no forced-action engine, no
  extra turn/action machinery (D-526 boundary stands). Decision record:
  DECISIONS.md D-607. No production code change was required for the
  lock itself.
- **Verification (2026-09-02):** full suite at the PR #8 head `1727
  passed, 0 failed, 10 errors, 2 warnings` (10 known M29 fixture errors
  only); focused Calamity/cosmology/arsenal suites green; Ruff/mypy/
  compileall clean on the new modules. Delivered to `main` via PR #8
  (merge commit `d5636da46606e4fa065580edf37390cf4ea20551`). Version
  stays 0.19.0 (baseline); no schema/migrations.
Unreleased Stage 4.6: Developer Learning-Gate Sweep (docs/50 Stage 4, sixth unit; docs/42 §3; docs/19 §12/§24; docs/45 §12) 2026-08-28

Read-only batch view of the 4.1 validation gate over the whole

Full changelog entry (verbatim, engineering detail)
- **Read-only batch view of the 4.1 validation gate over the whole
  battle table** (docs/42 §3 pipeline stage "Data Validation";
  docs/19 §12/§24 validation before learning; docs/45 §12
  "investigate learning problems"; docs/42 §24 "Review datasets" at
  summary level). Fresh audit: knowledge export (docs/31 §26) was
  the only other new candidate and stays D-R005 (artifact
  format/scope/restore undefined); all previously-rejected
  candidates remain blocked. No D-R005 here — aggregation of
  existing deterministic verdicts by arithmetic only. Version stays
  0.19.0; no schema/migrations.
- **`LearningValidationService.learning_gate_overview(include_limit=10)`**
  (`dio.services.learning`): frozen `LearningGateOverview`/
  `LearningGateFailure` — population is ALL battles (stable id
  order; non-completed surface as VAL-001 failures, never hidden),
  each validated through the SAME `validate_battle` code path
  (test-proven identical verdicts); outputs pass/fail counts, a
  per-finding-code histogram (codes sorted), and bounded failing
  battles (clamp [1,25]); deterministic; writes nothing.
- **`/learning_gate [limit]`** (`dio.application.cogs.learning`,
  extended): admin-only ephemeral sweep surface on the reward-admin
  convention; empty battle table → zero-overview message. M31
  locked command surface gains `learning_gate`; 4.2–4.5 surfaces
  preserved and re-tested.
- **Tests:** new `tests/unit/test_stage46_learning_gate_sweep.py`
  (9 tests). Full suite `1666 passed, 0 failed, 10 errors, 2
  warnings` (10 known M29 fixture errors only; baseline 1657 + 9).
Unreleased Stage 4.5: Developer Learning-Record Inspection (docs/50 Stage 4, fifth unit; docs/31 §27; docs/45 §7/§22) 2026-08-28

Read-only single-record DETAIL view completing the 4.3 summary

Full changelog entry (verbatim, engineering detail)
- **Read-only single-record DETAIL view completing the 4.3 summary
  listing** (docs/31 §27 "Inspect memories"; docs/45 §7 "View stored
  knowledge"; §22 developer-only tools; docs/19 §26 "Learned
  patterns"). Fresh audit: every other cluster candidate remains
  D-R005/blocked (edit = fabrication; no confidence scale; no lock
  schema; undefined retraining/dataset/activity-log/status content;
  no knowledge flow/training). No D-R005 here — verbatim
  transcription of one stored row. Version stays 0.19.0; no
  schema/migrations.
- **`LearningValidationService.get_learning_record(battle_id)`**
  (`dio.services.learning`): frozen `LearningRecordDetail` with the
  FULL stored `observed_pattern` exactly as persisted; `LRN-404`
  when none; deterministic newest-row pick on legacy multi-row
  violations; never re-runs validation, never writes (proven
  decoupled from battle rows).
- **`/learning_view battle_id:<id>`** (`dio.application.cogs.learning`,
  extended): admin-only ephemeral inspection on the reward-admin
  convention; the pattern renders as a JSON code block, truncated
  only at Discord's field limit and always labeled. M31 locked
  command surface gains `learning_view`; 4.2/4.3/4.4 surfaces
  preserved and re-tested.
- **Tests:** new `tests/unit/test_stage45_learning_record_inspection.py`
  (9 tests). Full suite `1657 passed, 0 failed, 10 errors, 2 warnings`
  (10 known M29 fixture errors only; baseline 1648 + 9).
Unreleased Stage 4.4: Developer-Controlled Learning-Record Removal (docs/50 Stage 4, fourth unit; docs/45 §7) 2026-08-28

The explicit, admin-only correction path over persisted learning

Full changelog entry (verbatim, engineering detail)
- **The explicit, admin-only correction path over persisted learning
  records** — named by four specs (docs/45 §7 "Remove outdated
  knowledge"; docs/19 §27 "Knowledge correction / Removing bad
  patterns"; docs/42 §24 "Remove entries"; docs/31 §27 "Remove
  incorrect knowledge"). Selected by a fresh discovery audit;
  classification: implementation-ready — `AILearningRecord` is leaf
  data with no consumers (verified in code), so deletion has no
  downstream semantics. No D-R005; version stays 0.19.0; no
  schema/migrations.
- **`LearningValidationService.remove_learning_records(battle_id)`**
  (`dio.services.learning`): deletes ONLY the `AILearningRecord` rows
  sourced to the named battle (the identifier 4.3 displays; unique per
  the 4.2 invariant; legacy multi-row violations fully repaired);
  `LRN-404` when none exists — nothing deleted, safe idempotent
  repeat. Battle data is NEVER touched. Frozen `LearningRemovalResult`
  reports the removed record ids.
- **`/learning_remove battle_id:<id>`** (`dio.application.cogs.learning`,
  extended): admin-only ephemeral surface on the reward-admin
  convention + `standard_embed`/`user_message` patterns. M31 locked
  command surface gains `learning_remove`; 4.2/4.3 surfaces preserved
  and re-tested.
- **Boundary guarantees proven by tests:** reversible per docs/42 §25
  (persist → remove → persist recreates a record with an IDENTICAL
  frozen transcription); 4.1 gate unaffected (still passes after
  removal); 4.3 listing reflects removal; write boundary — only
  ai_learning_records changes; single-battle isolation; no automatic
  removal anywhere; no edit/confidence/lock (still D-R005: editing
  frozen evidence = fabrication; no confidence scale; no lock schema).
- **Tests:** new `tests/unit/test_stage44_learning_record_removal.py`
  (8 tests).
- **Incident:** a THIRD sandbox rebuild during final validation again
  deleted all local checkpoint commits (never pushed; the prior bundle
  artifact was lost too); the working tree survived complete. The 4.4
  checkpoint commit was withheld per the standing rules — recovery
  decision pending (see root RECONSTRUCTION_STATE.md).
Unreleased Stage 4.3: Developer Learning Monitoring (docs/50 Stage 4, third unit; docs/19 §26) 2026-08-28

Read-only, admin-only inspection of the records 4.2 persists

Full changelog entry (verbatim, engineering detail)
- **Read-only, admin-only inspection of the records 4.2 persists**
  (docs/19 §26 "Developer Monitoring": view learned patterns,
  confidence levels, data sources, learning changes; docs/45 §7/§22;
  docs/31 §27; docs/42 §24). Selected by a fresh discovery audit; no
  D-R005 needed — zero new knowledge semantics. Version stays 0.19.0;
  no schema/migrations.
- **`LearningValidationService.list_learning_records(limit=10)`**
  (`dio.services.learning`): frozen `LearningRecordListing` of stored
  `AILearningRecord` columns only (record id, source battle,
  confidence, version, created timestamp, pattern kind). Deterministic
  order (`created_at` DESC, ties by `source_battle_id` ASC); limit
  clamped to [1, 25]. Never re-runs validation, never re-derives
  evidence, never interprets, never writes (proven decoupled: the
  listing works even with the battle rows deleted).
- **`/learning_records [limit]`** (`dio.application.cogs.learning`,
  extended): admin-only ephemeral monitoring surface on the existing
  `/reward_grant` permission convention + `standard_embed`/`user_message`
  patterns; empty-state message; "confidence 0.0 = not yet evaluated"
  gloss; battle ids shown only because docs/19 §26 requires viewing
  data sources on an admin-only ephemeral surface. M31 locked command
  surface gains `learning_records`.
- **Explicitly NOT implemented:** knowledge edit/removal/locking
  (docs/45 §7, docs/31 §27, docs/19 §27 — destructive writes needing
  separately specified correction/audit semantics); confidence
  adjustment/formulas; pattern interpretation; dataset
  creation/versioning; any write; LLM/provider; self-play/RL/
  prediction; Stage 5; gameplay changes.
- **Tests:** new `tests/unit/test_stage43_developer_learning_monitoring.py`
  (9 tests). Full suite `1640 passed, 0 failed, 10 errors, 2 warnings`
  (10 known M29 fixture errors only; baseline 1631 + 9).
Unreleased Stage 4.2: Developer-Controlled Validated-Evidence Persistence (docs/50 Stage 4, second unit) 2026-08-28

The explicit, admin-only write path behind the Stage 4.1 gate.

Full changelog entry (verbatim, engineering detail)
- **The explicit, admin-only write path behind the Stage 4.1 gate.**
  Implemented under the user-approved bounded D-R005 contract; version
  stays 0.19.0; no schema/migration (`AILearningRecord` existed,
  unwired).
- **`LearningValidationService.persist_validated_evidence(battle_id)`**
  (`dio.services.learning`, extended — no redundant infrastructure):
  the battle MUST pass the 4.1 gate (failing battle → `LRN-422`, zero
  records; unknown battle → `LRN-404`); a passing battle produces
  exactly ONE `AILearningRecord` — idempotent (existing record
  returned, never duplicated; checked BEFORE re-validation so a later
  engine-version bump cannot orphan a recorded battle);
  `source_battle_id` = the battle; `confidence = 0.0` ("not yet
  evaluated" — no formula invented); `version = 1.0`.
- **`observed_pattern` is a frozen transcription of validated evidence
  only:** 4.1 validation/provenance facts (verdict, recorded + intake
  current ruleset/engine versions, evidence counts) + Stage 3.1
  battle-review facts (summary, combat profiles, key moments, turning
  point, evidence-cited strengths/weaknesses). Nothing is interpreted
  into strategies/lessons/mistakes/recommendations. Builds and
  alternative/counterfactual possibilities are OMITTED (data does not
  exist) — proven by test. Deterministic: same battle state → same
  transcription.
- **`/learning_record battle_id:<id>`** (`dio.application.cogs.learning`):
  admin-only ephemeral surface following the existing `/reward_grant`
  convention (guild `administrator` or `manage_guild`); normal users
  rejected; M31 locked command surface gains `learning_record`.
- **Boundary held:** persistence never alters battle/replay/events/
  snapshots/action_history/statistics/Stage 3 outputs; NO automatic
  learning exists (battle finalization writes nothing — proven by
  end-to-end test); no strategy discovery, interpretation, confidence
  calculations, recommendations, coaching, counterfactuals, self-play,
  RL, predictions, autonomous decisions, LLM/provider, or Stage 5
  work.
- **Tests:** new `tests/unit/test_stage42_validated_evidence_persistence.py`
  (12 tests). Full suite `1631 passed, 0 failed, 10 errors, 2 warnings`
  (10 known M29 fixture errors only; baseline 1619 + 12).
Unreleased Stage 4.1: PvP Learning Data Validation (docs/50 Stage 4, first unit; docs/19 §12/§24; docs/42 §3/§11) 2026-08-28

First Stage-4 unit — the developer-controlled validation gate.

Full changelog entry (verbatim, engineering detail)
- **First Stage-4 unit — the developer-controlled validation gate.**
  Transcribes only the spec-named check dimensions; no scores,
  thresholds, or heuristics invented. Version stays 0.19.0.
- **`LearningValidationService`** (`dio.services.learning`):
  deterministic, read-only `validate_battle(battle_id)` over the M2
  artifacts (Battle, Replay, battle_state_snapshots, action_history,
  events). Stable finding codes in fixed order — Validity VAL-001..006
  (completed state; result/winner/participant consistency; Player-row
  referential integrity), Completeness CMP-101..110 (replay presence +
  structure; action/event/snapshot evidence; turn-0 snapshot; turn
  coverage; duplicates; malformed combat_state), Consistency
  CON-201..208 (battle row vs replay results on outcome/winner/turns;
  row-count vs replay-list equality for actions and events;
  non-participant actors; out-of-range action turns; snapshot row vs
  combat_state turn), Provenance PROV-301..304 (recorded + current
  ruleset/engine versions; mismatches REPORTED and failing the gate
  for the current-version dataset — never mixed silently, docs/21
  §25). Verdict: "pass" iff zero findings, else "fail"; frozen
  `LearningValidation`/`ValidationFinding`/`ValidationEvidence`
  result objects; `LRN-404` unknown battle.
- **Gate only — not learning:** no strategy detection, mistake
  classification, recommendations, confidence/anomaly formulas,
  pattern discovery, self-play, LLM/provider, or autonomous
  behavior. Writes NOTHING — `ai_knowledge`, `ai_learning_records`,
  `theory_strategies`, `simulations` stay unwired; Stage 4.1
  produces validated evidence only (a developer-explicit persistence
  action awaits separately specified approval semantics, docs/45
  §14/§22).
- **No cog:** no developer-command convention exists in the
  application (docs/45 §22 unimplemented), so the gate is
  service-layer only, DI-registered in `bootstrap.py`; the M31
  locked public command surface is unchanged.
- **Data boundary (honest):** builds/matchups (linkage never
  written), per-artifact attribution, alternative decisions, and all
  pattern/confidence semantics remain unavailable/undefined — not
  validated, not invented (D-R005).
- **Tests:** new `tests/unit/test_stage41_learning_validation.py`
  (14 tests: pass/fail paths per dimension, provenance capture +
  mismatch reporting, determinism, isolation, read-only incl. zero
  AI-table writes, LRN-404, real finalize→validate end-to-end, DI
  registration without command surface). Full suite `1619 passed, 0
  failed, 10 errors, 2 warnings` (10 known M29 fixture errors only).
  No schema/migrations; no CI changes; Stage 3.1–3.4 + M2 preserved.
- **Incident:** post-validation sandbox rebuild (fresh clone) lost
  the six local checkpoint commits from the object store; the
  working tree survived complete. Checkpoint commit withheld pending
  recovery decision (see root RECONSTRUCTION_STATE.md).
Unreleased Stage 3.4: Combat Performance Statistics (docs/50 Stage 3; docs/21 §6) 2026-08-28

Fourth Stage-3 unit — deterministic Combat Performance

Full changelog entry (verbatim, engineering detail)
- **Fourth Stage-3 unit — deterministic Combat Performance
  Statistics.** Spec-named metrics only (docs/21 §6: damage,
  defense, recovery groups). Version stays 0.19.0.
- **`CombatPerformanceService`** (`dio.services.performance`):
  read-only career aggregation over completed battles' immutable
  replays + per-turn snapshots — Damage: total dealt/taken, average
  damage per turn; Defense: damage prevented (sum of recorded
  ``shield_absorbed`` on damage taken), shields created (count and
  total value of ``shield`` effects sourced), damage avoided (dodge
  count + dodge rate from ``after_attack`` events); Recovery:
  healing done (sourced healing effects) and received, resources
  recovered (``energy_gained`` event amounts), survival duration
  (average turns survived from snapshot ``alive`` traces).
- **`/performance` command** (`dio.application.cogs.performance`):
  public embed on the existing `standard_embed`/`user_message`/
  lookup-only-identity architecture (STX-404 unknown player).
  DI-registered; the M31 locked command-surface list gains
  `performance`.
- **Honest data boundary:** docs/21 §6 "damage efficiency" has no
  defined semantics in the surviving specification and is NOT
  computed; matchup/build analytics, artifact analysis, coaching,
  and counter suggestions remain data-blocked or recommendation-based
  and out of scope. Nothing fabricated (D-R005).
- **Explicit non-goals:** no LLM/provider, no learning, no writes,
  no recommendations, no Stage 4+ features, no schema/balance/reward
  changes.
- **Tests:** new `tests/unit/test_stage34_combat_performance.py` (7
  tests): damage/defense/recovery metric math, completed-battle
  scoping + player isolation, empty state + zero-division safety,
  STX-404, read-only guarantee, embed contract, command
  registration; M31 surface list updated.

---
Unreleased Stage 3.3: Action Statistics (docs/50 Stage 3; docs/21 §7) 2026-08-28

Third Stage-3 unit — deterministic Action Statistics.

Full changelog entry (verbatim, engineering detail)
- **Third Stage-3 unit — deterministic Action Statistics.** Spec-named
  metrics only (docs/21 §7: ultimate timing, item usage, rest usage,
  target selection; ability usage shipped as Stage 3.2). Version
  stays 0.19.0.
- **`ActionStatisticsService`** (`dio.services.actions`): read-only
  aggregation over `action_history` rows of COMPLETED battles:
  per-category usage (attack/ability/ultimate/item/rest — uses,
  battles, average/first/last turn, giving docs/21 §7 "Ultimate
  timing" and "Rest usage"), item usage breakdown per item
  (`action_data.content_id`), and target selection (per-opponent
  targeted-action counts, distinct targets; self-targeted actions
  excluded). Deterministic ordering throughout (count desc, then id).
- **`/actions` command** (`dio.application.cogs.actions`): public
  embed on the existing `standard_embed`/`user_message`/
  lookup-only-identity architecture; display names only — raw
  content/player ids never rendered (STX-404 unknown player).
  DI-registered; the M31 locked command-surface list gains `actions`.
- **Honest data boundary:** docs/21 §8 Decision Quality
  (counterfactual comparisons), docs/29 §12 Artifact Analysis
  (per-artifact attribution is not recorded — artifacts act via
  hooks and recorded effects carry combatant ids), docs/29 §13
  Counter Suggestions, and build-level analytics (unwritten build
  linkage) are NOT implemented. Nothing fabricated.
- **Explicit non-goals:** no LLM/provider, no learning, no writes, no
  recommendations, no Stage 4+ features, no schema/balance/reward
  changes.
- **Tests:** new `tests/unit/test_stage33_action_statistics.py` (9
  tests): category aggregation + ultimate timing, item breakdown,
  target selection + deterministic order, completed-battle scoping +
  isolation, empty state, read-only guarantee, STX-404, embed name
  contract, command registration; M31 surface list updated.

---
Unreleased Stage 3.2: Ability Usage Analysis (docs/50 Stage 3; docs/29 §11, docs/21 §10) 2026-08-28

Second Stage-3 unit — deterministic Ability Usage Analysis.

Full changelog entry (verbatim, engineering detail)
- **Second Stage-3 unit — deterministic Ability Usage Analysis.**
  Spec-defined metrics only (which abilities, how often, when,
  effectiveness, who uses them); no invented analytics. Version stays
  0.19.0.
- **`AbilityUsageService`** (`dio.services.usage`): read-only
  aggregation over `action_history` rows of COMPLETED battles:
  per-player per-ability `uses`, `battles`, `average_turn`,
  `success_rate` (share of uses whose action resolved ok with at
  least one successful effect), `average_damage`/`average_healing`
  (from recorded per-effect results), and the deterministic
  most-co-used partner ability (ties -> lexicographically smallest
  id; docs/21 §10 "common combinations"); plus the ability-scoped
  aggregate across players (total uses, unique users, averages;
  docs/21 §10 "who uses it"). Entries ordered by uses desc, then id.
- **`/usage` command** (`dio.application.cogs.review`-style cog at
  `dio.application.cogs.usage`): public embed on the existing
  `standard_embed`/`user_message` architecture; no argument = the
  invoker's own summary (lookup-only identity, STX-404);
  `ability:<name>` = name-resolved aggregate via
  `ContentService.search` (USG-404 when unmatched or unrecorded).
  Display names only — raw content/player ids are never rendered.
  DI-registered; the M31 locked command-surface list gains `usage`.
- **Honest data boundary:** docs/21 §10 "Context" (player skill,
  build type, opponent type) is NOT implemented — build linkage
  (`battles.build_a_id/build_b_id`) is never written by any current
  code path and skill labels are judgments; docs/29 §10 Build
  Coaching remains data-blocked on that linkage. Nothing was
  fabricated.
- **Explicit non-goals:** no LLM/provider, no learning, no writes,
  no recommendations/coaching, no counter suggestions, no
  build/opponent analytics, no schema/balance/reward changes.
- **Tests:** new `tests/unit/test_stage32_ability_usage.py` (9
  tests): aggregation math, partner tie-break, completed-battle
  scoping + isolation, cross-player aggregate, empty state,
  read-only guarantee, STX-404/USG-404, embed name contract,
  command registration; M31 surface list updated.

---
Unreleased Stage 3.1: Battle Review (docs/50 Stage 3, first unit) 2026-08-27

First Stage-3 (Basic Intelligence) unit — deterministic Battle

Full changelog entry (verbatim, engineering detail)
- **First Stage-3 (Basic Intelligence) unit — deterministic Battle
  Review. AI analyzes; it never decides.** Version stays 0.19.0
  (post-crash convention; see M2 entry).
- **`BattleReviewService`** (`dio.services.review`): read-only,
  deterministic post-battle analysis over the completed M2 data
  foundation (Battle row + immutable Replay JSON + per-turn
  battle_state_snapshots). Outputs frozen dataclasses: summary,
  per-player `CombatProfile` (damage dealt/taken, healing received,
  crits, dodges/incoming attacks, action mix, ultimate timing),
  `KeyMoment`s, one turning point, and evidence-cited
  strengths/weaknesses (`PlayerReview`). No LLM/provider, no learning,
  no writes of any kind.
- **Locked deterministic rules** (operator-approved as NEW DESIGN):
  R1 biggest single-turn HP swing (total HP loss across both
  combatants, earliest on ties); R2 durable winner HP-trace lead
  (earliest turn from which the winner stays strictly ahead in every
  later snapshot); R3 elimination turn (earliest snapshot where a
  combatant is no longer alive); R4 ultimate timing (first ultimate
  turn labelled early/mid/late against total turns); turning-point
  priority R3 > R2 > R1; fixed factual strength/weakness mappings
  (out-damage, dodge/crit counts, damage imbalance, unused ultimate,
  decisive-swing loss share), each citing its evidence.
- **`/review` command** (`dio.application.cogs.review`): public
  embed via the existing `standard_embed`/`user_message` architecture;
  no argument = the invoker's latest completed battle; explicit battle
  id allowed only for battles the invoker participated in
  (REV-403 otherwise; REV-404 unknown battle/replay; REV-405 not
  completed; STX-404 unresolvable player). No internal ids are ever
  rendered (usernames + turn numbers only). Registered in the DI
  container; the M31 locked command-surface list gains `review`.
- **Explicit non-goals (unchanged):** no counterfactuals/alternatives,
  mistake classification, coaching, build analysis, counter
  suggestions, predictions, adaptive learning, autonomous decisions,
  balance/reward changes, schema changes.
- **Tests:** new `tests/unit/test_stage31_battle_review.py` (11
  tests): summaries (victory/draw), profile aggregation, R1-R4 incl.
  negatives, turning-point priority, evidence-cited reviews, read-only
  guarantee (row counts unchanged), battle isolation + validation
  errors, real finalize→review end-to-end, embed id-hiding contract,
  command registration.
- Reconstructed/completed during post-crash recovery from the M31.0 /
  v0.19.0 baseline (new design, operator-approved rule set).

---
0.19.0 Milestone 31.0: Discord UI Foundation / Name Layer 2026-08-13

MINOR bump: shared Discord presentation foundation for M31

Full changelog entry (verbatim, engineering detail)
- **MINOR bump:** shared Discord presentation foundation for M31
  (screenshots-as-UX-reference program). No combat mechanics, content,
  engine, or balance changes; no new/deferred content implemented.
- **New presentation layer:** `dio.application.presentation` (embed
  color tokens per surface, button-style rules — red is exit/destructive
  only, 10-segment meter bars, compact `5.73M` number formatting,
  pagination footer text, friendly restriction wording),
  `dio.application.names` (`NameResolver` — the single id→display-name
  path; never raises, never renders raw ids), `dio.application.errors`
  (`user_message`/`sanitize_text`/`problem_lines` — B6: clean,
  id-free player-facing error copy; internals stay in logs).
- **Service name/search API:** `ContentService.display_name()` +
  `ContentService.search()` (+`ContentMatch`) — registry-backed, used
  by all Discord surfaces; prepares autocomplete for M31.1+.
- **ID exposure cleared (M31 audit §IV):** battle embed title is
  `⚔️ {A} vs {B}` (was `Battle {id[:8]}`); result/feed footers drop
  internal ids; battle log renders `attacked` / `used {content name}`
  from recorded `data.content_id` (was `used Attack`); status/opponent
  curse + cooldown lines resolve to display names with the battle's
  curse threshold (`Purgatory: 63/200`); `/info` lists are name-first;
  profile/character/build success echoes no longer print row ids.
- **B3 fix:** an empty `/build` invocation is now a name-based view of
  the current build — it can never wipe the saved loadout (full editor
  arrives in M31.1).
- **B5 fix (verified gap):** slash commands were never registered —
  no `tree.sync`/`setup_hook` existed. Startup now syncs after cog
  load, gated by `DIO_DISCORD_SYNC_COMMANDS` (default true) with an
  optional `DIO_DISCORD_DEV_GUILD_ID` fast path; failure is logged,
  never crashes startup.
- **Recovery id-free:** `/recover`/`/recover_end` no longer print or
  require internal battle ids; `/recover_end` defaults to the caller's
  own stale session.
- **Version pins:** 0.18.0 → 0.19.0 (`pyproject`, `dio.__version__`,
  version-pin tests updated per convention; M22.5 identity contracts
  unchanged).
- **Tests:** 52 new (`test_m31_presentation/names/errors/embeds/
  foundation`); M11/M28 suites re-pointed at intentional string changes
  (titles/log wording/info lists/profile lead) with every covered
  behavior re-asserted; engine/content suites untouched.

---
Unreleased Milestone 29: Human Content Intake, Reconciliation & Implementation Readiness 2026-08-12

C — PARTIALLY READY / SPECIFIC BLOCKERS (D-602).

Full changelog entry (verbatim, engineering detail)
- **Intake/audit milestone; version stays 0.15.2** (M29 §22). Verdict:
  **C — PARTIALLY READY / SPECIFIC BLOCKERS** (D-602).
- The complete Human source package (dio.bot Arsenal documentation,
  373 entries; 319 at full mechanics) was discovered, read, and
  machine-inventoried (`scripts/m29_source_intake.py`): 16+6 curses,
  16+6 ultimates, 22 consumables, 43 wildcards, 120+30 abilities,
  102+12 artifacts.
- Affinity → Curse → Ultimate mapping derived from the source and
  machine-verified (22/22 pairs; 16 player + 6 boss). Rune
  reconciliation record produced for all 16 Runes (Ember→Scorch …
  Sanguine→Hemorrhage); bindings unchanged in M29; Ruin/Physical
  premise discrepancies (D-584/D-587) resolved by the source.
- Specific blockers: 28 ability + 4 artifact name/ID collisions with
  the Divine registry (race-namespace decision REQUIRED); levels-based
  model vs the D-552 no-levels boundary; no Affinity section in the
  source; 54 boss entries names-only; 6 source-ambiguous consumables;
  gang/prestige/shard/gemstone/stardust systems referenced but
  unauthorized. Nothing implemented, invented, rebalanced, renamed, or
  converted; Divine untouched; registry 269; no economy/Wildcard/
  rating/Stardust/progression; no deployment.
- Tests: `tests/unit/test_m29_human_content_intake.py` (16 tests:
  source integrity, mapping derivation, collision pins, Rune
  reconciliation record, Divine regression, boundaries);
  **1123 total, 83.27% coverage**, mypy (118 files), Ruff (219 files),
  ready 0, fuzz 0, secret scan 0.
0.17.0 Milestone 30 (full): Human Content Implementation & Functional Integration 2026-08-12

MINOR bump (D-604): production Human content implemented on top

Full changelog entry (verbatim, engineering detail)
- **MINOR bump (D-604):** production Human content implemented on top
  of the M30 foundation (affinities/curses/Runes).
- **Human Ultimates (13):** Absolution, Glaciate, Largesse, Lucidity,
  Miasma, Bulwark, Torment, Rupture, Unmake, Accretion, Phantasm,
  Bloom, Celerity — source max-level values, L1→L9 harmony tables
  preserved (level adapter), affinity-gated; Daybreak/Enigma/Awaken
  deferred (documented).
- **Human Consumables (9):** Focus Crystal, Fuel Cell, Leech Seed,
  Lucky Voucher, Medkit, Purging Stone, Repeater, Teddy Bear, War
  Horn; gang/prestige items deferred.
- **Human Abilities (21)** and **Human Artifacts (20)** with real
  mechanics (battle-start passives, crit reactions, lifesteal,
  execution, grit, curse reflects, control).
- **Name-collision policy:** COLLISION_MAP (32 thematic renames;
  source_name provenance preserved); Divine originals untouched;
  Shattering Charge + Desperate Pact implemented under Human ids.
- **Generic engine extensions:** harmony pool ceiling scales to the
  participants' ultimate costs (Divine battles keep 100); energy-gain
  and curse-buildup events carry effect metadata (Torrent rest-block,
  Unmake spread guard); level adapter for L1→L9 tables.
- Tests: `tests/unit/test_m30_full_human_content.py` (50 tests:
  registration, ultimate execution, consumables, abilities,
  artifacts, collisions, serialization/replay, loadout isolation,
  Divine regression, boundaries). **1210 total, 81.60% coverage**,
  mypy strict clean (129 files), Ruff clean (232 files), build
  `andy_engine-0.17.0`, registry 389, `dio ready` 0, fuzz 0, secret
  scan 0. Divine unchanged; no economy/Wildcard/rating/Stardust/
  progression; no deployment.
0.16.0 Milestone 30: Human Affinities, Curses & Rune Reconciliation 2026-08-12

MINOR bump (D-603): new production Human content.

Full changelog entry (verbatim, engineering detail)
- **MINOR bump (D-603):** new production Human content.
- **Human Affinities (16):** `affinity.human.<name>` (Ember…Sanguine),
  identity-only (the supplied source establishes no affinity
  mechanics), `content_race="human"`, owning their Human curse via
  metadata; `HUMAN_AFFINITY_CURSES` (16 machine-verified pairs) is the
  authoritative Human mapping; the Divine `AFFINITY_CURSES` untouched.
- **Human Curses (16):** `curse.human.<name>` (Scorch, Freeze, Shock,
  Doom, Drown, Exhaust, Hex, Madness, Sow, Wither, Break, Cascade,
  Crush, Blight, Haunt, Hemorrhage) + 8 Human curse statuses. 14
  implemented from the source via existing engine channels (status
  ticks/hooks, stat modifiers, action restrictions, roster ops,
  summons, last-action replay). Blocked & documented: Break (ability
  levels, D-552) and Cascade's Calamity amplification (no Calamity
  system). Source ambiguities recorded (Hemorrhage "/turn", Blight
  explosion magnitude, Madness forced-action adapter, Scorch explosion
  timing). Boss curses NOT registered.
- **Rune reconciliation:** all 16 Rune bindings point at the Human
  identities (Ember→Scorch … Sanguine→Hemorrhage); loader validates
  against HUMAN_AFFINITY_CURSES; Light/Verdant/Boreal/Entropic Rune
  effects re-keyed to Exhaust/Sow/Freeze/Cascade; the Sanguine Rune's
  v1 amplifier is DEFERRED (M30-RUN-001); RuneMaster/raid/eligibility
  layers intact.
- **Engine hardening:** EventBus.publish snapshot iteration (a status
  hook subscribed mid-dispatch could re-run earlier hooks on one event
  — found via the Cascade tests).
- Tests: `tests/unit/test_m30_human_affinity_curse.py` (37 tests);
  historical audit tests updated with documented justification (M22.5,
  M23, M24, M25, M26, M27, M28, M29, production-content, canonical
  rules, registry, services). **1160 total, 82.81% coverage**, mypy
  strict clean (121 files), Ruff clean (223 files), build
  `andy_engine-0.16.0`, registry 309, `dio ready` 0, fuzz 0, secret
  scan 0. Divine unchanged; no economy/Wildcard/rating/Stardust/
  progression; no deployment.
0.15.2 Milestone 28: Command Consolidation, Battle UI & Interactive Combat UX 2026-08-11

PATCH bump (D-601): Discord command/API surface changed per the

Full changelog entry (verbatim, engineering detail)
- **PATCH bump (D-601):** Discord command/API surface changed per the
  established convention (§37) — gameplay-neutral, no combat formulas,
  balance values, Rune, economy, Wildcard, rating, or progression
  change.
- **Command consolidation:** the six per-type info commands
  (`/abilities`, `/artifacts`, `/affinities`, `/curses`, `/ultimates`,
  `/consumables`) were REMOVED and consolidated into `/info` — one
  command, eight selectable categories (Abilities · Artifacts ·
  Consumables · Affinity & Ultimate [combined intentionally] · Curses ·
  Runes · Race · Classes) with select-menu navigation, pagination
  (25/page), and registry-grounded entry info (incl. Rune bonded/
  unbonded/eligibility/raid fields and class tier/slot data).
- **Battle UX (BattleView):** eight primary controls — Surrender,
  Attack, Rest, Ultimate, Status buttons + Ability/Artifact/Consumable
  selects + Target select with deterministic ⚡ Weakest / 💪 Strongest
  shortcuts (HP-ordered, tie-break participant order; engine-validated).
- **Battle Status embed:** HP bar + current/max/%, Power, Energy,
  Harmony, Dodge, Critical, Defense; Curse Resistance shown ONLY when
  buildup exists; Curse Buildup, active statuses, cooldowns,
  restrictions, summons, Enemies count. Opponent inspection via
  Status → Select Opponent (observable stats + visible buildup; ability
  inventory hidden).
- **Action flow:** player action-result embed (authoritative engine
  data: damage/crit/heal/status/curse/resource effects + HP deltas),
  compact Battle Log in the battle embed (last 5 actions), surrender
  flow (`BattleService.surrender` → engine `_end_battle` outcome
  "surrender"), character icon integration point with safe fallback.
- **Fixed (M28-UX-001):** latent M11 embed bug
  (`ResourcePool.maximum` → `specs[name].max_value`); presentation-only.
- Tests: `tests/unit/test_m28_ux.py` (22 tests) + consolidated-cog
  tests updated; **1107 total, 83.27% coverage**, mypy strict clean
  (118 files), Ruff clean (218 files), build `andy_engine-0.15.2`,
  registry 269 unchanged, `dio ready` 0, fuzz 0, replay/isolation/
  Discord green, secret scan 0. No deployment. Human content boundary
  and gameplay boundary preserved (§34/§29).
Unreleased Milestone 27: Human Content Integration Framework & Registry Readiness Audit 2026-08-11

B — FRAMEWORK READY WITH GAPS (D-600).

Full changelog entry (verbatim, engineering detail)
- **Audit-only milestone; version stays 0.15.1** (M27 §23). Verdict:
  **B — FRAMEWORK READY WITH GAPS** (D-600).
- Framework verified: race-typed architecture end-to-end (every
  content type carries `content_race`); registries race-agnostic
  (globally unique IDs, race metadata); loader rejects every invalid
  race combination (full matrix tested); resolver action paths
  race-agnostic; serialization/replay/battle-state/Discord embeds
  preserve race. Human classes (25) + Runes (16) verified intact;
  no Human content invented; no placeholders; no Rune binding changed;
  no Divine content modified.
- Gaps (pending Human source): Human Affinity→Curse mapping structure
  + loader path (M26-HUM-003); Rune reconciliation (D-598/D-599);
  per-curse capability classification; Human Ultimate affinity-gate
  applicability.
- Tests: 19 new audit tests (`tests/unit/test_m27_framework_readiness.py`);
  **1084 total, 83.36% coverage**, mypy/Ruff clean, registry 269,
  `dio ready` 0, fuzz 0, secret scan 0, Stardust 0. No deployment.
Unreleased Milestone 26: Human Affinity & Curse Source Integration Audit 2026-08-11

Finding: the Human Affinity/Curse source was NOT supplied

Full changelog entry (verbatim, engineering detail)
- **Audit-only milestone; version stays 0.15.1** (M26 §21).
- Finding: the Human Affinity/Curse source was NOT supplied —
  exhaustive workspace search found only the original prototype
  (the Divine source, already ported). 0 Human affinities, 0 Human
  curses registered (machine-verified). Nothing invented.
- All 16 Rune bindings remain UNRESOLVED — USER DECISION REQUIRED
  (provisional Divine resolution, D-598/D-599); no binding changed.
  `AFFINITY_CURSES` remains Divine-only, untouched.
- Engine capability analysis + per-curse audit templates documented;
  Divine side verified unchanged; economy/Wildcard/rating/Stardust
  boundaries re-verified.
- Tests: 13 new audit tests (`tests/unit/test_m26_human_affinity_curse_audit.py`);
  **1065 total, 83.36% coverage**, mypy/Ruff clean, registry 269,
  `dio ready` 0, fuzz 0. Verdict: **C — AUDIT BLOCKED** (Human source
  incomplete). No deployment.
Unreleased Milestone 25: Human Content Intake, Separation Audit & Integration Plan 2026-08-11

Audit: machine-generated Human/Divine content inventory

Full changelog entry (verbatim, engineering detail)
- **Audit-only milestone; version stays 0.15.1** (M25 §22 — no gameplay
  release for documentation).
- Audit: machine-generated Human/Divine content inventory
  (`scripts/m25_content_inventory.py`): Divine 177 (77 abilities / 16
  affinities / 40 artifacts / 16 curses / 16 ultimates / 12
  consumables), Human 41 (25 classes / 16 Runes), shared 51 statuses,
  registry 269.
- Source-of-truth finding (D-598): Rune `bound_affinity`/`bound_curse`
  resolve to Divine-registered identities; `AFFINITY_CURSES` is not
  accepted as the final Human source of truth until the Human
  Affinity/Curse spec is supplied and reconciled. Nothing renamed or
  rewritten.
- Missing Human systems documented as UNKNOWN (Affinities, Curses,
  Abilities, Artifacts beyond Runes, Consumables, Ultimates, specs);
  integration contract + upload checklist produced; economy/Wildcard/
  rating/Stardust boundaries verified (0 Stardust references; no new
  systems).
- Tests: 20 new audit tests (`tests/unit/test_m25_human_content_separation.py`);
  **1052 total, 83.36% coverage**, mypy/Ruff clean, registry 269,
  `dio ready` 0, fuzz 0. Verdict: **B — HUMAN INTEGRATION PARTIALLY
  READY**. No deployment.
Unreleased Update

Documented finding M16-AUD-002 (D-559): targetless ULTIMATE actions

Full changelog entry (verbatim, engineering detail)
### Milestone 16 — decision resolution & final combat specification audit (2026-08-10)
- **No production code changes** (version stays 0.12.0) — the M16
  brief granted no approvals of the M15 decision package; the
  milestone is an audit/verification/documentation lock (D-558).
- Added `tests/unit/test_m16_audit.py` (24 tests): curse audit
  dimensions (buildup/resistance/threshold/duration/removal/
  ownership/inflictor/summons/nullification/isolation/replay),
  ultimate audit (canonical V1/affinity/Harmony tiers/one-action/
  summon exclusion/replay), consumable audit (12 registered; Ability
  Cache inert and blocked), security/isolation invariants (no
  registry/library mutation, no cross-battle hook leakage, no global
  instance growth, no Divine exposure through Human builds), and
  bounded performance sanity (stress battles terminate; no growth
  across 30 battles). 855 tests, 82.69% coverage.
- Documented finding M16-AUD-002 (D-559): targetless ULTIMATE actions
  fall back to the actor per the docs/04 §4.3 effect normalization
  (legacy defaulted to the opponent); not silently fixed — a
  target-defaulting rule is a user decision.
- Deliverables: MILESTONE16_DECISION_RESOLUTION.md +
  MILESTONE16_FINAL_COMBAT_SPECIFICATION_REPORT.md.

### Added
- Full 50-document specification set (Developer Constitution through AI Development Roadmap).
- Complete AI ecosystem documentation (Combat Intelligence through Multi-Agent Architecture).
- Repository structure: README, INDEX, appendices, AI context files.
- **Milestone 0 — Project Foundation (v0.1.0).** Layered `dio` package
  implementing the docs/03 architecture:
  - Registry framework with automatic discovery, duplicate protection,
    reference/circular-dependency validation, and the ten documented
    registries (docs/05, docs/17).
  - Typed event system with priority ordering, cancellation, and
    chain-depth protection (docs/18).
  - Canonical 30-hook catalog with the documented priority tiers
    (1000/500/300/100/0) and a HookDispatcher over the event bus (docs/06).
  - Trigger framework: conditions, validation rules, per-battle cooldowns
    (docs/06 §7-8, §12).
  - Calculation-layer framework: Calculator interface, Modifier model,
    modifier pipeline (Base→Flat→Percentage→Multiplier→Cap→Final),
    formula registry (docs/04 §13-14, docs/08).
  - Configuration (pydantic-settings, `DIO_*` env + `.env`, nested groups,
    feature flags), structured logging with correlation ids, error
    hierarchy per docs/04 §20, and a DI container.
  - Data layer: SQLAlchemy 2 models for every docs/13 entity (15 tables),
    generic typed repositories with immutable-model enforcement, Alembic
    migration 0001 (verified up/down, zero model drift).
  - Combat engine skeleton: battle phase machine, combat state, action
    object, action resolver contract (execution pipeline is Stage 1).
  - Discord bootstrap: DioBot, cog auto-discovery, graceful shutdown,
    fail-fast token check, `/ping` health cog (docs/16).
  - `dio` CLI (check / db-init / db-migrate / db-revision / bot-run),
    Makefile tooling, GitHub Actions CI (ruff + mypy + pytest on
    3.11–3.13), pre-commit hooks.
  - Reference prototype preserved verbatim at `src/dio_engine/`
    (41 artifacts, 79 abilities; fuzz harness verified clean).
  - 128 tests, 85.7% coverage; new tracking docs (PROJECT_ROADMAP.md,
    TASKS.md, KNOWN_ISSUES.md, DECISIONS.md); AI_MEMORY.md session 2.

### Changed
- **v0.2.0 — Milestone 1: Core Combat Engine.** Added the combat engine
  on top of the foundation (no foundation rewrite):
  - Battle lifecycle, CombatState, TurnEngine, ActionResolver (11-step
    docs/06 §10 pipeline), EffectResolver with the documented damage and
    curse pipelines, status runtime (docs/07), resources, cooldowns,
    temporary modifiers, seeded RNG, death/victory/draw, battle records,
    recovery architecture, BattleRecorder persistence, DB-backed session
    store.
  - Documented calculators registered: stats.ratio_allocation,
    damage.final, healing.final, curse.buildup, defense.effective_
    resistance, stat.modified, resource.update, cooldown.final.
  - Conflict resolutions (developer-approved 2026-08-10): BAL-001 spec
    curse formula (threshold configurable, default 200), D-020 default
    Human stats activated, REG-001 dotted IDs confirmed, HOK-001
    canonical hooks confirmed.
  - 135 new tests (264 total, 87.0% coverage); engine version 0.2.0.
- Foundation API evolution (documented): CombatState gained the full
  canonical state; ActionResolver executes actions (previously raised
  UnimplementedFeatureError); effect model added to core.

### Added (v0.3.0 — Milestone 3: Core Game Content & Registration System)
- Content architecture (`dio.content`): AbilityDefinition,
  ArtifactDefinition, AffinityDefinition, CurseDefinition,
  ConsumableDefinition, UltimateDefinition, SummonDefinition,
  HumanClassDefinition; Race/HumanBeing/DivineBeing configuration with
  the authoritative AI_CONTEXT slot limits; build rules per docs/13.
- Registry: CLASS and SUMMON content types (12 registries); production
  content homes wired into discovery; canonical ID prefix validation.
- ContentLibrary: typed retrieval, cross-registry dependency validation,
  being/loadout validation, content-version recording; DI-wired.
- Combat Engine integration: ParticipantLoadout + loadout ownership,
  artifact/affinity hook binding, affinity stat modifiers, curse
  activation content effects, consumable use limits, summon identity,
  being→participant adapter. Approved engine rules untouched.
- 57 new tests (345 total, 88.2% coverage).

### Changed
- Engine version 0.3.0. Registry now rejects id prefixes that do not
  match the registry's content type (REG-001 enforcement).

### Added (v0.4.0 — Milestone 4: Production Game Content & Character Build System)
- Production content (96 items) from the existing project specification:
  16 affinities, 16 curses (7 with translated mechanics), 16 ultimates
  (identity-only), 12 consumables, 11 supporting statuses, 25 Human
  Classes (tiers, roll weights, Rune Master bonuses, stat modifiers,
  canonical-hook mechanics).
- Class Roll System (TIER_WEIGHTS 44.85/44.95/10/0.1) via the
  centralized RNG.
- Character/build persistence: CharacterService over the existing schema;
  migration 0002 (character affinity, docs/13 §6); affinity-ultimate
  gating; cumulative-stats/ratio validation.
- 42 new tests (387 total, 87.8% coverage).

### Changed
- Engine version 0.4.0. Engine changes were minimal content-integration
  additions (status data payloads, class stat modifiers at preparation,
  class hook binding, BattleRNG.choices/sample).

### Added (v0.4.1 — Milestone 5: Combat Content Integration & Spec Resolution)
- Full audit/design milestone: content matrix, curse/ultimate/harmony/
  consumable/status/HOK-001/artifact/summon/nullification audits, Decay
  conflict investigation, engine extension proposal, implementation
  boundary classification.
- Audit-justified infrastructure: explicit approved combat stage order
  (dio.engine.lifecycle), CombatContext standard content context
  (dio.engine.context), summon-ultimate restriction guard (documented
  rule), HOK-001 declarative legacy-hook map (48 hooks,
  dio.content.legacy.hook_map). 11 new tests (398 total, 88%).
- MILESTONE5_COMBAT_INTEGRATION_REPORT.md with USER DECISIONS REQUIRED.

### Changed
- Engine version 0.4.1. No approved combat rule or production content
  changed; blocked mechanics remain blocked and documented.

### Added (v0.4.2 — Milestone 5 corrections: Canonical Decisions & Harmony Design)
- Canonical user decisions recorded and implemented (DECISIONS
  D-500..D-510): Decay (60% healing->damage canonical), Nullification
  absolute negation (implemented in the EffectResolver; bypass only when
  explicit), Summons never trigger artifact passives (verified), Rune
  Master confirmed, connected Affinity/Curse/Ultimate/Harmony model,
  Human/Divine content separation across the whole content ecosystem
  (current set classified Divine), 25-50 total-action pacing.
- Harmony system implemented (dio/engine/harmony.py): four approved
  generation sources wired into battle events and the resolver,
  economy designed around the pacing model, ultimate Harmony
  requirements (low 40 / moderate 60 / high 80 / very_high 100) and
  spend-reset-to-0.
- Human/Divine separation: production content classified; filtering +
  validation; tests.
- 15 new canonical-rule tests (416 total, 88% coverage).

### Changed
- Engine version 0.4.2. Engine changes were the audit-justified
  corrections above; no approved combat rule or balance value changed
  outside the user-authorized Harmony economy design.

### Fixed
- Foundation-era defect: `apply_default_human_stats` behavior was pending
  approval — now approved and implemented per AI_CONTEXT (D-101).
- Hook integration gap closed: before_damage/after_damage/before_heal/
  after_heal now emit at the documented moments.
- **Final approved rules implemented (2026-08-10, DECISIONS D-130..D-134):**
  crit multiplier caps per race (Human 4x/3x, Divine 3x/3x) with explicit
  overrides; summon source identity + canonical summon events; Basic
  Attack = Power x RNG(0.85-1.25) via the seeded battle RNG; Rest = +3
  Energy, +20% lost HP, +20% DR until the player's next turn; curse
  meter resets on activation with no default overflow (per-effect
  override available). BattleConfig.basic_attack/rest_recovery
  placeholders removed; 25 new tests (288 total, 87.4% coverage).

---
0.15.1 Milestone 24.5: Light Rune Rune-level Eligibility Rule 2026-08-11

Approved change (D-597): the Light Rune's restriction is now

Full changelog entry (verbatim, engineering detail)
- **Approved change (D-597):** the Light Rune's restriction is now
  represented as a RUNE-LEVEL eligibility rule declared on the Rune
  itself, rather than hard-coding Light Rune eligibility as a generic
  class restriction. `RuneDefinition` gains `eligible_classes`
  (empty = every Human class permitted by the Rune's own rule) and
  `eligibility_reason`; the loader enforces the Rune's rule IN
  ADDITION to the existing raid-exclusive layer (user decision: layer
  on top). Human classes, RuneMaster, and all class mechanics are
  fully preserved; no class content changed.
- **Approved rule (user decision):** any Human class may equip the
  Light Rune per the Rune's own rule; Divine beings cannot (Human-only
  Rune, `content_race`). The raid-exclusive/RuneMaster access layer
  remains enforced on top, so the effective equipping class set is
  unchanged (Human classes with raid access). The other 15 Runes are
  untouched (no Rune-level rule declared).
- Engine: `eligible_classes`/`eligibility_reason` on `RuneDefinition`
  + `is_eligible(being)`; `_rune` builder passes the rule through
  (always-serialized `eligible_classes` metadata key); loader
  validation (Rune-rule check + declared-class-id check) in
  `validate_being`.
- Tests: `tests/unit/test_m24_5_light_rune_eligibility.py` (14 tests:
  Rune-level declaration + metadata, every Human class passes the
  rule, Divine rejected, raid layer on top, RuneMaster preserved,
  named-list enforcement, unknown-class diagnostics, other 15 Runes
  unchanged, serialization round-trip, registry integrity); M23 audit
  allowed-list updated (documented).
- 1032 tests (1018 + 14) / 83.36% coverage / mypy strict clean (116
  files) / Ruff clean (212 files) / build `andy_engine-0.15.1` /
  registry 269 (unchanged) / `dio ready` exit 0 / fuzz 0 errors /
  secret scan 0 hits. No deployment.
0.15.0 Milestone 24: Human Rune Implementation, Acquisition & Core Integration 2026-08-10

Human Rune system (the approved 16 Runes; Artifact subtype, no

Full changelog entry (verbatim, engineering detail)
### Added
- **Human Rune system** (the approved 16 Runes; Artifact subtype, no
  parallel system): `RuneDefinition` in dio.content.base with
  `bound_affinity`/`bound_curse`/Bonded-Unbonded tiers; 16 Runes
  registered in the artifact registry (40 -> 56) with machine-verified
  Affinity -> Curse bindings (AFFINITY_CURSES), `content_race="human"`
  and `raid_exclusive=True`.
- **`raid_exclusive` artifact capability** + RuneMaster access:
  `ArtifactDefinition.raid_exclusive`; the production RuneMaster now
  carries `grants_raid_artifact_access=True` (the production port of
  the legacy flag); loadout validation rejects raid-exclusive artifacts
  for unauthorized classes and validates Rune bindings.
- **Rune effects (v1 values, documented revisable):** common lever =
  bound-curse buildup amplification (Bonded x1.30 / Unbonded x1.15,
  before resistance); Verdant +2/+1 seeds per activation with INFINITE
  accumulation (user decision; technical bound only; the parasite
  "seeds" data key now accumulates additively); Sanguine Anemia
  28/65 +5% growth (Bonded) / 24/55 +3% (Unbonded) with INFINITE
  battle-local growth (serialized in the new per-combatant
  `rune_state`); Light Starvation Harmony drain 25/22 (no new Harmony
  source); Entropic curse-activation duplication (Bonded any curse /
  Unbonded bound curse) with NO gameplay chain cap (the existing
  engine event-depth safety boundary is preserved); Boreal +1
  Permafroze charge (Bonded).
- **Acquisition (approved model):** `RuneDropService` — solo 10%,
  group 1%, exactly ONE group roll, battle-id ledger duplicate
  protection, victory-eligibility interface; group distribution is
  recorded as PENDING_GROUP_DISTRIBUTION (open decision).
- **PvP reward interface:** `PvPRewardEvaluator` (legitimate-victory +
  anti-repeat + config-gated minimum rating); rating NEVER grants
  combat power. Reward settings (DIO_RUNE_DROP_SOLO/GROUP,
  DIO_PVP_MINIMUM_RATING) in the config.
- **Wildcard infrastructure:** PvE/Boss-only reward items; PvP use
  rejected; effects not finalized (future milestone).
- 41 new tests (tests/unit/test_m24_runes.py): registry/access/bonding/
  effects/acquisition/PvP/wildcards/isolation/serialization/replay.
  1018 tests, 83.33% coverage.

### Changed
- `CombatantState.rune_state` (serialized battle-local Rune state);
  `StatusManager` count-stacking additively merges the "seeds" data
  key; the parasite seed count now scales with accumulated seeds
  (aligned with the documented per-seed intent; identity without a
  Rune).

### Not done
- No Divine Runes; no unauthorized Human systems; no economy/
  progression; no deployment. Rune numbers are v1 and may be
  re-audited after the remaining Human systems are integrated.
Unreleased Milestone 23: Rune Proposal Audit, Balance Review & Decision Package 2026-08-10

Audit of all 16 proposed Runes (machine-verified Affinity->Curse

Full changelog entry (verbatim, engineering detail)
### Added (audit artifacts only — no production change)
- Audit of all 16 proposed Runes (machine-verified Affinity->Curse
  pairs, curse mechanics, artifact architecture, RuneMaster, Harmony
  economy); deep audits for Entropic, Verdant, Sanguine, Light.
- Decision package with D-577..D-592 reserved (ALL PENDING USER
  DECISION) + the architecture decision D-593 (raid_exclusive /
  acquisition).
- 17 audit tests (tests/unit/test_m23_rune_audit.py); 977 tests,
  83.14% coverage; version stays 0.14.1.
- Documented gaps: Appendix K absent from the repository; full
  proposal texts not supplied; Ruin/Physical premises mismatched.

### Not done
- NO Rune implemented, registered, activated, or made canonical; no
  production behavior changed; no engine capability added; no
  deployment.
Unreleased Milestone 22.6: Final ANDY Replit Release Package & File Handoff 2026-08-10

Verified from the staged copy and from an independent extraction of

Full changelog entry (verbatim, engineering detail)
### Added
- Final transferable release archive `release/ANDY_Replit_Release_v0.14.1.zip`
  (1,202,476 bytes; SHA-256 3ec3bec4bb98db8822368db4d1956521d41b310ccddeadd0e287f395b29eaf4e)
  with root directory `ANDY_Replit_Release_v0.14.1/` — 364 files, 53
  directories; no secrets, caches, local databases, or build artifacts.
- Handoff set: `ANDY_RELEASE_MANIFEST.md`, `ANDY_FILE_INVENTORY.md`,
  `ANDY_REPLIT_QUICK_START.md`, `ANDY_RELEASE_SHA256.txt`,
  `MILESTONE22_6_USER_FILE_HANDOFF.md`.
- Verified from the staged copy and from an independent extraction of
  the ZIP: 960 tests, 83.14% coverage, mypy/Ruff clean, migrations at
  head, registry 253, `dio ready` exit 0, prototype fuzz 0 errors,
  secret scan 0 hits.

### Not done
- No code changes (version stays 0.14.1); no gameplay changes; no
  deployment; no Discord connection; no production database; no
  credentials added. The archive is the handoff — Replit import,
  Secrets, PostgreSQL, migrations, bot start and live validation are
  operator actions.
Unreleased Milestone 22.5: Project Rename DIO → ANDY & Replit Packaging 2026-08-10

Project identity renamed DIO → ANDY. User-facing branding now

Full changelog entry (verbatim, engineering detail)
### Changed
- **Project identity renamed DIO → ANDY.** User-facing branding now
  says ANDY (README, current-state docs, CLI descriptions, the
  `dio check` app line via `settings.app_name` default `andy`,
  Dockerfile comments, Replit packaging, the M22 Replit handoff, and
  the ops docs).
- Python distribution metadata renamed `dio-engine` → `andy-engine`
  (pyproject name/description/authors/keywords). Version remains
  **0.14.1** (no version bump for a rename).
- Replit packaging refreshed for ANDY (`.replit`, `replit.nix`,
  REPLIT_DEPLOYMENT.md, REPLIT_ENVIRONMENT.md,
  REPLIT_PRODUCTION_CHECKLIST.md); the run command stays
  `python -m dio bot-run` (retained internal entry point).

### Retained (documented compatibility contracts, D-575)
- Internal Python package/import path `dio`; CLI `python -m dio`;
  `DIO_*` environment variables (`DIO_DISCORD_TOKEN`,
  `DIO_DATABASE_URL`, `DIO_ENVIRONMENT`, …); database schema/tables;
  migration identifiers (head b521670f9664); serialized state keys;
  replay format; registry/content IDs (253 items unchanged); Discord
  command identifiers; error codes.

### Not done
- No gameplay/content/balance changes; no registry change; no
  database migration; no production deployment; no Discord
  connection; no credentials added; no new systems.
Unreleased Milestone 22: Replit Production Deployment 2026-08-10

Deployment verdict C — DEPLOYMENT BLOCKED (no code changes;

Full changelog entry (verbatim, engineering detail)
- **Deployment verdict C — DEPLOYMENT BLOCKED** (no code changes;
  version stays 0.14.1). The workspace is not a Replit repl; no
  DIO_DISCORD_TOKEN / DIO_DATABASE_URL / DIO_ENVIRONMENT; no
  PostgreSQL/git. No live deployment occurred (M22 safety rule).
- Added the Replit deployment package (configuration artifacts):
  `.replit`, `replit.nix`, REPLIT_DEPLOYMENT.md, REPLIT_ENVIRONMENT.md,
  REPLIT_PRODUCTION_CHECKLIST.md, plus
  MILESTONE22_REPLIT_PRODUCTION_HANDOFF.md and
  MILESTONE22_REPLIT_PRODUCTION_VALIDATION_REPORT.md.
- Added 12 production-boundary tests
  (tests/unit/test_m22_production_validation.py). 939 tests, 83.09%.
Unreleased Milestone 21: Controlled Pre-Launch Deployment 2026-08-10

Deployment verdict C — DEPLOYMENT BLOCKED (no code changes;

Full changelog entry (verbatim, engineering detail)
- **Deployment verdict C — DEPLOYMENT BLOCKED** (no code changes;
  version stays 0.14.1). All environment-free gates passed (927
  tests, 83.09%, ready exit 0/1-paths, bot dry-run, fuzz, secret
  scan, production guards verified at runtime, session-store
  persistence round-trip). The deployment chain stopped at the
  infrastructure gate: no Docker/PostgreSQL/host, no credentials, no
  git identity. See MILESTONE21_PRODUCTION_DEPLOYMENT_REPORT.md.
0.14.1 Milestone 20: Final Project Integration, QA & Launch Readiness Audit 2026-08-10

M20-AUD-001 (D-572): Soul Manipulation's ON_DEATH restore now

Full changelog entry (verbatim, engineering detail)
### Fixed
- **M20-AUD-001 (D-572):** Soul Manipulation's ON_DEATH restore now
  applies the authoritative legacy power formula
  (`base_power += (max_power − power) × 0.10`). The ported
  implementation computed `power − power` (always 0) — a genuine
  incorrect implementation of an already-authoritative specification
  (the power-restore component was a silent no-op). No balance change:
  the effect now matches the legacy exactly. Regression-tested.

### Added
- Final audit layer (14 tests in tests/unit/test_m20_final_integration.py):
  combat lifecycle edges (turn-start DoT death, TURN_END kill, draw
  path, summon owner death, ended-battle rejection), serialization
  round-trip of every stateful field, same-seed/different-seed
  determinism, 30-battle isolation, security boundaries,
  unauthorized-system guards, and the Soul Manipulation regression.
  927 tests, 83.09% coverage.
0.14.0 Milestone 19: Human Content Audit, Authorization & Implementation 2026-08-10

Human Class mechanics completed (the authoritative Human content

Full changelog entry (verbatim, engineering detail)
### Added
- **Human Class mechanics completed** (the authoritative Human content
  set — 25 classes from the legacy `classes/` package):
  - Data-driven (already present, verified): Knight (+20% HP, +10% DR),
    Assassin (−30% HP, +1 crit mult, +20% dodge), Spirit King (full
    curse immunity), Rune Master (slot bonuses).
  - Hook mechanics completed: Swordsman (−20% curse inflict + 20%
    attack re-trigger, chain ≤ 5), Spearman (DR piercing), Archer
    (1-turn attack delay + passive-attack immunity), Martial Artist
    (back-to-back +50%, the legacy documented approximation), Mage
    (+20% curse inflict), Summoner (20%-stats summon every 5th owner
    turn), Enchanter (ally stat transfer on ally turns), Healer (50%
    heal share to allies), Spellblade (+25% attack AND curse damage),
    Battle Mage (affinity-curse trigger — BLOCKED component: no Human
    affinity content exists), Paladin (+50% healing received), Fallen
    Knight (+75% attack damage, +50% curse taken), Necromancer
    (battle-start undead; summon control stays blocked), Dragon Tamer
    (battle-start dragon, 10 Purgatory/turn, dragon on curse trigger),
    Time Weaver (opponent attack delay), Blood Lord (uncapped
    lifesteal), World Tree Guardian (stat-debuff immunity).
- **Minimal engine capabilities (all item-driven, battle-local,
  deterministic, serialized):**
  - `uncapped` healing flag (D-568, Blood Lord) — skips the max-HP
    clamp and the Decay conversion (legacy direct health add).
  - Deferred-attack machinery (D-569, Archer / Time Weaver):
    `CombatantState.pending_attacks` (serialized) + resolution at the
    combatant's next turn start; `Battle.should_defer_attack` /
    `basic_attack_effects` / `_resolve_pending_attacks`.
  - `CombatState.last_manual_attacker` (D-570, Martial Artist;
    recorded after the attack's effects resolve — legacy order).
  - Damage-origin markers (D-571): ABILITY damage is stamped
    `is_ability`, ULTIMATE/ARTIFACT/ITEM damage `is_manual` (legacy
    deal_damage defaults), so Archer's passive immunity distinguishes
    action damage from hook/status/summon damage.
- 26 new tests (tests/unit/test_m19_human_content.py): every class
  mechanic, registry/roll/validation, determinism, battle isolation,
  Human/Divine separation, security. 913 tests, 83.02% coverage.

### Fixed
- None (no pre-existing defect was found; the M19 audit confirmed the
  class-registration infrastructure).
0.13.0 Milestone 18: Final User Decision Resolution & Divine Combat Completion 2026-08-10

Decision gate resolved (D-562..D-567): the user approved five

Full changelog entry (verbatim, engineering detail)
### Added
- **Decision gate resolved (D-562..D-567):** the user approved five
  mechanics and rejected/kept four:
  - **Voidpiercer's Edge crit cap (D-562):** new `crit_multiplier_cap`
    per-combatant override channel; the legacy 5.0 raise is applied.
    Silent Reckoning stays at the D-130 3x (the legacy clamp itself
    capped its 6.0 spike at the default 3.0 — 3x is the faithful
    legacy outcome).
  - **Targetless ultimates (D-563, M16-AUD-002 resolved):** a
    targetless ULTIMATE action defaults to the actor's primary
    opponent (legacy parity), resolved before validation so
    validation/hooks/context/effects/replay agree. Self-targeting
    ultimates unaffected; actor fallback remains for other action
    types.
  - **Deathless Vigil resurrection (D-564):** true battle-local
    resurrection via ON_DEATH — full HP, full power (modifiers
    cleared), death fields cleared, once per battle; −30% max HP at
    the next owner turn start. Replaces the M6-era BEFORE_DEATH
    translation.
  - **Morphogenesis resistance shuffle (D-565):** new per-curse
    resistance channel `curse_resistance.<id>`; the user-confirmed
    factor-preserving mapping r = clamp(1 − 1/(1+U), 0, 1) with
    U ~ uniform(−30, 30) per landed manual attack (legacy
    on_manual_attack gate). Documented divergence: U < −1 clamps to
    immunity (legacy drained the curse meter).
  - **Split Personality (D-566):** user-defined pool = the Divine
    registry (active, unowned, cap 5, seeded pick); battle-local grant
    at the legacy −5 energy-cost cut. No levels (UD-01 rejected), no
    auto-use (UD-02 rejected).
- 19 new tests (tests/unit/test_m18_decision_resolution.py) covering
  every approved mechanic, the rejected-decision locks, and the
  inventory/matrix state. 887 tests, 83.01% coverage.

### Fixed
- None (no pre-existing defect was found in the M18 audit).
0.12.1 Milestone 17: Final Divine Content Decision Resolution & Remaining Engine Gap Fix 2026-08-10

Decision gate (D-560): the M17 brief granted no approvals of

Full changelog entry (verbatim, engineering detail)
### Added
- **Decision gate (D-560):** the M17 brief granted no approvals of
  M15-UD-01..08 or M16-AUD-002; all remain PENDING USER DECISION
  (content unchanged); M15-UD-09 (deferrals) and M15-UD-10 (Human
  unauthorized) preserved.
- **Final audit layer** (13 tests in tests/unit/test_m17_final_audit.py):
  decision-gate locks (no restore/rewind/rollback surface, no extra-turn
  machinery, no ability levels/XP/rarity on ANY registered ability, no
  Human content in the prohibited registries, mandom/endlessly
  unregistered, Ability Cache inert+blocked), the M16-AUD-002 pinned
  behavior, a 5-seed multi-seed determinism sweep, and bounded stress
  re-verification. 868 tests, coverage 82.99%.

### Fixed
- **M17-AUD-001 (D-561):** a TURN_END hook's effects could kill the
  last opponent (e.g. Mirror Protocol's turn-end strike), ending the
  battle inside the hook resolution (resolve_effect -> _check_deaths ->
  check_victory -> _end_battle); `TurnEngine.end_turn` then crashed
  with BTL-608 ("cannot end a turn: no active turn") because the
  end-turn phases ran on the already-ended battle. `end_turn` now
  returns cleanly when the battle ended during TURN_END hooks; the
  victory/BATTLE_ENDED/session-finalize recording was already done by
  `_end_battle`. Regression-tested (minimal reproduction + the
  mixed-content path that originally exposed it).
0.12.0 Milestone 15: Final Divine Content Audit, Completions & User Decision Preparation 2026-08-10

mode="set" stat effect (D-553): STAT_MODIFY metadata flag that

Full changelog entry (verbatim, engineering detail)
### Added
- **`mode="set"` stat effect (D-553):** STAT_MODIFY metadata flag that
  turns the effect into an absolute set-to-value -- the resolver computes
  the compensating flat delta (target - current effective, divided by
  the active percentage x multiplier factor) so the channel's effective
  value equals the requested value; `hp` sets the field directly,
  clamped to the effective max_hp. This is a stat modification ONLY --
  no snapshots, history, or rollback (the D-525 restore-engine
  prohibition is untouched).
- **Cooldown validation gate (D-554):** the action-validation cooldown
  check no longer short-circuits on a declared `meta.cooldown`; a
  COOLDOWN_SET effect may place ANY content on cooldown (content
  without cooldown entries remains always-ready, so existing behavior
  is unchanged).
- **Echoed Sanctuary (D-555):** the last restore-family artifact --
  stats capture/restore of the eight legacy Stats fields ONLY (+10%
  while captured, 20-turn auto-revert, manual revert on second
  activation, 5-turn cooldown). Legacy scope verified from the source:
  `copy.deepcopy(owner.stats)` -- no statuses/curses/cooldowns/roster/
  harmony/energy/summons.
- **Sundering Verdict (D-556):** battle-start disable of one random
  opponent ability per opponent (legacy `disabled=True` translated as a
  battle-long COOLDOWN_SET -- activation blocked, stays equipped, hooks
  keep firing, matching the legacy dispatch which never filters
  disabled) + one random artifact destroyed (ROSTER_MODIFY) + Crush 50;
  dodge-gated activation removes a random opponent ability + Crush 50.
- **Fortunes Undertow completed (D-557):** per-turn percentage modifiers
  on BOTH power and max_power (D-547 multiplicative compounding
  reproduces the legacy compounding exactly); the Moper catch scales all
  four pool stats.
- **Prismatic Riposte completed (D-557):** full legacy dodge pipeline --
  pools x1.25, seeded uniform 0.1-0.9 re-split, then ALL eight stats
  x1.25; the legacy dodge-cap raises are moot under the production cap
  (1.0 = always dodge).
- **Ultimatum reclassified PORTED (D-557):** the legacy temporary
  passive-disable (disabled=True on the target's passives) is
  behaviorally INERT in the legacy engine -- `disabled` is consulted
  only by `can_activate` (passives are never activated) and the legacy
  hook dispatch never filters disabled abilities -- so the production
  port already captures the complete legacy behavior.
- 28 new tests (tests/unit/test_m15_final_content.py): the four
  completions, the set-mode capability, race isolation, battle-local
  state, serialization, determinism, nullification scope, summon
  handling, deferral/block regressions, and the repository-computed
  completion matrix.

### Fixed
- None (the M15 audit found no pre-existing engine bugs; the two
  capability changes are documented extensions, D-553/D-554).
0.11.0 Milestone 14: Remaining Engine Gaps & Final Combat Specification 2026-08-10

Battle-local roster operations (D-549): EffectType.ROSTER_MODIFY

Full changelog entry (verbatim, engineering detail)
### Added
- Battle-local roster operations (D-549): EffectType.ROSTER_MODIFY
  (grant/remove/remove_all of abilities/artifacts; seeded random
  selection; hook bind/unbind; ABILITY_GRANTED / ABILITY_REMOVED /
  ARTIFACT_DESTROYED events emitted before unbinding; battle-local only).
- Registry-random ability grants (D-550): Battle.random_ability.
- Unblocked abilities (4 new + 5 completed): system_breach, soft_and_wet,
  dreaded_return (summon resurrection), jackpot (partial: no nested
  auto-use), mutation (refund), cyberpsychosis (scramble), ultimatum
  (cost halving), colossus_unbound (wipe).
- Unblocked artifacts (5): aeonic_flux, reapers_gambit (pool flips via
  the max-stat channels), sovereigns_genesis, release_schedule (partial:
  no level growth), communal_reprieve (awaken heal).
- All 16 curses implemented: parasite (drains + permanent heal
  redirect), immunity (copied resistances + inflictor-scoped countdown),
  cataclysm (artifact destruction), plague (Antibody strikes on the
  inflictor's turn start).
- 26 new tests (tests/unit/test_m14_content_completion.py): roster
  capability, serialization, per-item behavior, complex replay +
  isolation, deferral regressions.

### Fixed
- Cross-battle state leak: the Plague antibody id counter lived on the
  shared registry-level curse instance; ids are now derived per battle.
- Roster removal now emits the removal event BEFORE unbinding the
  removed content's hooks (Mutation's refund and Sovereign's Genesis'
  replacement must observe it).
0.10.0 Milestone 13: Combat Content Completion & Specification Audit 2026-08-10

Max-stat modifier channels (D-545): stat.max_hp / stat.max_power

Full changelog entry (verbatim, engineering detail)
### Added
- Max-stat modifier channels (D-545): `stat.max_hp` / `stat.max_power`
  modifier-backed; effective max-HP/Power used by healing caps,
  percent-max damage, Rest, hp_pct, and the max-HP ultimates; current
  pools clamp to new maxima (legacy semantics).
- Ability-cost modifier channel (D-546): `ability_cost.<content_id>`
  flat/percentage modifiers applied in the resolver (validation and
  spending agree); STAT_MODIFY accepts a `target_calculation` override.
- Snapshot round-trip includes the modifier bank (D-548).
- Abilities completed (10): minazuki, subliminal_light, conqueror,
  desperation, devils_rhythm, dark_determination, heros_valor,
  aegis_protocol (partial -> ported), adaptation (blocked -> ported),
  overdose (blocked -> ported).
- Artifacts completed (3): inertia_reversal, surging_current,
  radiant_undertow (partial -> ported).
- 22 new tests (tests/unit/test_m13_completions.py): engine channels,
  per-item behavior, Mandom/Endlessly deferral regressions, canonical
  rules intact.

### Fixed
- `CombatState.from_dict` restored no modifiers (serialization gap;
  D-548).
- Percentage-modifier composition clarified as multiplicative
  (D-547) -- the completions match the legacy compounding exactly.
0.9.1 Milestone 12: Production Deployment & Operations Hardening 2026-08-10

Production configuration guards (D-541): SQLite + debug rejected in

Full changelog entry (verbatim, engineering detail)
### Added
- Production configuration guards (D-541): SQLite + debug rejected in
  production; log-level validation; Discord token `repr=False`
  (secret redaction).
- Bot startup hardening (D-542): config validation, database
  reachability (APP-104), and schema presence (APP-105) are verified
  before any Discord connection; migrations stay an explicit step.
- Graceful shutdown (D-543): close() closes Discord then disposes the
  database pool; never raises.
- `dio ready` readiness probe (D-544): config + database + registry,
  exit 0 = READY.
- Containerization: Dockerfile (slim, non-root, no baked secrets,
  `dio ready` healthcheck), .dockerignore, docker-compose.yml
  (PostgreSQL + optional bot profile).
- Operations docs: DEPLOYMENT.md, OPERATIONS.md, SECURITY.md,
  PRODUCTION_CHECKLIST.md.
- 24 new tests (config validation/redaction/production rules, startup
  failure modes, graceful shutdown, persistence-failure safety,
  recovery concurrency, CLI readiness, smoke bootstrap).

### Changed
- Settings.app_version now defaults to the package version (previously
  stale 0.1.0).
- Bot startup with a missing token now fails via the authoritative
  configuration validation (CFG-100).
0.9.0 Milestone 11: Discord Bot & UI Integration 2026-08-10

Application services (Discord-independent): BattleService (battle

Full changelog entry (verbatim, engineering detail)
### Added
- Application services (Discord-independent): BattleService (battle
  creation, engine-authoritative submission, turn-loop driving,
  finalization/persistence), ChallengeService (ephemeral, concurrency-
  safe accept/decline/expiry), ContentService (registry-backed browsing),
  RecoveryService (safe session recovery).
- Discord layer: ProfileCog (/profile, /character, /build), ContentCog
  (registry-driven browsing commands), PvpCog (/challenge, /recover,
  /recover_end); ChallengeView (Accept/Decline); BattleView (Attack /
  Rest / Ultimate buttons + Ability/Artifact/Consumable/Target selects
  generated from production state); battle embeds; DiscordBattleSession
  Manager (battle identity, participant ownership, per-battle action
  locks, stale/duplicate/ended rejection).
- Container wiring for all new services (bootstrap.py).
- No new database migration: sessions use the battles table status;
  players link via discord_id (D-538).

### Changed
- BattleService.submit advances the turn after a successful action
  (D-539); rejected actions never advance.

### Fixed
- Ultimate button resolves the actor's ultimate from the loadout.
0.8.1 Milestone 10: Combat Integration Hardening 2026-08-10

Action-restriction stacking now additive (legacy Seal overflow:

Full changelog entry (verbatim, engineering detail)
### Fixed
- Action-restriction stacking now additive (legacy Seal overflow:
  turns_left + 2 per activation; D-536).
- Seal curse preserves its blocked rows on re-activation while the
  target is still sealed (legacy overflow semantics; D-537).
- Stale "placeholder" comments about curse meter consumption corrected
  (the D-134 mechanism was already implemented).

### Added
- 21 audit tests (tests/unit/test_m10_audit.py): lifecycle edges
  (rejected ultimate harmony, multi-effect AFTER_ULTIMATE, ultimate
  exemption from restrictions), Decay interaction edges (lifesteal,
  ultimate heal), summon audit, strong-attack matrix, reflection
  one-chain + reflection-vs-nullification, absorb/nullify distinctness,
  complex combined-battle deterministic replay + battle isolation,
  Curse Vial with identity-only curses, hook-id uniqueness, bounded
  heavy-battle performance sanity.
- MILESTONE10_COMBAT_INTEGRATION_HARDENING_REPORT.md (readiness:
  READY FOR DISCORD INTEGRATION).
0.8.0 Milestone 9: Approved Ultimate Implementation 2026-08-10

All 16 Ultimate V1 designs implemented exactly as user-approved

Full changelog entry (verbatim, engineering detail)
### Added
- All 16 Ultimate V1 designs implemented exactly as user-approved
  (D-534): Ember Cremation, Boreal Absolute Zero, Voltaic Thunderstorm,
  Abyssal Abyssal Decree, Tidal Tsunami, Light Radiant Dawn, Arcane
  Arcane Binding, Ruin Ruin, Verdant Verdant Harvest, Noxious Pandemic,
  Physical Iron Body, Entropic Entropic Cascade, Gravitic Singularity,
  Celestial Celestial Chorus, Spectral Ghost Parade, Sanguine Blood Moon
  (`src/dio/content/ultimates/__init__.py`; `spec_status=canonical_v1`).
- Approved Harmony requirements as content costs (60/80/100 per the
  approved table); activation spends + resets Harmony (D-510).
- 4 new ultimate-support statuses (status.ultimate_absolute_zero,
  status.ultimate_iron_body, status.ultimate_entropic_cascade,
  status.ultimate_blood_moon); status count 42 -> 46.
- 40 new tests (tests/unit/test_m9_ultimates.py): per-ultimate behavior,
  activation requirement, harmony consumption, affinity gating, target
  validation, damage/healing, status effects, curse interaction,
  Nullification, DR, Absorb, Reflection, dodge, summon interaction,
  deterministic replay, battle isolation.
- MILESTONE9_ULTIMATE_IMPLEMENTATION_REPORT.md.
- MILESTONE8_ULTIMATE_PROPOSALS.md status updated to CANONICAL — VERSION
  1 (approved 2026-08-10).

### Changed
- D-528 test expectations updated from the pre-approval identity-only
  state to the approved canonical state (documented expectation change,
  not a weakened assertion).

### Fixed
- (none — no regressions; 638 baseline tests unchanged and passing)
0.7.0 Milestone 8: Content Specification Finalization & Ultimate Design 2026-08-10

D-524: ported Ability/Artifact content remains DIVINE.

Full changelog entry (verbatim, engineering detail)
### Added
- User decisions D-524..D-528 recorded and regression-tested:
  - D-524: ported Ability/Artifact content remains DIVINE.
  - D-525: Mandom stays DEFERRED (no state-restore engine).
  - D-526: Endlessly stays DEFERRED (no extra-turn engine).
  - D-527: Decay uses the production damage pipeline (D-521 CONFIRMED).
  - D-528: Ultimate effects may be drafted as proposals only.
- Engine capabilities (documented extensions):
  - Status-attached hooks + status application effects
    (StatusDefinition.declare_hooks / apply_effects; D-529).
  - Ability-cost discount statuses (StatusDefinition.ability_cost_discount;
    D-530) — Overclock Chip.
  - Last-action summary + last-curse-inflicted tracking on
    CombatantState (D-531) — Spectre curse, Echo Charm.
- Consumables completed: Iron Ward, Ghost Draft, Vampiric Thorn,
  Overclock Chip, Stat Tonic, Cleansing Draft, Focus Shard, Echo Charm
  (CONSUMABLE-001/003 resolved).
- Curses completed: Permafroze (status-attached doubling), Echo
  (engine-integrated spread), Spectre (last-action replay) — 12 of 16.
- Abilities: King Crimson's same-ability-twice lock completed via
  status.kc_lock (56 PORTED).
- Artifacts: Hexward Sanctum (per-turn meter decay) and Scarecrow's Toll
  (full meter cleanse) completed (23 PORTED).
- New shared statuses: status.curse_permafroze, status.curse_echo
  (rebuilt), status.kc_lock (42 total).
- MILESTONE8_ULTIMATE_PROPOSALS.md — 16 Ultimate design proposals,
  all PENDING USER APPROVAL (D-528).
- 37 new tests (tests/unit/test_m8_decisions.py, test_m8_content.py).

### Changed
- StatusManager.apply returns (active, created); status-attached hooks
  and application effects bind only for new instances (no duplicate
  firing on stacking).
- Action resolver applies and consumes ability-cost-discount statuses.

### Fixed
- (none — no regressions; 600 baseline tests unchanged and passing)
0.6.0 Milestone 7: Combat Completion & Specification Finalization 2026-08-10

Decay conversion hook (D-521): the canonical 60% healing->damage

Full changelog entry (verbatim, engineering detail)
### Added
- **Decay conversion hook** (D-521): the canonical 60% healing->damage
  rule is implemented end-to-end (curse.decay activation ->
  status.curse_decay -> engine conversion in the healing resolver,
  data-driven via StatusDefinition.healing_conversion); CURSE-MEC-002
  and DECAY-HOOK-001 resolved.
- **Action restrictions** (D-520): EffectType.ACTION_RESTRICT + the
  action_restricted event; enforced by the resolver (docs/18 §12);
  Seal curse, Silent Reckoning stagger and Scarecrow's Toll punish now
  functional; Right of Conquest gains rage on restriction and shatters
  restrictions at rage>=70.
- **One action per turn** (D-519): the resolver enforces the documented
  turn structure (docs/18 §9); rejected actions do not consume the turn.
- **Strong-attack derivation** (D-522): a landed non-critical hit above
  the attacker's power is "strong" (DOC-002 resolved); Gold Experience
  Requiem's strong defense triggers correctly.
- **Tests**: 30 new (600 total; 83.49% coverage) -- Decay conversion,
  restrictions, one-action-per-turn, exactly-once AFTER_* events, dodge
  integrity, strong derivation, nullify/absorb/reflect distinction,
  battle isolation, deterministic replay with passives, pacing
  measurements.

### Changed
- Version 0.5.0 -> 0.6.0; status count 39 -> 40 (status.curse_decay);
  implemented curses 7 -> 9 (Decay, Seal).
- Tests updated to model real turns (one action per turn) -- no
  assertions weakened.

### Documentation
- DECISIONS D-519..D-523, KNOWN_ISSUES (CURSE-MEC-001/002, DECAY-HOOK-001,
  DOC-002, PORT-DEV-001, M7-GAP-001, M7-USER-001), TASKS/ROADMAP/
  AI_MEMORY updated, MILESTONE7_COMBAT_COMPLETION_REPORT.md.
0.5.0 Milestone 6: HOK-001 Content Port 2026-08-10

HOK-001 adapter (dio/content/legacy/): the translation layer from

Full changelog entry (verbatim, engineering detail)
### Added
- **HOK-001 adapter** (`dio/content/legacy/`): the translation layer from
  the preserved prototype to the production engine -- legacy name maps
  (16 curses, 28 statuses), effect-building helpers (damage/healing/
  curse/status/stat/energy/summon), deterministic RNG passthroughs, and
  the definitive 79+41 content inventory (`inventory.py`) with per-item
  PORTED / PARTIAL / BLOCKED status and deviation notes.
- **Ported content**: 70 of 79 abilities and 34 of 41 artifacts
  registered as DIVINE content (55+21 PORTED, 15+13 PARTIAL with
  documented deviations, 9+7 BLOCKED with exact reasons); 28 supporting
  legacy statuses (shared infrastructure).
- **Engine extensions (consumer-justified, D-512)**: 9 new canonical
  events/hooks (dodge, curse buildup/activation/before, status apply
  before, stat modify before/after, energy gain/spent/lost/before);
  AFTER_ATTACK/ABILITY/ULTIMATE/CONSUMABLE/REST events now emitted with
  outcome data; `ActionType.ARTIFACT` (active artifact activation at the
  Artifact stage); dynamic costs (`effective_costs`) + one-use
  `_temp_discount`; negative curse buildup = meter reduction; owner-
  scoped content instances; ability hook binding; kill-by-crit / last-
  hit-almighty attribution; `prevent_dodge` before-attack flag.
- **Tests**: 154 new (570 total; 83.28% coverage) covering the adapter,
  engine extensions, every ported ability/artifact, deep artifact
  branches, and cross-system rules (summon/artifact restrictions,
  nullification, race separation, determinism, harmony/energy
  correctness).

### Changed
- Version 0.4.2 -> 0.5.0; registry counts: 70 abilities, 34 artifacts,
  39 statuses (production content, DIVINE); inventory-driven.
- Resource-event decision (RES-EVT-001) documented exception for energy
  events.

### Documentation
- DECISIONS D-511..D-518, KNOWN_ISSUES HOK-EXT-001/PORT-DEV-001/
  DECAY-HOOK-001, TASKS/ROADMAP/AI_MEMORY updated,
  MILESTONE6_HOK001_CONTENT_PORT_REPORT.md.
1.0.0 Documentation Baseline

docs/01 – docs/09: Core engine architecture, combat design, registry, hooks, status effects, formulas, balance philosophy.

Full changelog entry (verbatim, engineering detail)
### Added
- `docs/01` – `docs/09`: Core engine architecture, combat design, registry, hooks, status effects, formulas, balance philosophy.
- `docs/10` – `docs/12`: Combat Intelligence, Theory Engine, AI Design Philosophy.
- `docs/13` – `docs/22`: Database schema, testing, security, command architecture, content pipeline, event system, AI training pipeline, progression, analytics, matchmaking.
- `docs/23` – `docs/48`: Full AI ecosystem — decision engine, counterplay discovery, knowledge network, self-play, reinforcement learning, personality modeling, coaching, live assistance, memory management, explainability, balance analysis, content generation, tournament analysis, anti-cheat, world simulation, autonomous research, multi-agent collaboration, communication, long-term evolution, dataset governance, performance optimization, failure handling, developer administration, user assistant, competitive ranking, future expansion.
- `docs/49`: Complete AI Architecture Integration Document.
- `docs/50`: AI Development Roadmap & Implementation Priority.

---
Unreleased Versioning Notes

This changelog tracks documentation and specification versions, not necessarily deployed code versions.

Full changelog entry (verbatim, engineering detail)
- This changelog tracks **documentation and specification** versions, not necessarily deployed code versions.
- Code implementation versions should be tracked separately once implementation begins, per `docs/50_AI_Development_Roadmap_Implementation_Priority.md`, Section 11.
- Major AI behavior changes must include migration notes and rollback procedures per `docs/41_AI_Long_Term_Evolution_Self_Improvement_Framework.md`.


---
0.18.0 Milestone 30.5: Seven Deadly Sins superbosses 2026-08-12

MINOR bump (D-605): Lucifer, Mammon, Asmodeus, Nemesis,

Full changelog entry (verbatim, engineering detail)
- **MINOR bump (D-605):** Lucifer, Mammon, Asmodeus, Nemesis,
  Beelzebub, Satan, Belphegor — Divine superbosses, each with a unique
  Divine Law implemented entirely through the existing hook/event
  system (no new combat subsystems; isolated to Sin ids).
- Laws: Pride (30% Power cap + Excess→All-Stats, Ascension, Challenge
  Marks, Pride Memory, Non Serviam), Greed (Buff/Artifact/Consumable
  theft, Greedy Tax, Debt Collections, Mine), Lust (redirection to
  Lust Slaves, spawn cap + Temptation, Obsession, Desire Memory,
  Ecstasy), Envy (0.5x cumulative per action, Buff Mirror, Summon
  Prohibition, Adaptation, Mirror of the Damned), Gluttony (Curse/
  Damage/Summon/Consumable consumption, Hunger→Feast, Abyssal Feast),
  Wrath (Rage, retaliation slots, execution below 50% HP, Wrath of
  God), Sloth (current-Power decay, +10pp DR per hit, Turn Drain to
  exhaustion, curse reflection, Apathy, Eternal Sleep).
- Engine (minimal, generic): BattleParticipant.sin_id (serialized),
  Sin-hook binding at battle start. No combat order/formulas/caps/
  Divine content changed.
- Tests: `tests/unit/test_m30_5_sins.py` (20). **1230 total, 80.11%
  coverage**, mypy (138), Ruff (242), build 0.18.0, ready 0, fuzz 0,
  secret 0. No deployment.