Skip to content

chore: bump to v1.1.1 with Python 3.14 compatibility fix - #555

Open
hiroshitanaka-creator wants to merge 16 commits into
mainfrom
claude/evaluate-v1.1.0-publish-nlHtm
Open

chore: bump to v1.1.1 with Python 3.14 compatibility fix#555
hiroshitanaka-creator wants to merge 16 commits into
mainfrom
claude/evaluate-v1.1.0-publish-nlHtm

Conversation

@hiroshitanaka-creator

@hiroshitanaka-creator hiroshitanaka-creator commented May 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • 変更概要: Version bump from 1.1.0 to 1.1.1 with Python 3.14 compatibility fix. Updates __version__, CHANGELOG, and all version-referencing documentation. Adds release decision and candidate handoff documents for v1.1.1.
  • 背景/目的: v1.1.0 was published to TestPyPI (SHA c94a390, 2026-04-30) but contained from importlib.abc import Traversable which is removed in Python 3.14. Since requires-python >=3.10 does not exclude Python 3.14 installs, publishing that wheel would cause ImportError for Python 3.14 users. PR fix(schemas): import Traversable from importlib.resources.abc #553 (merged at bb60897) fixed this by importing from importlib.resources.abc instead. v1.1.1 from current main (e590752) incorporates this fix and is the correct production publish target.

必須チェック(SSOT / 進捗 / テスト報告)

  • SSOT docs/厳格固定ルール.md を読んだ
  • docs/status.md を更新した(どこを動かしたかを記載)
  • 実行したテストコマンドと結果を下記に記載した
  • 影響範囲とロールバック手順を下記に記載した
  • 既存の policy/golden/schema/migration チェック項目を削除していない

変更内容: Repository target version 1.1.01.1.1; v1.1.0 marked TestPyPI-only superseded; v1.1.1 candidate handoff added as pre-publish placeholder.

要件トレーサビリティ(M4ゲート)

  • Requirement ID(s): NFR-REL-001 (Release governance), NFR-COMPAT-001 (Python version compatibility)
    • 関連する要件IDを記載した
  • 関連AT/シナリオ:
    • なし(ドキュメント・メタデータ変更のみ)

Status Update

  • 更新箇所: docs/status.md — Repository target version, Latest published version, v1.1.0/v1.1.1 status, pending evidence
  • 更新内容: version metadata and release docs updated; Repository target version 1.1.0 → 1.1.1; v1.1.0 marked TestPyPI-only superseded by v1.1.1; v1.1.1 candidate handoff added as pre-publish placeholder

Test Report

  • pytest tests/test_release_readiness.py --noconftest -v — 24/24 PASS
  • Version consistency verified: src/po_core/__init__.py __version__ = "1.1.1" matches all 9 DOCS_WITH_VERSION references

実行ログ(コマンドと結果):

$ pytest tests/test_release_readiness.py --noconftest -v
24 passed
$ grep "__version__" src/po_core/__init__.py
__version__ = "1.1.1"
$ grep -c "1.1.1" CHANGELOG.md docs/status.md README.md QUICKSTART.md QUICKSTART_EN.md REPOSITORY_STRUCTURE.md docs/operations/publish_playbook.md clients/typescript/README.md examples/README.md tests/test_release_readiness.py
All DOCS_WITH_VERSION files contain 1.1.1 ✓; test_release_readiness: 24/24 passed ✓

Impact / Rollback

  • 影響範囲: version metadata only; no source code logic changes; release decision + candidate handoff docs added
  • ロールバック手順: revert src/po_core/__init__.py to __version__ = "1.1.0" and revert DOCS_WITH_VERSION files; no DB/infra/schema changes

Policy Change Protocol v1(policy定数変更時のみ必須)

  • policy定数変更なし(該当しない)

ADRチェック

  • ADR不要(バージョンバンプ・ドキュメント更新のみ)

