feat(combat): inject optional allowed-set into clean_damage_types/combatant_defenses - #8
Merged
Conversation
sligara7
force-pushed
the
l3-allowed-param
branch
from
July 29, 2026 01:28
81cf4c1 to
9ea2793
Compare
sligara7
added a commit
that referenced
this pull request
Jul 29, 2026
…10) main is currently RED on CI, and no commit caused it. The lint gate runs `ruff check src tests examples` after `pip install -e ".[dev]"`, where the extra declared an open-ended `ruff>=0.1`. CI therefore installs whatever ruff shipped most recently, and `[tool.ruff]` set only line-length/target-version — so the ENFORCED RULE SET was whatever that version happened to default to. ruff 0.16.0 widened those defaults (I/RUF/SIM/PL/UP). The result: 40 findings appeared at once — 17 import-sort (I001), 7 RUF022, plus SIM/PL/UP — in files no open PR had touched, retroactively failing work that was green when written. Verified by running 0.16.0 against unmodified `main`: 40 errors, the same failure seen on PR #8, which is therefore blocked by this and not by its own diff. Two changes, because there are two independent causes: - `ruff>=0.5,<0.17` — bound the tool on both sides so the gate is reproducible. Floor 0.5 because the rule set below uses the `[tool.ruff.lint]` table. - `[tool.ruff.lint] select = ["E4","E7","E9","F"]` — state the enforced set explicitly so it is a property of this repo, not of the installed ruff. This is the load-bearing half: without it, the next default-widening release moves the gate again regardless of any version pin. These four are what the project has actually been enforcing (ruff's historical default). Adopting import sorting or the RUF/SIM/UP families is a deliberate choice for its own commit, with its ~40 fixes reviewed — not a side effect of a dependency resolving forward. No source file is touched here. Verified: ruff 0.16.0 (what CI installs) and local ruff 0.15.15 BOTH report "All checks passed" against this commit — the point is that they now agree. pytest 1654 passed; the one failure (test_version_matches_package_metadata) is a stale editable install on the dev host, reproduces on unmodified main, and CI installs fresh. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…batant_defenses Add a keyword-only allowed: frozenset[str] = DAMAGE_TYPES to clean_damage_types and combatant_defenses. Default preserves SRD-13 behavior (backward-compatible); a caller governing its own damage-type vocabulary passes SRD-13 ∪ custom so registered types survive the filter at assembly, computed-stats read, AND live combat damage application — no split-brain. dndwright stays domain-agnostic. Bump 0.25.2 -> 0.26.0. Public API (__all__) unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXPSRe6rg8jtdAAvqZrxvf
sligara7
force-pushed
the
l3-allowed-param
branch
from
July 29, 2026 02:10
9ea2793 to
6fe1756
Compare
sligara7
added a commit
that referenced
this pull request
Jul 29, 2026
Adds the caller-governed damage-type vocabulary: clean_damage_types() and combatant_defenses() take an optional keyword-only `allowed` frozenset, so a host application that registers custom damage types can pass SRD-13 ∪ custom and have those types survive the filter at component assembly, the computed-stats read AND live combat damage application — instead of being silently dropped on one side and not the other. Default is DAMAGE_TYPES, so every existing caller is unchanged, and the public API (__all__) is untouched. (#8) Also backfills the CHANGELOG section for 0.26.0, which shipped to PyPI on 2026-07-01 with no entry — evaluate_character(components=...), recorded from #9 — and repairs the compare links, which had drifted four releases behind (they ended at v0.23.2, leaving 0.24.0 through 0.26.0 unlinked). Verified per RELEASING.md against a fresh `pip install -e ".[dev]"`, which is what makes the installed-metadata guard actually run rather than skip: - pytest: 1659 passed, 0 failed — including test_version_matches_package_metadata, which now has both version sources agreeing at 0.27.0 - ruff check src tests examples: All checks passed - python -m build: dndwright-0.27.0.{whl,tar.gz} - twine check: both PASSED - dist/ and build/ removed; CI rebuilds them Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a keyword-only
allowed: frozenset[str] = DAMAGE_TYPESparameter toclean_damage_types()andcombatant_defenses()incombat/combat.py.DAMAGE_TYPESexactly as before (backward-compatible; all existing call sites compile + behave identically).SRD-13 ∪ custom) so registered types survive the filter at component assembly, the computed-stats read, and live combat damage application.allowedcomes from). Members must be lower-cased (caller owns canonicalisation).__all__) unchanged.Why
Downstream StoryFlow v1.1.0 adds a per-universe damage-type registry. The hardcoded SRD-13 frozenset was the single chokepoint that silently dropped any custom type — and it is applied by two consumers (the character-sheet compute path AND the live-combat
combatant_defensescall). Dependency-injecting the allowed-set is the single-source-of-truth fix that avoids a split-brain (registry honored on the sheet but not in combat) and avoids duplicating the filter across consumers.Tests
tests/test_defenses_and_serialization.py: widened-vocab survival, default-unchanged back-compat, per-channel threading, and a registered type actually halving damage inapply_damage(governed at the point damage is applied, not just on the sheet).ruff check src tests examplesclean, api-contract green (__all__unchanged).Rebased onto main (2026-07-28)
This branch was cut from
v0.25.2, before 0.26.0 was released. It has been rebased onto currentmain(358eb3e, = thev0.26.0tag):0.25.2 -> 0.26.0version bump. 0.26.0 has since been released to PyPI with different content (evaluate_character(components=...), feat(rules): evaluate_character(components=...) — compose item modifiers onto the sheet #9), so this branch must not claim that number.pyproject.tomland__version__are left at main's0.26.0, in lockstep.## 0.26.0->## [Unreleased]and removed the now-duplicate empty[Unreleased]heading further down. Versioning this work is a release-time decision (next would be0.27.0— minor, since it is an additive API change).combat/combat.pyand the new tests verified content-identical to the pre-rebase commit).Release/PyPI publish remains a separate gated step per
RELEASING.md.