Skip to content

Reduce template instantiations during registration - #951

Draft
knoepfel wants to merge 5 commits into
Framework-R-D:mainfrom
knoepfel:refactor/registration-inversion
Draft

knoepfel wants to merge 5 commits into
Framework-R-D:mainfrom
knoepfel:refactor/registration-inversion

Conversation

@knoepfel

@knoepfel knoepfel commented Oct 2, 2026 •

Copy link
Copy Markdown
Member
  • Code: Replace graph_proxy and graph_registration_bundle with shared registration context, registration state, and capability-specific proxies. Keep registration operations in glue backed by registration_core.
  • Code: Update plugin registration to pass a registration_carrier to source plugins and create proxies through proxy_factory. Restrict proxy use to synchronous registration callbacks.
  • Code: Change algorithm_bits to use a canonical algorithm_type; update fold, observer, predicate, and transform nodes to use that type.
  • Python: Invalidate module and source wrapper pointers after registration. Raise RuntimeError if registration uses an invalidated wrapper.
  • Build system and docs: Install registration_context.hpp instead of graph_proxy.hpp. Update registration documentation and add a plan document.
  • Tests: Add compile-time proxy capability checks, a provider test that destroys glue before execution, and coverage for canonical algorithm_bits types. Test execution results were not provided.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (2)
.github/copilot-instructions.md — auto-discovered
AGENTS.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 8db01ac1-67e6-43de-b669-9312fad8557d

📥 Commits

Reviewing files that changed from the base of the PR and between 78ebe91 and 3e912c6.

📒 Files selected for processing (25)
  • phlex-registration-inversion-plan.md
  • phlex/app/load_module.cpp
  • phlex/core/CMakeLists.txt
  • phlex/core/declared_fold.hpp
  • phlex/core/declared_observer.hpp
  • phlex/core/declared_predicate.hpp
  • phlex/core/declared_transform.hpp
  • phlex/core/framework_graph.hpp
  • phlex/core/glue.cpp
  • phlex/core/glue.hpp
  • phlex/core/graph_proxy.hpp
  • phlex/core/node_catalog.hpp
  • phlex/core/registration_context.hpp
  • phlex/detail/plugin_macros.hpp
  • phlex/metaprogramming/delegate.hpp
  • phlex/module.hpp
  • phlex/resource.hpp
  • phlex/source.hpp
  • plugins/python/src/modulewrap.cpp
  • plugins/python/src/pymodule.cpp
  • plugins/python/src/wrap.hpp
  • test/CMakeLists.txt
  • test/provider_test.cpp
  • test/proxy_capabilities_test.cpp
  • test/transform_node_test.cpp
💤 Files with no reviewable changes (1)
  • phlex/core/graph_proxy.hpp

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: build (gcc, none)
  • GitHub Check: Analyze cpp with CodeQL
  • GitHub Check: coverage
  • GitHub Check: clang-tidy-check
🧰 Additional context used
📓 Path-based instructions (3)
Source excerpt: Use clang-format tool for all C++ code (VS Code auto-formats on save)

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Files:

  • phlex/core/declared_fold.hpp
  • phlex/core/declared_transform.hpp
  • phlex/core/declared_predicate.hpp
  • phlex/core/node_catalog.hpp
  • phlex/core/declared_observer.hpp
  • plugins/python/src/wrap.hpp
  • plugins/python/src/modulewrap.cpp
  • plugins/python/src/pymodule.cpp
  • test/transform_node_test.cpp
  • test/provider_test.cpp
  • phlex/app/load_module.cpp
  • phlex/core/glue.cpp
  • test/proxy_capabilities_test.cpp
  • phlex/detail/plugin_macros.hpp
  • phlex/metaprogramming/delegate.hpp
  • phlex/core/framework_graph.hpp
  • phlex/core/registration_context.hpp
  • phlex/resource.hpp
  • phlex/source.hpp
  • phlex/module.hpp
  • phlex/core/glue.hpp
Source excerpt: All Markdown files must strictly follow these markdownlint rules:

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Files:

  • phlex-registration-inversion-plan.md
Source excerpt: MD012: no multiple consecutive blank lines Source excerpt: MD022: headings surrounded by exactly one blank line Source excerpt: MD031: fenced code blocks surrounded by exactly one blank line Source excerpt: MD032: lists surr...

📄 CodeRabbit inference engine (AGENTS.md)

Files:

  • phlex-registration-inversion-plan.md
🪛 Cppcheck (2.21.0)
plugins/python/src/modulewrap.cpp

[style] 81-81: The function 'invalidate_module' is never used.

(unusedFunction)


[style] 102-102: The function 'invalidate_source' is never used.

(unusedFunction)

test/proxy_capabilities_test.cpp

[style] 28-28: The function 'initial_value' is never used.

(unusedFunction)

🪛 LanguageTool
phlex-registration-inversion-plan.md

