Skip to content

feat: add PacketFunctionProxy for read-only pipeline loading (PLT-931)#87

Merged
eywalker merged 12 commits intodevfrom
eywalker/plt-931-when-loading-from-saved-pipeline-and-function-pod-function
Mar 15, 2026
Merged

feat: add PacketFunctionProxy for read-only pipeline loading (PLT-931)#87
eywalker merged 12 commits intodevfrom
eywalker/plt-931-when-loading-from-saved-pipeline-and-function-pod-function

Conversation

@eywalker
Copy link
Contributor

Summary

  • Introduces PacketFunctionProxy — a proxy that stands in for unavailable packet functions in deserialized pipelines, enabling cached data access without the original Python callable
  • When a pipeline is loaded and the function can't be imported, the proxy satisfies PacketFunctionProtocol so FunctionNode, CachedFunctionPod, and DB access all work normally for cached results
  • Downstream operators and function pods (whose functions are available) can compute on cached data from proxy-backed upstream nodes
  • Supports late binding via bind() with identity validation, and unbind() for reverting

Fixes PLT-931

Changes

  • src/orcapod/errors.py — Add PacketFunctionUnavailableError
  • src/orcapod/core/packet_function_proxy.py — New PacketFunctionProxy class with metadata storage, stored URI/hashes, bind/unbind, invocation error on unbound
  • src/orcapod/pipeline/serialization.pyfallback_to_proxy param on resolve_packet_function_from_config
  • src/orcapod/core/function_pod.pyfallback_to_proxy param on FunctionPod.from_config with URI injection
  • src/orcapod/pipeline/graph.py_load_function_node uses proxy fallback; upstream usability accepts READ_ONLY
  • CLAUDE.md / .zed/rules — Document PR target branch and Linear status policies
  • DESIGN_ISSUES.md — Log RC1: ResultCache.record_path not overridable via public API

Test plan

  • 20 unit tests for PacketFunctionProxy (construction, metadata, invocation, bind/unbind, FunctionPod integration)
  • 3 serialization helper tests (fallback_to_proxy for resolver and FunctionPod.from_config)
  • 4 integration tests (pipeline load with unavailable function: READ_ONLY status, get_all_records, iter_packets, downstream operator computation)
  • Full test suite: 2212 tests passing, zero failures

🤖 Generated with Claude Code

eywalker and others added 11 commits March 15, 2026 21:37
Introduces PacketFunctionProxy to fix read-only pipeline loading when
the original packet function is unavailable. The proxy satisfies
PacketFunctionProtocol, enabling full FunctionNode construction with
CachedFunctionPod and DB access for cached data retrieval.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Also logs RC1 design issue for ResultCache.record_path not being
overridable via public API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add PacketFunctionProxy that stands in for unavailable packet functions
in deserialized pipelines, enabling cached data access without the
original function. Add PacketFunctionUnavailableError for invocation
attempts on unbound proxies.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover invocation behavior (unbound raises, empty variation/execution
data), bind/unbind lifecycle, and identity mismatch detection for
function name, version, and output schema.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ch tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion

When fallback_to_proxy=True and normal resolution fails (ImportError,
AttributeError, unknown type ID), return a PacketFunctionProxy instead
of raising. Mirrors the existing pattern in resolve_source_from_config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When fallback_to_proxy=True, passes through to
resolve_packet_function_from_config. If a PacketFunctionProxy is
returned, injects the URI from the parent config's "uri" field.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lity

- Relax upstream usability checks to accept both FULL and READ_ONLY
  status, enabling downstream nodes to be reconstructed when their
  upstream uses a proxy.
- Rewrite _load_function_node to use fallback_to_proxy=True so that
  unavailable functions get a PacketFunctionProxy instead of falling
  back to fully read-only mode. Nodes with a proxy get READ_ONLY
  status and their cached function pod record path is restored from
  the descriptor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nction

Add TestPipelineLoadWithUnavailableFunction class with 4 tests:
- test_load_with_unavailable_function_has_read_only_status
- test_load_with_unavailable_function_can_get_all_records
- test_load_with_unavailable_function_iter_packets_yields_cached
- test_downstream_operator_computes_from_cached

These tests verify that when a pipeline is saved, the function module_path
is corrupted (simulating an unavailable function), and the pipeline is
reloaded, the function node gets a PacketFunctionProxy with READ_ONLY
status and can still serve cached data. The downstream operator test
confirms that a SelectPacketColumns operator can compute from the
READ_ONLY function node's cached output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Feature branch PRs always target dev; dev→main for versioning
- Update Linear issue status to In Progress when starting work

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 15, 2026 22:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a PacketFunctionProxy mechanism to allow pipelines to load in a “read-only but cache-accessible” state when a serialized packet function can’t be imported, enabling cached-result access and downstream computation from cached data.

Changes:

  • Introduces PacketFunctionProxy + PacketFunctionUnavailableError to represent unavailable packet functions while preserving identity metadata.
  • Adds fallback_to_proxy support in packet-function resolution and FunctionPod.from_config, and uses proxy fallback during Pipeline.load.
  • Expands unit + integration test coverage for proxy behavior, resolver fallback, and pipeline load/read-only execution paths.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/orcapod/errors.py Adds PacketFunctionUnavailableError for unbound proxy invocation.
src/orcapod/core/packet_function_proxy.py Implements proxy packet function with bind/unbind and identity metadata.
src/orcapod/pipeline/serialization.py Adds fallback_to_proxy option to packet-function resolver.
src/orcapod/core/function_pod.py Adds proxy fallback to FunctionPod.from_config and injects URI into proxies.
src/orcapod/pipeline/graph.py Loads function nodes with proxy fallback; treats READ_ONLY upstreams as usable.
tests/test_core/packet_function/test_packet_function_proxy.py New unit tests for proxy behavior + FunctionPod integration.
tests/test_pipeline/test_serialization_helpers.py Tests resolver/pod fallback behavior.
tests/test_pipeline/test_serialization.py Integration tests for loading pipelines with unavailable functions and downstream ops.
DESIGN_ISSUES.md Documents record-path override limitation as a design issue.
CLAUDE.md / .zed/rules Updates workflow/policy documentation.
superpowers/specs/... / superpowers/plans/... Design + implementation plan documentation for PLT-931.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov-commenter
Copy link

codecov-commenter commented Mar 15, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 93.41317% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/orcapod/core/packet_function_proxy.py 91.72% 11 Missing ⚠️

📢 Thoughts on this report? Let us know!

- Add uri to PythonPacketFunction.to_config() output
- Refactor PacketFunctionProxy to read URI from config (remove uri param)
- Move _BUILTIN_TYPE_MAP to pipeline/serialization.py
- Coerce unrecognized type strings to object in _deserialize_schema_from_config
- Simplify FunctionPod.from_config() (remove proxy-specific URI injection)
- Remove record_path override from _load_function_node in graph.py
- Fix result_path_prefix derivation in FunctionNode.from_descriptor
- Narrow exception handling to ImportError/ModuleNotFoundError/AttributeError
- Fix test specificity (pytest.raises with specific exception types)
- Add schema round-trip consistency and hash preservation tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@eywalker eywalker merged commit 11d3ce5 into dev Mar 15, 2026
4 checks passed
@eywalker eywalker deleted the eywalker/plt-931-when-loading-from-saved-pipeline-and-function-pod-function branch March 16, 2026 21:03
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.

3 participants