From 01515dc38a608deea87e73d3d81d3373e935c734 Mon Sep 17 00:00:00 2001 From: Dominikus Nold Date: Sat, 29 Aug 2026 22:15:41 +0200 Subject: [PATCH 1/2] fix(review): preserve user-scoped module installs --- docs/agent-rules/20-repository-context.md | 2 +- openspec/CHANGE_ORDER.md | 3 +- .../.openspec.yaml | 2 + .../TDD_EVIDENCE.md | 29 +++++++++++++ .../design.md | 21 ++++++++++ .../proposal.md | 37 ++++++++++++++++ .../requirements-evidence.yaml | 42 +++++++++++++++++++ .../specs/agent-governance-loading/spec.md | 20 +++++++++ .../tasks.md | 26 ++++++++++++ src/specfact_cli_modules/dev_bootstrap.py | 5 ++- tests/unit/test_dev_bootstrap.py | 32 ++++++++++++-- .../test_local_bundle_source_alignment.py | 2 +- 12 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/.openspec.yaml create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/TDD_EVIDENCE.md create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/design.md create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/proposal.md create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/requirements-evidence.yaml create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md create mode 100644 openspec/changes/module-scope-02-preserve-user-installs/tasks.md diff --git a/docs/agent-rules/20-repository-context.md b/docs/agent-rules/20-repository-context.md index 63b5805a..7a246b3f 100644 --- a/docs/agent-rules/20-repository-context.md +++ b/docs/agent-rules/20-repository-context.md @@ -78,4 +78,4 @@ In this checkout: - Prefer **`specfact module init --scope project --repo .`** (and project-scoped installs) so bundled modules live under the repo, not only under user scope. - **`SPECFACT_MODULES_REPO`** is set to the modules repo root for every **`hatch run`** (`pyproject.toml` env-vars) and via **`apply_specfact_workspace_env`** from `specfact_cli_modules.dev_bootstrap` (also used by `ensure_core_dependency`, pytest `conftest`, and `scripts/pre_commit_code_review.py`). **`SPECFACT_REPO_ROOT`** defaults to the resolved sibling/core specfact-cli checkout when discoverable. -- If you still see a precedence warning for a module id, remove the stale user copy: **`specfact module uninstall --scope user`**, then confirm with **`specfact module list --show-origin`**. +- A user-scoped copy shadowed here remains installed and available outside this repository. Normal precedence requires no uninstall or cleanup action; use **`specfact module list --show-origin`** only when you need to inspect the effective source. diff --git a/openspec/CHANGE_ORDER.md b/openspec/CHANGE_ORDER.md index 631aef59..d284a2e3 100644 --- a/openspec/CHANGE_ORDER.md +++ b/openspec/CHANGE_ORDER.md @@ -7,7 +7,7 @@ must be read together with the core repo change order in `nold-ai/specfact-cli`. | Bucket | Count | Location | |---|---:|---| -| **Active** | 19 | [`openspec/changes/`](changes/) | +| **Active** | 20 | [`openspec/changes/`](changes/) | | **Parked** | 16 | [`openspec/parking-lot/`](parking-lot/) | | **Archived** | 49 | [`openspec/changes/archive/`](changes/archive/) | @@ -56,6 +56,7 @@ This track is first because no changed-scope assurance claim is trustworthy unti | Order | Change folder | GitHub # | Positioning | Blocked by | |---:|---|---|---|---| +| 0 | `module-scope-02-preserve-user-installs` | [#452](https://github.com/nold-ai/specfact-cli-modules/issues/452) | Preserve user-scoped modules when project-local sources shadow them; remove destructive review/bootstrap guidance | none; paired core [#699](https://github.com/nold-ai/specfact-cli/issues/699) is coordinated but independently mergeable | | 1 | `code-review-14-scope-truth-and-differential-enforcement` | [#416](https://github.com/nold-ai/specfact-cli-modules/issues/416) | Resolve worktree/index/range/full scope explicitly; compare pinned merge-base/head analyses; authenticate one target-tip project-runtime layer for both snapshots; fail closed on unknown scope, runtime provenance, or analyzer coverage | accepted planning PR [#413](https://github.com/nold-ai/specfact-cli-modules/pull/413); paired core adoption is downstream after the signed release | The immutable C14 compatibility smoke establishes core 0.55.1 as the minimum: lightweight tag `v0.55.1`, full commit `b1e517e60e669eaba15a18ecfa83ef5a9df65276`, and full tree `47984be5434d7ae65ed6908bf525a32053290337`. Runtime metadata therefore uses `>=0.55.1,<1.0.0`: the ceiling is required because recursive installation includes Codebase and Requirements modules whose current manifests reject core 1.x. Current paired-core validation exercises compatible versions above the minimum; a routine compatible core update within the dependency graph does not require a module metadata release. Remove the ceiling only after widening and validating the required dependency graph. This correction supersedes C14's exact-only admission wording without changing its frozen provenance identities or historical evidence. diff --git a/openspec/changes/module-scope-02-preserve-user-installs/.openspec.yaml b/openspec/changes/module-scope-02-preserve-user-installs/.openspec.yaml new file mode 100644 index 00000000..50adc910 --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-08-29 diff --git a/openspec/changes/module-scope-02-preserve-user-installs/TDD_EVIDENCE.md b/openspec/changes/module-scope-02-preserve-user-installs/TDD_EVIDENCE.md new file mode 100644 index 00000000..4e735943 --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/TDD_EVIDENCE.md @@ -0,0 +1,29 @@ +# TDD Evidence + +## Failing Before + +- `hatch run pytest tests/unit/test_dev_bootstrap.py tests/unit/test_local_bundle_source_alignment.py -q` + - Result: FAIL before production edits (`2 failed, 11 passed`). + - The new bootstrap and repository-guidance assertions could not find the required preservation language; both existing surfaces still prescribed a user-scope uninstall. + +## Passing After + +- `hatch run pytest tests/unit/test_dev_bootstrap.py tests/unit/test_local_bundle_source_alignment.py -q` + - Result: PASS (`13 passed`). + - The bootstrap and repository rule surfaces now preserve user-scoped installations, and the local import-isolation test remains green under its accurate in-memory eviction name. + +## Quality Gates + +- `hatch run format`: PASS (1,229 files unchanged). +- `hatch run type-check`: PASS (0 errors, 0 warnings). +- `hatch run lint`: PASS (Pylint 10.00/10). +- `hatch run yaml-lint`: PASS (seven manifests plus registry). +- `hatch run check-bundle-imports`: PASS. +- `hatch run verify-modules-signature --payload-from-filesystem --enforce-version-bump --allow-missing-public-key`: PASS for all seven modules. No signed payload or manifest changed, so no module version bump is required. The strict local-key form was also attempted and stopped only because this worktree does not contain the public key. +- `hatch run contract-test`: PASS (`28 passed, 1753 deselected`). +- Staged Requirements evidence gate at maturity `planned`: PASS with schema-v2 mappings for all changed scenarios and exact pytest selectors. +- `hatch run smart-test`: reached the full suite with one failure in `test_capsule_runtime_loads_the_packaged_signed_lock_before_materialization`; the same failure reproduces from an isolated clean `origin/dev` worktree at `870fea3d`, so it is baseline C14/environment debt rather than a regression from this change. +- `hatch run test`: `1780 passed, 1 failed`; the only failure is the same clean-`origin/dev` capsule-runtime baseline failure. +- `hatch run specfact code review run --enforcement changed --bug-hunt --json --out .specfact/code-review.json`: PASS after replacing one changed-file `print(..., file=sys.stderr)` warning; the worktree review reported schema 1.4, score 120, zero findings, exit code 0. +- The staged commit-hook review exposed three whole-file Pylint warnings in pre-existing test helpers; they were refactored and the focused tests/lint reran green. Its remaining advisory is environment-only: the external CrossHair process cannot import `pytest` while inspecting the staged test module. +- `git diff --check`: PASS. diff --git a/openspec/changes/module-scope-02-preserve-user-installs/design.md b/openspec/changes/module-scope-02-preserve-user-installs/design.md new file mode 100644 index 00000000..06fef7f9 --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/design.md @@ -0,0 +1,21 @@ +## Overview + +Keep module precedence unchanged while removing guidance that turns normal shadowing into destructive cleanup. The modules repository only needs to describe the correct contract and protect that wording with focused tests; core owns runtime discovery and doctor output. + +## Decisions + +- Treat project-over-user shadowing as workspace-local precedence, not evidence of a stale or invalid user installation. +- State that the user copy remains installed and available in repositories without the project-scoped copy. +- Keep explicit user-initiated uninstall behavior unchanged. This change removes routine recommendations; it does not disable the command. +- Test the exact contributor-facing surfaces that caused the defect instead of adding a new runtime abstraction. +- Rename the local test bootstrap test to describe in-memory import eviction accurately. The helper changes `sys.path` and `sys.modules`; it does not delete installed files. + +## Risks + +- A user may still need to remove a genuinely unwanted duplicate. Mitigation: origin diagnostics remain available through `specfact module list --show-origin`, and explicit uninstall remains documented elsewhere. +- A wording-only regression could reintroduce destructive agent behavior. Mitigation: focused tests reject user-scope uninstall recommendations on these bootstrap surfaces. +- Core output could remain inconsistent with repository guidance. Mitigation: paired bug `nold-ai/specfact-cli#699` carries matching OpenSpec and tests. + +## Rollback + +Revert the guidance and test changes. No module data, installation state, manifest, registry row, or signature is migrated by this change. diff --git a/openspec/changes/module-scope-02-preserve-user-installs/proposal.md b/openspec/changes/module-scope-02-preserve-user-installs/proposal.md new file mode 100644 index 00000000..70ed201f --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/proposal.md @@ -0,0 +1,37 @@ +## Why + +The modules repository tells development agents to uninstall user-scoped modules when a project-local copy shadows them. Review and bootstrap workflows repeatedly follow that instruction and remove `specfact-codebase` and `specfact-code-review` from the user scope, even though project-over-user precedence is expected and the user installation is still needed in other repositories. + +## What Changes + +- Replace destructive shadow-cleanup guidance in the development bootstrap and repository rules with an explicit preservation contract. +- Explain that project scope takes precedence only inside the current repository and does not delete or invalidate the user-scoped installation. +- Add regression coverage that fails if routine bootstrap guidance recommends `specfact module uninstall ... --scope user` again. +- Clarify the local test bootstrap name so in-memory import eviction cannot be mistaken for filesystem module removal. + +## Capabilities + +### Modified Capabilities + +- `agent-governance-loading`: Repository bootstrap guidance preserves valid user-scoped module installations when project-local sources shadow them. + +## Impact + +- Affected code and guidance: `src/specfact_cli_modules/dev_bootstrap.py`, `docs/agent-rules/20-repository-context.md`, and focused unit tests. +- Paired core behavior: `nold-ai/specfact-cli#699` removes the same destructive recommendation from discovery and doctor diagnostics. +- Registry and signed module payload impact: none. No `registry/index.json`, `packages/*/module-package.yaml`, or signed module asset changes are planned. +- Published docs impact: none; the affected rule is contributor/agent guidance rather than a modules.specfact.io page. + +--- + +## Source Tracking + + +- **Parent Epic**: [#162](https://github.com/nold-ai/specfact-cli-modules/issues/162) +- **Bug Issue**: [#452](https://github.com/nold-ai/specfact-cli-modules/issues/452) +- **Paired Core Bug**: [nold-ai/specfact-cli#699](https://github.com/nold-ai/specfact-cli/issues/699) +- **Issue Relationships**: `#452` is a sub-issue of Epic `#162`; the paired core bug is a sub-issue of Feature `nold-ai/specfact-cli#353`. +- **Blocked By**: none +- **Repository**: nold-ai/specfact-cli-modules +- **Last Synced Status**: issue type, labels, assignee, parent, project assignment, In Progress status, and blocker metadata verified on 2026-08-29 +- **Sanitized**: false diff --git a/openspec/changes/module-scope-02-preserve-user-installs/requirements-evidence.yaml b/openspec/changes/module-scope-02-preserve-user-installs/requirements-evidence.yaml new file mode 100644 index 00000000..8f880e41 --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/requirements-evidence.yaml @@ -0,0 +1,42 @@ +schema_version: "2" +requirements: + openspec:module-scope-02-preserve-user-installs:agent-governance-loading:repository-bootstrap-guidance-preserves-user-scoped-modules: + rationale: "Repository and bootstrap guidance must preserve valid user-scoped installations during normal project shadowing." + stakeholder_refs: + - "nold-ai/specfact-cli-modules#452" + - "nold-ai/specfact-cli#699" + touchpoints: + - id: workspace-bootstrap-guidance + kind: source_file + locator: "src/specfact_cli_modules/dev_bootstrap.py" + - id: repository-scope-guidance + kind: documentation + locator: "docs/agent-rules/20-repository-context.md" + - id: local-source-alignment + kind: test_file + locator: "tests/unit/test_local_bundle_source_alignment.py" + verification_cases: + - case_id: MSI-MOD-001 + scenario_id: repository-bootstrap-guidance-preserves-user-scoped-modules + method: test + intent: "Prevent bootstrap guidance from recommending user-scope uninstall." + observable: "Bootstrap states that the user copy remains installed and available elsewhere." + selector: + runner: pytest + node_id: tests/unit/test_dev_bootstrap.py::test_workspace_env_guidance_preserves_user_scoped_modules + - case_id: MSI-MOD-002 + scenario_id: repository-bootstrap-guidance-preserves-user-scoped-modules + method: test + intent: "Prevent repository rules from recommending user-scope uninstall." + observable: "Repository guidance states that the user copy remains installed and available elsewhere." + selector: + runner: pytest + node_id: tests/unit/test_dev_bootstrap.py::test_repository_scope_guidance_preserves_user_scoped_modules + - case_id: MSI-MOD-003 + scenario_id: repository-bootstrap-guidance-preserves-user-scoped-modules + method: test + intent: "Keep in-memory import eviction distinct from filesystem module removal." + observable: "Local source alignment passes without deleting or uninstalling user-scoped files." + selector: + runner: pytest + node_id: tests/unit/test_local_bundle_source_alignment.py::test_enforce_local_bundle_sources_evicts_loaded_user_bundle_imports diff --git a/openspec/changes/module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md b/openspec/changes/module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md new file mode 100644 index 00000000..16ec40dd --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/specs/agent-governance-loading/spec.md @@ -0,0 +1,20 @@ +## ADDED Requirements + +### Requirement: Repository bootstrap guidance preserves user-scoped modules + +Contributor and agent bootstrap guidance SHALL treat project-over-user module shadowing as workspace-local precedence and SHALL NOT prescribe deletion of the shadowed user-scoped installation as routine cleanup. + +#### Scenario: Project module shadows a user installation + +- **GIVEN** the same module id is installed in project scope and user scope +- **WHEN** an agent loads repository bootstrap or module-scope guidance +- **THEN** the guidance states that project scope takes precedence inside the current repository +- **AND** the guidance states that the user-scoped copy remains installed and usable outside the repository +- **AND** the guidance does not recommend a user-scope uninstall merely because the copy is shadowed + +#### Scenario: Local test bootstrap evicts an imported user module + +- **GIVEN** a test process imported a bundled module from the user-scoped source path +- **WHEN** the local bundle source bootstrap realigns the test process to repository sources +- **THEN** it may remove the loaded module from in-memory import state +- **AND** it does not delete or uninstall the user-scoped module files diff --git a/openspec/changes/module-scope-02-preserve-user-installs/tasks.md b/openspec/changes/module-scope-02-preserve-user-installs/tasks.md new file mode 100644 index 00000000..e339a769 --- /dev/null +++ b/openspec/changes/module-scope-02-preserve-user-installs/tasks.md @@ -0,0 +1,26 @@ +## 1. Governance and Scope + +- [x] 1.1 Create bug issue #452 with Bug type, labels, assignee, parent Epic #162, project assignment, In Progress status, and explicit no-blocker metadata. +- [x] 1.2 Cross-link paired core bug nold-ai/specfact-cli#699 and confirm no active change owns this corrective scope. +- [x] 1.3 Add and strictly validate the paired OpenSpec change before behavior edits. +- [x] 1.4 Keep the internal wiki source mirror aligned with both active public changes. + +## 2. Tests Before Implementation + +- [x] 2.1 Add a failing regression test for non-destructive development-bootstrap guidance. +- [x] 2.2 Add a failing regression test for non-destructive repository rule guidance. +- [x] 2.3 Rename the local import-isolation test so it does not imply filesystem uninstall behavior. +- [x] 2.4 Record the failing-before command and result in `TDD_EVIDENCE.md` before production edits. + +## 3. Implementation + +- [x] 3.1 Update the development bootstrap docstring to preserve shadowed user installations. +- [x] 3.2 Update repository context guidance to explain workspace-local precedence and no-action behavior. +- [x] 3.3 Keep registry, manifests, signed module payloads, and explicit uninstall behavior unchanged. + +## 4. Evidence and Delivery + +- [x] 4.1 Run focused passing tests and record passing-after evidence. +- [x] 4.2 Run format, type-check, lint, yaml-lint, bundle-import, contract, smart-test, full test, and applicable signature gates; document reproducible `origin/dev` baseline failures. +- [x] 4.3 Run SpecFact changed-scope bug-hunt review, resolve every finding, and record fresh JSON evidence. +- [ ] 4.4 Commit with a signed Conventional Commit, push the bugfix branch, and open a PR to `dev` cross-linked to both issues and the paired core PR. diff --git a/src/specfact_cli_modules/dev_bootstrap.py b/src/specfact_cli_modules/dev_bootstrap.py index 075ae44d..b931ac0c 100644 --- a/src/specfact_cli_modules/dev_bootstrap.py +++ b/src/specfact_cli_modules/dev_bootstrap.py @@ -53,7 +53,8 @@ def apply_specfact_workspace_env(repo_root: Path) -> None: Pins ``SPECFACT_MODULES_REPO`` to the modules repo root and ``SPECFACT_REPO_ROOT`` to the resolved sibling/core specfact-cli checkout when known. Discovery then agrees with ``specfact module list --show-origin`` expectations; project ``.specfact/modules`` still wins over ``~/.specfact/modules`` - when both exist—remove stale user copies with ``specfact module uninstall --scope user``. + when both exist. The user copy remains installed and available outside this workspace, so normal + shadowing requires no uninstall or cleanup action. """ resolved = repo_root.resolve() os.environ["SPECFACT_MODULES_REPO"] = str(resolved) @@ -93,7 +94,7 @@ def ensure_core_dependency(repo_root: Path) -> int: if core_repo is None: if _installed_core_exists(): return 0 - print("Unable to resolve specfact-cli checkout. Set SPECFACT_CLI_REPO.", file=sys.stderr) + sys.stderr.write("Unable to resolve specfact-cli checkout. Set SPECFACT_CLI_REPO.\n") return 1 installed_root = _installed_core_root() diff --git a/tests/unit/test_dev_bootstrap.py b/tests/unit/test_dev_bootstrap.py index 62964870..4c5e9b36 100644 --- a/tests/unit/test_dev_bootstrap.py +++ b/tests/unit/test_dev_bootstrap.py @@ -65,6 +65,24 @@ def test_apply_specfact_workspace_env_sets_defaults(monkeypatch: pytest.MonkeyPa assert os.environ["SPECFACT_REPO_ROOT"] == str(core.resolve()) +def test_workspace_env_guidance_preserves_user_scoped_modules() -> None: + guidance = apply_specfact_workspace_env.__doc__ or "" + + assert "remains installed" in guidance + assert "available outside this workspace" in guidance + assert "module uninstall" not in guidance + + +def test_repository_scope_guidance_preserves_user_scoped_modules() -> None: + repository_root = Path(__file__).resolve().parents[2] + guidance = (repository_root / "docs" / "agent-rules" / "20-repository-context.md").read_text(encoding="utf-8") + scope_guidance = guidance.split("## SpecFact module scopes", maxsplit=1)[1] + + assert "remains installed" in scope_guidance + assert "available outside this repository" in scope_guidance + assert "module uninstall --scope user" not in scope_guidance + + def test_apply_specfact_workspace_env_without_core_repo(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None: repo_root = tmp_path / "modules-repo" repo_root.mkdir() @@ -119,9 +137,13 @@ def test_ensure_core_dependency_allows_matching_editable_core(monkeypatch: pytes core = _make_core_repo(tmp_path / "paired-core") monkeypatch.setenv("SPECFACT_CLI_REPO", str(core)) + + def _installed_core_root() -> Path: + return core.resolve() + monkeypatch.setattr( "specfact_cli_modules.dev_bootstrap._installed_core_root", - lambda: core.resolve(), + _installed_core_root, ) assert ensure_core_dependency(repo_root) == 0 @@ -136,14 +158,18 @@ def test_ensure_core_dependency_reinstalls_when_editable_core_mismatches( core_wanted = _make_core_repo(tmp_path / "core-wanted") monkeypatch.setenv("SPECFACT_CLI_REPO", str(core_wanted)) + + def _installed_core_root() -> Path: + return core_wrong.resolve() + monkeypatch.setattr( "specfact_cli_modules.dev_bootstrap._installed_core_root", - lambda: core_wrong.resolve(), + _installed_core_root, ) recorded: list[list[str]] = [] - def _fake_run(cmd: list[str], **kwargs: object) -> SimpleNamespace: + def _fake_run(cmd: list[str], **_kwargs: object) -> SimpleNamespace: recorded.append(list(cmd)) return SimpleNamespace(returncode=0) diff --git a/tests/unit/test_local_bundle_source_alignment.py b/tests/unit/test_local_bundle_source_alignment.py index 98bcda1b..db176932 100644 --- a/tests/unit/test_local_bundle_source_alignment.py +++ b/tests/unit/test_local_bundle_source_alignment.py @@ -8,7 +8,7 @@ # pylint: disable=protected-access -def test_enforce_local_bundle_sources_removes_shadowed_user_bundle_modules(monkeypatch) -> None: +def test_enforce_local_bundle_sources_evicts_loaded_user_bundle_imports(monkeypatch) -> None: user_bundle_src = str((Path.home() / ".specfact" / "modules" / "specfact-backlog" / "src").resolve()) local_bundle_src = str((test_bootstrap.MODULES_REPO_ROOT / "packages" / "specfact-backlog" / "src").resolve()) fake_module_path = f"{user_bundle_src}/specfact_backlog/backlog/commands.py" From b4749678d3ce6c02f13e7f5328ac6bade41ab22b Mon Sep 17 00:00:00 2001 From: Dominikus Nold Date: Sat, 29 Aug 2026 22:25:00 +0200 Subject: [PATCH 2/2] docs(openspec): record paired review delivery --- .../changes/module-scope-02-preserve-user-installs/tasks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspec/changes/module-scope-02-preserve-user-installs/tasks.md b/openspec/changes/module-scope-02-preserve-user-installs/tasks.md index e339a769..3286fc4f 100644 --- a/openspec/changes/module-scope-02-preserve-user-installs/tasks.md +++ b/openspec/changes/module-scope-02-preserve-user-installs/tasks.md @@ -23,4 +23,4 @@ - [x] 4.1 Run focused passing tests and record passing-after evidence. - [x] 4.2 Run format, type-check, lint, yaml-lint, bundle-import, contract, smart-test, full test, and applicable signature gates; document reproducible `origin/dev` baseline failures. - [x] 4.3 Run SpecFact changed-scope bug-hunt review, resolve every finding, and record fresh JSON evidence. -- [ ] 4.4 Commit with a signed Conventional Commit, push the bugfix branch, and open a PR to `dev` cross-linked to both issues and the paired core PR. +- [x] 4.4 Commit with a signed Conventional Commit, push the bugfix branch, and open PR #454 to `dev` cross-linked to both issues and paired core PR #700.