[style] ~24-~24: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...es all node-registration operations. 3. It implements object binding through `make...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...registration. - source_graph_proxy<T> exposes source registration; the target design ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~89-~89: Ensure spelling is correct
Context: ...se mutable catalogs or the TBB graph to plugin code. - It has an explicitly documented...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~90-~90: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...logs or the TBB graph to plugin code. - It has an explicitly documented lifetime t...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~404-~404: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hregistration methods permanently. 3. Preserve capability-specificmake()` return ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~405-~405: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...y-specific make<T>() return types. 4. Preserve framework_graph::make<T>() as a `glue...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (3)
plugins/python/src/modulewrap.cpp (1)

81-84: LGTM!

Also applies to: 102-105, 1273-1276, 1350-1353, 1666-1669

plugins/python/src/pymodule.cpp (1)

44-46: LGTM!

Also applies to: 87-89

plugins/python/src/wrap.hpp (1)

40-42: LGTM!

Also applies to: 50-52


📝 Walkthrough

Walkthrough

The PR replaces the shared graph proxy with internal registration state and capability-specific proxies. It updates plugin registration to use a registration carrier and invalidates Python wrappers after registration callbacks.

Changes

Registration Inversion

Layer / File(s) Summary
Shared registration state and glue
phlex/core/registration_context.hpp, phlex/core/glue.hpp, phlex/core/glue.cpp, phlex/core/framework_graph.hpp, test/provider_test.cpp, phlex-registration-inversion-plan.md
A shared registration context and state now carry framework dependencies and bound objects. registration_core centralizes glue operations. A provider test checks registration after the glue object is destroyed.
Capability-specific proxies and callable types
phlex/module.hpp, phlex/source.hpp, phlex/resource.hpp, phlex/core/graph_proxy.hpp, phlex/metaprogramming/delegate.hpp, phlex/core/declared_*.hpp, test/proxy_capabilities_test.cpp, test/transform_node_test.cpp, test/CMakeLists.txt, phlex/core/node_catalog.hpp, phlex-registration-inversion-plan.md
The shared proxy is removed. Module, provider, source, and resource proxies use controlled construction and expose distinct operations. Callable type aliases use algorithm_type; tests check proxy capabilities and callable types.
Framework and plugin registration flow
phlex/core/framework_graph.hpp, phlex/core/registration_context.hpp, phlex/detail/plugin_macros.hpp, phlex/app/load_module.cpp, phlex/resource.hpp, phlex/source.hpp, phlex/core/CMakeLists.txt, phlex/core/node_catalog.hpp, phlex-registration-inversion-plan.md
The framework creates proxies through registration context. Plugin entry points and loaders pass a registration_carrier; resource loading obtains its proxy directly from the framework graph. The plan documents compatibility constraints and plugin rebuild requirements.
Python wrapper invalidation and validation
plugins/python/src/modulewrap.cpp, plugins/python/src/pymodule.cpp, plugins/python/src/wrap.hpp, phlex-registration-inversion-plan.md
Python module and source wrappers are invalidated after registration callbacks. Transform, observer, and provider registration calls report RuntimeError when their wrapped pointer is null. The plan documents callback lifetimes and validation requirements.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant FrameworkGraph
  participant ModuleLoader
  participant SourcePluginShim
  participant ProxyFactory
  participant SourceGraphProxy
  FrameworkGraph->>ModuleLoader: provide registration_carrier
  ModuleLoader->>SourcePluginShim: invoke creator with carrier and configuration
  SourcePluginShim->>ProxyFactory: create source proxy from carrier
  ProxyFactory->>SourceGraphProxy: construct proxy
Loading

Suggested reviewers: greenc-fnal

Merge Risk: ⚪ Minimal · up to 3e912

No actionable issue remains from this review; the change is mergeable after normal checks.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 3e912

The registration interfaces become more explicitly capability-scoped, and retained Python wrappers lose registration access after their callbacks complete. No introduced security defect was established. Matching framework and plugin builds remain necessary, and deployment compatibility and plugin-path ownership have not been verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The effective plugin trust boundary remains the application process. Configuration and plugin-search-path authority determine which executable plugin code is loaded. Capability-specific C++ interfaces constrain supported registration operations, but they are not a sandbox for malicious native code.

Trust Boundaries and Controls

  • observed — Retained Python wrappers lose registration authority after both successful callbacks and callbacks that leave a Python exception. Invalidation clears the borrowed pointer before wrapper release; all exposed registration methods reject the invalidated wrapper instead of dereferencing that pointer.
  • observed — Plugin identity selection is unchanged in the inspected base-to-head comparison: a Python configuration selects the fixed Python bridge plugin, conflicting Python and C++ specifications are rejected, and native specifications continue through the existing shared-library loader.

Resilience and Maintainability Implications

  • inferred — Wrapper revocation and graph rollback are separate guarantees. Registration can mutate the graph before a callback fails, as it could before this PR. The normal application loading path propagates failure rather than reaching graph execution, but recovery by external callers that reuse the graph is not established.

Hardening Proposals

  • proposed — Package and roll back the framework with its rebuilt plugins as one compatible release set. If independently deployed plugin binaries become a supported requirement, introduce explicit ABI negotiation or a versioned opaque interface before invoking creator symbols.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 80 functions across 21 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies the main objective: reducing template instantiations through the registration-inversion refactor and related proxy changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 80 functions across 21 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🧪 Generate unit tests (beta)
  • Create a new PR
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.70370% with 22 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
plugins/python/src/modulewrap.cpp 18.18% 6 Missing and 3 partials ⚠️
phlex/core/registration_context.hpp 69.56% 7 Missing ⚠️
phlex/module.hpp 63.63% 4 Missing ⚠️
plugins/python/src/pymodule.cpp 50.00% 0 Missing and 2 partials ⚠️
@@            Coverage Diff             @@
##             main     #951      +/-   ##
==========================================
- Coverage   85.97%   85.82%   -0.16%     
==========================================
  Files         184      184              
  Lines        8566     8555      -11     
  Branches     1027     1032       +5     
==========================================
- Hits         7365     7342      -23     
- Misses        950      960      +10     
- Partials      251      253       +2     
Flag Coverage Δ
scripts 80.45% <ø> (ø)
unittests 87.98% <83.70%> (-0.22%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
phlex/app/load_module.cpp 90.32% <100.00%> (-0.16%) ⬇️
phlex/core/declared_fold.hpp 96.00% <ø> (ø)
phlex/core/declared_observer.hpp 95.83% <ø> (ø)
phlex/core/declared_predicate.hpp 95.83% <ø> (ø)
phlex/core/declared_transform.hpp 97.61% <ø> (ø)
phlex/core/framework_graph.hpp 100.00% <100.00%> (ø)
phlex/core/glue.cpp 100.00% <100.00%> (ø)
phlex/core/glue.hpp 100.00% <100.00%> (ø)
phlex/core/node_catalog.hpp 100.00% <ø> (ø)
phlex/detail/plugin_macros.hpp 100.00% <100.00%> (ø)
... and 8 more

... and 2 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7659b9a...3e912c6. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Clang-Tidy Check Results

Clang-tidy found the following issue(s) on lines changed by this pull request:

/__w/phlex/phlex/phlex-src/phlex/core/glue.hpp:248: warning: std::move of the variable 'core' of the trivially-copyable type 'internal::registration_core' has no effect; remove std::move()
/__w/phlex/phlex/phlex-src/phlex/core/registration_context.hpp:23: warning: class 'registration_context' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator
/__w/phlex/phlex/phlex-src/phlex/core/registration_context.hpp:106: warning: class 'registration_carrier' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator
/__w/phlex/phlex/phlex-src/phlex/core/glue.cpp:16: warning: no header providing "std::vector" is directly included
/__w/phlex/phlex/phlex-src/phlex/core/glue.cpp:38: warning: no header providing "std::unique_ptr" is directly included
/__w/phlex/phlex/phlex-src/phlex/module.hpp:39: warning: the parameter 'f' of type '(anonymous namespace)::jit_callback_impl<void, std::integer_sequence<unsigned long, 0, 1, 2>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:39: warning: the parameter 'f' of type '(anonymous namespace)::jit_callback_impl<void, std::integer_sequence<unsigned long, 0, 1>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:39: warning: the parameter 'f' of type '(anonymous namespace)::jit_callback_impl<void, std::integer_sequence<unsigned long, 0>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:39: warning: the parameter 'f' of type '(anonymous namespace)::py_callback_impl<void, std::integer_sequence<unsigned long, 0, 1, 2>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:39: warning: the parameter 'f' of type '(anonymous namespace)::py_callback_impl<void, std::integer_sequence<unsigned long, 0, 1>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:39: warning: the parameter 'f' of type '(anonymous namespace)::py_callback_impl<void, std::integer_sequence<unsigned long, 0>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:60: warning: the parameter 'f' of type '(anonymous namespace)::jit_callback_impl<phlex::experimental::dcarg, std::integer_sequence<unsigned long, 0, 1, 2>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:60: warning: the parameter 'f' of type '(anonymous namespace)::jit_callback_impl<phlex::experimental::dcarg, std::integer_sequence<unsigned long, 0, 1>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:60: warning: the parameter 'f' of type '(anonymous namespace)::jit_callback_impl<phlex::experimental::dcarg, std::integer_sequence<unsigned long, 0>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:60: warning: the parameter 'f' of type '(anonymous namespace)::py_callback_impl<phlex::experimental::dcarg, std::integer_sequence<unsigned long, 0, 1, 2>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:60: warning: the parameter 'f' of type '(anonymous namespace)::py_callback_impl<phlex::experimental::dcarg, std::integer_sequence<unsigned long, 0, 1>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/phlex/module.hpp:60: warning: the parameter 'f' of type '(anonymous namespace)::py_callback_impl<phlex::experimental::dcarg, std::integer_sequence<unsigned long, 0>>' is copied for each invocation but only used as a const reference; consider making it a const reference
/__w/phlex/phlex/phlex-src/test/transform_node_test.cpp:164: warning: redundant 'typename'

Download clang-tidy artifacts

@knoepfel
knoepfel marked this pull request as draft October 12, 2026 13:19
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.

1 participant