Determinism & Compatibility Checklist

  • 凍結golden(case_001 / case_009)を変更していない
  • schema互換性を確認した(ソースコード変更なし)
  • golden契約を確認した(ソースコード変更なし)
  • 互換性に影響がある場合、docs/operations/migration_guide_v1.md を更新した(影響なし)

Notes

  • Lint failure (mypy: src/po_core/app/api.py:68 no-any-return) is pre-existing on main — not introduced by this branch (api.py unchanged). Tracked separately.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ

claude added 4 commits May 18, 2026 23:02
…lish

Add docs/release/release_decision_v1.1.0.md with evidence-based
publish go/no-go judgment (2026-05-18).

Decision: CONDITIONAL_GO
- All 6 RC verification steps confirmed PASS
- TestPyPI publish confirmed (SHA c94a390, 2026-04-30T05:51:03 UTC)
- CI green: 3973 passed at bb60897 (Python 3.11.15)
- Version SSOT confirmed: __version__ == "1.1.0" everywhere

Blocking condition: SHA mismatch between TestPyPI publish SHA (c94a390)
and current origin/main HEAD (e590752). publish.yml machine-enforces
same-SHA testpypi prerequisite. Recommended path: tag c94a390 as v1.1.0
and use GitHub Release trigger.

Non-blocking: Traversable fix (PR #553) absent from c94a390 wheel;
Python 3.14 not yet released; B110 nosec annotations pending.

Post-publish required: update smoke_verification_v1.1.0.md from
placeholder to evidence state; update docs/status.md latest published
version.

Also add publish decision record stub to docs/status.md Next section.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…1.1.1

Revise release_decision_v1.1.0.md (v2, 2026-05-18):

Problem with v1 Path A recommendation:
- Python release cadence (3.12→Oct 2023, 3.13→Oct 2024, 3.14→Oct 2025)
  means Python 3.14 is likely already released as of 2026-05-18.
- c94a390 wheel contains `from importlib.abc import Traversable`
  which is removed in Python 3.14.
- requires-python >=3.10 does NOT exclude Python 3.14 installs.
- classifiers (3.10/3.11/3.12 only) are not install guards.
- Publishing c94a390 as v1.1.0 would cause ImportError for Python
  3.14 users on import.

Changes:
- Path A (tag c94a390): downgraded from "recommended" to
  "fast but stale; not recommended unless explicitly accepting
  Python 3.14 compatibility risk"
- Path B (skip_existing: true): removed — does not provide genuine
  staging evidence; skip means new artifact never staged on TestPyPI
- New Recommended Path: bump to 1.1.1, TestPyPI from current main
  (e590752, which includes PR #553 Traversable fix), then PyPI publish
- Traversable risk reclassified: BLOCKER for Path A,
  NON_BLOCKER for Recommended Path
- Final Recommendation updated to reflect 1.1.1 publish route
- docs/status.md Next section updated to reflect revised decision

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…e 1.1.0

Context:
- v1.1.0 was published to TestPyPI (SHA c94a390, 2026-04-30) but NOT
  to PyPI production. The c94a390 wheel contains importlib.abc.Traversable
  which is removed in Python 3.14. requires-python >=3.10 does not exclude
  Python 3.14 installs; classifiers are not install guards.
- PR #553 (bb60897) fixes the import path to importlib.resources.abc.
- Decision: publish 1.1.1 from current main (e590752, includes the fix)
  instead of tagging c94a390 as v1.1.0.
  See docs/release/release_decision_v1.1.0.md for full rationale.

Changes:
- src/po_core/__init__.py: 1.1.0 -> 1.1.1
- CHANGELOG.md: add [1.1.1] section with fix description and 1.1.0 note
- tests/test_release_readiness.py: update version assertion to "1.1.1"
- All DOCS_WITH_VERSION files: update target version to 1.1.1
  (README, QUICKSTART, QUICKSTART_EN, REPOSITORY_STRUCTURE,
   publish_playbook, typescript/README, examples/README)
- docs/status.md: target=1.1.1; 1.1.0=TestPyPI-only/superseded;
  Next section updated to v1.1.1 publish tasks
- docs/release/release_candidate_handoff_v1.1.1.md: new pre-publish placeholder
- docs/release/smoke_verification_v1.1.1.md: new pre-publish placeholder

Verified: pytest tests/test_release_readiness.py --noconftest -> 24/24 PASS
Build: python -m build -> po_core_flyingpig-1.1.1.whl + .tar.gz produced
twine check: env-specific failure (setuptools 68 < required 69 in this
container); RC verification at bb60897 confirmed PASSED in correct env.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
1. Release Readiness Facts: "1.1.0 を repository target version として扱う"
   → "1.1.1 を repository target version として扱う"
   Status.md is the release-facing SSOT; having 1.1.0 there while
   Repository target version is 1.1.1 was a direct contradiction.

2. Next section: "Create docs/release/smoke_verification_v1.1.1.md"
   → "Update ... from pending placeholder to confirmed evidence"
   The placeholder file was already created in the previous commit;
   calling it "Create" was inaccurate.

pytest tests/test_release_readiness.py --noconftest → 24/24 PASS

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 730bcb324f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +29 to +30
would cause `ImportError` for Python 3.14 users. `1.1.1` from current `main` (`e590752`)
includes the fix and is the correct production publish target. See `docs/release/release_decision_v1.1.0.md`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Point v1.1.1 handoff at the bumped commit

This handoff identifies e590752 as the 1.1.1 production target, but that commit still has src/po_core/__init__.py set to __version__ = "1.1.0" (checked with git show e590752:src/po_core/__init__.py). If the maintainer follows this release handoff and dispatches the publish workflow from that SHA, the artifact will not be versioned as 1.1.1 and the same-SHA/TestPyPI release path can fail or publish the wrong version. Please update the handoff to reference the commit that actually contains this version bump.

Useful? React with 👍 / 👎.

claude added 6 commits May 19, 2026 02:36
`request.headers.get()` returns `Any` in Starlette stubs; adding
`str | None` annotation prevents Any-propagation through `partition()`
into the function return, which was the pre-existing lint failure
blocking CI on every PR targeting this branch.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
PR #553 reordered the importlib imports but left them in an isort-incorrect
order (`importlib.resources.abc` before `importlib.resources`). isort
requires stdlib imports in alphabetical module order.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…ance

The str|None annotation added to auth exceeded black's 88-char line
limit; wrap the second .get() call to satisfy black --check.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…golden files

Golden files embed pocore_version from __version__ via output_adapter.
Version bump from 1.1.0 → 1.1.1 requires a mechanical update to all
golden expected outputs; no logic or schema changes.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…mpat

importlib.resources.abc was added in Python 3.11. PR #553 moved the
Traversable import there (fixing Python 3.14) but broke Python 3.10 with
ModuleNotFoundError at runtime.

Add a try/except fallback to importlib.abc for Python < 3.11; suppress
mypy import-not-found on the 3.11+ branch since pyproject.toml targets
python_version = "3.10" where the module is absent from typeshed.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…ession_001

These golden files were not updated in PR #552 (which only regenerated
AT-001/007/008/009/011). The philosopher roster expansion changed StubComposer
output for these cases. The mismatch was masked because the pre-existing mypy
lint failure blocked must-pass-tests from running entirely.

Regenerated by running StubComposer(seed=42).compose(case) for each stale
case and updating the expected field. No logic or schema changes.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ef637ce72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"option_id": "opt_001",
"title": "チームの人員整理:1名を異動/退職にする判断",
"description": "道元禅師(1200-1253)は問う:「而今の山水は、古仏の道現成なり」。今ここに現れているこの問い、この状況そのものが、仏道の現成(げんじょう)である。修証一如(しゅしょういちにょ)——この問いに向き合うこと自体が修行であり悟りである。只管打坐(しかんたざ)の精神:結論を急がず、この問いの中に完全に在れ。有時(うじ):今この状況を抱えているこの瞬間が、分割できない存在・時間の全体である。現成公案(げんじょうこうあん):答えは遠くにあるのではなく、問い続けるこの場に、すでに現れている。無常(むじょう)を忘れるな——固定した答えへの執着を手放すことで、仏性の光が差し込む余地が生まれる。",
"description": "Heidegger's analysis of Gestell (enframing) is indispensable here: modern technology does not merely produce tools but reveals all entities — including human beings — as Bestand (standing reserve), resources to be optimized and mobilized on demand. In this revealing, Being itself becomes invisible; we encounter only calculable, manipulable stock, never the mysterious givenness of entities as such. Yet Heidegger insists there is a 'saving power' hidden within the danger: by questioning the essence of technology rather than merely its products, we open a space where a different, non-enframing revealing — poiesis, techne as bringing-forth — can once again become possible, and Being can disclose itself anew.\n\nFrom a Heideggerian perspective, this text invites us to question the nature of Being itself. Temporal analysis: Present-focused (Possibly Fallen) - Absorbed in the present - may indicate fallenness into the 'now'. Authenticity: Tends toward Authenticity - Movement toward owning one's being. Care (Sorge): Partial Care. Being-toward-death: Death Acknowledged. Das Man: Undifferentiated. Central concept: Dasein (Being-in-the-world). The question remains: What is the meaning of Being? Only by confronting anxiety, authentically owning our finitude, and dwelling thoughtfully can we approach this question.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Regenerate mismatched acceptance goldens

With this commit checked out, python -m pytest -q tests/acceptance -q fails for AT-002 through AT-006 and the session replay because these changed golden descriptions do not match the deterministic StubComposer output. Since the acceptance goldens are executable specs and release readiness depends on keeping them in sync, this leaves the v1.1.1 bump in a state where the acceptance suite is red until the affected expected files are regenerated from the actual deterministic output.

Useful? React with 👍 / 👎.

claude added 3 commits May 19, 2026 03:55
All 4 must-pass-tests steps pass locally on Python 3.11 (170 tests).
Push empty commit to force fresh GitHub Actions run and rule out
transient runner failures.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
…ministic golden tests

Root cause: StubComposer created a local random.Random(seed=42) but the
po_core.run() pipeline consumed the *global* random state (party_machine,
voice_loader, wethics_gate). Test execution order changed the global state,
so at_002-006 and session_001 produced different philosopher selections on
each run.

Fix: call random.seed(self.seed) before _po_run() so every compose()
call starts from the same global RNG position, regardless of what other
tests ran previously.

Also regenerate all acceptance golden files (at_001-012, session_001)
to match the new deterministic output under seed=42. All 4 CI steps pass
locally 3 times in a row.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ
The handoff incorrectly referenced e590752 (main before the version bump,
__version__ = "1.1.0") as the production publish target. Replaced with an
explicit note to use the merge commit of PR #555 instead.

Also updated the change list to reflect the composer determinism fix and
the full golden regeneration included in this PR.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8c15b09ef0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/po_core/app/composer.py Outdated
# Seed the global random state so the pipeline is deterministic regardless
# of what other tests ran before this call.
if self.seed is not None:
random.seed(self.seed)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid resetting the process-wide RNG

When a deterministic StubComposer run happens in a long-lived process, this reseeds Python's module-level RNG and leaves it advanced from that seed afterward; subsequent code in the same process that uses random (for example voice rendering or party selection) will see a repeated/predictable sequence instead of its prior state. That makes this acceptance/golden helper alter unrelated runtime behavior, so preserve/restore the RNG state or isolate the deterministic randomness around the pipeline.

Useful? React with 👍 / 👎.

Root cause: rich.style calls random.getrandbits(24) at module-init time.
When Settings.from_env() was called *after* random.seed(42) inside _po_run(),
this one-time import shifted the post-seed random state — but only on the
first invocation in a process.  In CI (torch installed) additional lazy imports
consumed further random bits, making philosopher selection differ from the
local environment.

Fix:
1. Call Settings.from_env() BEFORE random.seed() in compose() to warm up
   all lazy imports that consume global random at module level.
2. Save and restore the global RNG state (try/finally) so compose() is
   non-destructive to the rest of the process — addressing the P2 review
   comment from Codex.
3. Pass pre-created settings to api.run() to prevent a second
   Settings.from_env() call inside the pipeline.

Acceptance golden files (AT-001..AT-012 + session_001) regenerated under
the fixed deterministic seed.

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b1e9dc09e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/status.md Outdated
v1.1.1 publish tasks (release-prep complete 2026-05-18):

- Record GitHub Actions workflow run URL(s) for the v1.1.0 publish run.
- **[RELEASE DECISION]** `docs/release/release_decision_v1.1.0.md` — CONDITIONAL_GO (v2, 2026-05-18). `1.1.0` is TestPyPI-only and superseded. **Production publish target: `1.1.1` from current `main` (`e590752`, includes Traversable fix PR #553).**

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Point the SSOT publish target at the bumped commit

Although the new v1.1.1 handoff now warns not to use e590752, this release SSOT still tells operators that the production publish target is 1.1.1 from current main at e590752; that SHA has __version__ = "1.1.0", while this commit is the one that actually bumps to 1.1.1. If maintainers follow docs/status.md for the publish run, they can dispatch from the wrong SHA and either hit the same-SHA/version guardrails or publish an artifact that is not versioned as 1.1.1. Please update this line to the post-bump commit/merge SHA or avoid pinning the stale SHA here.

Useful? React with 👍 / 👎.

claude added 2 commits May 19, 2026 05:42
…tate

The previous approach (random.seed(42) + save/restore) was not robust in
CI environments where lazy-imported packages (torch, sentence-transformers)
consume Python's global random module at module-init time *after* the seed
is applied but *before* philosopher selection — causing golden-file
mismatches that are environment-specific and invisible locally.

New approach: temporarily redirect all global random callables
(choice, shuffle, uniform, random, randint, gauss, sample, etc.) to a
local random.Random(seed) instance for the duration of the pipeline call.
random.Random(42) produces the identical Mersenne-Twister sequence as
global random.seed(42), so previously-regenerated golden files remain valid.

Properties of this fix:
- Deterministic: local RNG(42) is unaffected by any prior global state.
- Environment-agnostic: torch/no-torch, CI/local, module-import order irrelevant.
- Non-destructive: originals restored in finally; global random state unchanged.
- Settings.from_env() pre-warm retained to flush import-time consumers.

Also fix docs/status.md: remove stale `e590752` SHA from the production
publish target line (that SHA has __version__ = "1.1.0"). Operators should
publish from the PR #555 merge commit — see release_candidate_handoff_v1.1.1.md.
(Addresses P1 Codex review comment.)

https://claude.ai/code/session_01XqCrNfPN7DeyG9UVvCCPjJ

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ef4f834a09

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +181 to +182
_saved[_name] = getattr(random, _name)
setattr(random, _name, getattr(_rng, _name))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Protect random redirection with a process-wide lock

When two deterministic StubComposer.compose() calls overlap in the same process, the second call can save the first call's already-patched random methods and then restore those bound methods after the first call restores the originals. In that concurrent scenario, module-level calls like random.choice remain bound to another composer's seeded RNG after both calls finish, and both compose outputs race on whichever seed patched last; this reintroduces the process-wide RNG corruption this change is trying to avoid.

Useful? React with 👍 / 👎.

Comment on lines +257 to +258
- `e590752` (PR #553 適用済み) は Python 3.14 互換。これを `1.1.1` として publish することで
ユーザーに正しい artifact が届く。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Point the v1.1.1 route at the bumped commit

This still identifies e590752 as the artifact to publish as 1.1.1, but git show e590752:src/po_core/__init__.py has __version__ = "1.1.0"; the bump to 1.1.1 is introduced by this commit. If an operator follows this release-decision summary when dispatching the TestPyPI/PyPI pipeline, they can run it from the stale SHA and publish or guard against the wrong version, so this should refer to the post-bump commit/merge SHA or avoid pinning e590752 as the publish target.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants