PulseTrade.Comm.ResourceNode 0.1.1

dotnet add package PulseTrade.Comm.ResourceNode --version 0.1.1
                    
NuGet\Install-Package PulseTrade.Comm.ResourceNode -Version 0.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PulseTrade.Comm.ResourceNode" Version="0.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PulseTrade.Comm.ResourceNode" Version="0.1.1" />
                    
Directory.Packages.props
<PackageReference Include="PulseTrade.Comm.ResourceNode" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PulseTrade.Comm.ResourceNode --version 0.1.1
                    
#r "nuget: PulseTrade.Comm.ResourceNode, 0.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PulseTrade.Comm.ResourceNode@0.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PulseTrade.Comm.ResourceNode&version=0.1.1
                    
Install as a Cake Addin
#tool nuget:?package=PulseTrade.Comm.ResourceNode&version=0.1.1
                    
Install as a Cake Tool

PulseTrade.Comm.ResourceNode

PulseTrade.Comm.ResourceNode is the clean PTC Resource Node package boundary.

This project does not replace or rename PulseTrade.Comm.Mcp.Server. The legacy project remains archived as a combined-host implementation reference. New GW / SPA Host / PTCS integration code should depend on this package boundary when it needs Resource Node command, reply, capability, or dispatcher vocabulary.

Current slice:

  • command/reply DTOs for backend operations;
  • capability heartbeat/drain DTO;
  • shared dispatcher contract constants for HTTP bridge, ActorArgu bridge, and final PTCS ActorFabric/ShardingDelivery backend;
  • fail-closed final backend readiness vocabulary;
  • clean handler runtime/registry for built-in, backend-package, and multi-package catalog operations;
  • provider-side backend completion helpers for canonical request generation, prepared HTTP request composition, and injected-client completion/query submit;
  • service-stop lifecycle callback contract/runner that maps service-stopping to mark-leaving and service-left to mark-left using the existing /nodes/api/node-drain/* route/query vocabulary.
  • clean backend packages for AOE plan-only, AOE injected write contract, Marvel alias injected executor, GitHub MCP HTTP forwarding, and transitional legacy bridge.
  • clean PulseTrade.Comm.ResourceNode.Host executable exposing local-only /resource-node/healthz and /resource-node/api/command; it composes clean backend packages, accepts both strict ResourceCommand JSON and the existing SPA Host HTTP bridge command shape, and supports Windows Service StopAsync node-drain lifecycle callbacks.

Journal / Snapshot / DB

PulseTrade.Comm.ResourceNode core does not use Akka.Persistence journal/snapshot tables and does not own a database. It defines the provider-neutral ResourceResultProjectionProvider contract.

Provider packages:

  • PulseTrade.Comm.ResourceNode.SqlServer: SQL Server provider with tables ResourceNodeResultProjection and ResourceNodeProducerOutboxEvent; database comes from the caller's connection string.
  • PulseTrade.Comm.ResourceNode.Pcsl: PCSL provider with sets resource-node-result-projection and resource-node-sharding-producer-outbox; backing root comes from the caller's CommHub / PCSL root.
  • file-local fallback: createFileLocalResultProjectionProvider storeRoot writes JSON files under the caller-provided root; no journal/snapshot table.

Provider snapshots such as ptc.resource-node.pcsl.projection-snapshot.v1 and ptc.resource-node.sqlserver.projection-snapshot.v1 are export/import documents for result projection. They are not Akka.Persistence snapshot-store rows.

DurableProxy terminology

RN DurableProxy work uses these names for the RN-side low-cognitive proxy API:

Term Short name Direction Owner
CommandToCell cmd2cell ActorArguTargetCommand / ResourceCommand → fCell2<string> or explicit typed cell RN.Host integration code
InvokeLegacy ivkLegacy fCell2<string> + replyer → legacy actor/service input, usually string RN.Host integration code
LegacyReplyToCell legacy2cell legacy actor obj reply → fCell2<string> / ActorArguTargetReply RN.Host integration code

PulseTrade.Comm.ResourceNode.DurableProxy owns the hard part around those three functions: sharded actor creation, Akka Cluster Sharding / ShardingDelivery, confirm timing, retry, timeout/dead-letter, idempotency, and backend completion/result projection.

Current first slice:

  • project: Libs/PulseTrade.Comm/src/PulseTrade.Comm.ResourceNode.DurableProxy;
  • exact PTCS dependency: PulseTrade.Comm.Spa [0.2.5-beta14] for ActorArguTargetCommand / ActorArguTargetReply;
  • full API: ResourceNodeShardedFunctionSpec<'In,'Out> plus delivery policy, validation, local deterministic runner, retry/timeout/dead-letter report, terminal projection-before-confirm report, ResourceNodeTerminalCompletion, ResourceNodeTerminalCompletionProviderBinding, ResourceNodeShardingDeliveryRuntimeManifest, ResourceNodeShardingDeliveryStartPlan, ResourceNodeShardedFunctionActor props/dispatch boundary, ResourceNodeShardedFunctionEnvelope, deterministic shard id/message extractor, ResourceNodeShardedFunctionRegion.startWithProps, ResourceNodeShardedFunctionActor.propsWithShardingConsumerControllerStart, ResourceNodeShardingConsumerControllerFactory.props, ResourceNodeShardingProducerControllerFactory.props/start, and ResourceNodeShardingProducerLoop outbox dispatch/redrain/confirm planning;
  • RN.Host operation catalog: ResourceNodeOperationShardedSpecCatalog wraps clean ResourceCommand handlers into ResourceNodeShardedFunctionSpec<ResourceCommand, ResourceCommandReply> and health-projects built-in ttc.pingpong plus clean AOE/GitHub/Marvel package operations;
  • RN.Host catalog region binding: PulseTrade.Comm.ResourceNode.Host exposes DurableProxyCatalogShardRegionRuntime.start / startWithOptions, which start direct shard regions or ShardingConsumerController regions from the Host catalog and return a non-secret runtime projection;
  • low-cognitive API: ActorArguRawStringDurableProxySpec, DurableProxy.actorArguRawStringProxy, runActorArguRawStringProxyAsync, and runActorArguRawStringTargetReplyAsync;
  • typed low-cognitive gate: DurableProxyJsonCodec<'T> and ActorArguJsonStringDurableProxySpec<'Input,'Reply> validate typed RawArgu / legacy reply JSON around the same CommandToCell / InvokeLegacy / LegacyReplyToCell path;
  • demo: scripts/demo-rn-durableproxy-low-cognitive-api.fsx.

The local deterministic runner is a first-slice API/test/demo runner. It is not the final Akka Cluster Sharding / ShardingDelivery runtime.

ResourceNodeShardedFunctionSpec.runtimeManifest exists to prevent overclaiming. It reports:

  • contract version ptc-rn-sharding-delivery-runtime-v1;
  • current runtime kind rn-durableproxy-local-deterministic-runner;
  • final runtime kind akka-cluster-sharding-delivery;
  • LocalDeterministicRunnerSatisfiesRuntime=false;
  • missing final-runtime requirements such as ClusterSharding entity startup, ShardingDelivery consumer controller wiring, and idempotent result-vault completion.

ResourceNodeActorRuntime.TryReplayTerminalAsync and CompleteTerminalAsync are the terminal completion hooks for result vault providers. TryReplayTerminalAsync receives a stable completion key plus the original command and can return ResourceNodeTerminalCompletion.replayExisting before decode, handler invocation, or projection. CompleteTerminalAsync receives the same stable key plus a produceTerminal thunk for first-run terminal projection. ResourceNodeTerminalCompletionProviderBinding adapts the shared ResourceResultProjectionProvider contract into both hooks: SQL/PCSL provider packages can supply persistence without DurableProxy referencing their concrete assemblies. This gives the local deterministic runner and the controller-delivery actor path the same idempotent redelivery skip rule; live ProducerController/real region restart proof still belongs to the final service-window runtime slice.

ResourceNodeShardingDeliveryStartPlan is the bridge from specs/manifests toward the final Akka runtime. It lists shard count, type names, ShardRegion.StartEntity:<typeName> targets, required Akka packages, and missing runtime actions. Package-level ClusterSharding region startup is now represented by runtime kind akka-cluster-sharding-entity-region; it still intentionally reports SatisfiesFinalRuntime=false until live ProducerController/real region restart, SQL/live shared-provider completion, rolling update, and service-window behavior are proven.

ResourceNodeShardedFunctionActor is the Akka actor entity boundary. ResourceNodeShardedFunctionActor.props validates a spec and returns Akka Props; the actor receives direct ResourceNodeShardedFunctionDispatch or sharded ResourceNodeShardedFunctionEnvelope, runs the spec via the same DurableProxy runner, and replies with ResourceNodeShardedFunctionDispatchResult. ResourceNodeShardedFunctionActor.propsWithShardingConsumerControllerStart additionally registers the actor with an official Akka ShardingConsumerController via ConsumerController.Start<ResourceNodeShardedFunctionEnvelope>. The actor can consume ConsumerController.Delivery<ResourceNodeShardedFunctionEnvelope> and sends ConsumerController.Confirmed.Instance only after terminal completion; provider-bound runtimes use the same rule and can replay existing terminal completion without duplicate projection. ResourceNodeShardingConsumerControllerFactory.props creates the official Akka consumer controller props for this package boundary; ResourceNodeShardingProducerControllerFactory.props/start creates the producer-side official Akka controller seam for dispatch-side packages that own a shard region reference, and ResourceNodeShardingProducerLoop is the matching side-effect-free outbox/redrain reducer for a future live producer actor.

ResourceNodeShardedFunctionRegion.startWithProps starts a real Akka ClusterSharding direct-entity region for these actors. ResourceNodeShardedFunctionRegion.startSpecWithConsumerController starts the equivalent RN spec through the package-level ShardingConsumerController actor/factory seam. RN.Host DurableProxyCatalogShardRegionRuntime.start binds its real operation catalog to the direct region helper; startWithOptions can inject a provider-bound actor runtime and can select RegionMode=ShardingConsumerControllerRegion. Package-level restarted controller-delivery actor redelivery now replays before handler invocation; the next runtime slice is live ProducerController/real region restart and service-window proof.

Do not call these RN functions handlerIn or handlerOut. Those names belong to PTC.GW route registration:

Area In conversion Out conversion Keys
PTC.GW route handlerIn: MCP/Web invocation input → gateway/fCell command cell handlerOut: downstream result cell → MCP/Web response tool key + actor key / route key
RN DurableProxy CommandToCell: durable command → proxy input cell LegacyReplyToCell: legacy reply object → reply cell/result role + typeName + actorKey/entity id

The two shapes are similar because both wrap asynchronous work with before/after conversion. They are not the same API. GW is the public gateway surface. RN DurableProxy is an internal backend/proxy surface that adapts commands and legacy actors while the package owns delivery.

Common first slice:

ActorArguTargetCommand.RawArgu
  -> CommandToCell / cmd2cell builds fCell2.S / fCell2<string>
  -> InvokeLegacy / ivkLegacy sends string to legacy actor with replyer
  -> legacy actor tells obj to replyer
  -> LegacyReplyToCell / legacy2cell converts obj to fCell2<string>
  -> DurableProxy creates ActorArguTargetReply and terminal completion

ActorArgu route binding

PTCS ActorArguTargetCommand deliberately carries only the actor selected for the current send as ActorAddress plus the command text as RawArgu. It does not carry the full Dynamic selected-key tail. Therefore RN DurableProxy must not assume PTCS can choose a per-send native/RN target from [proxyActorAddress; "proxy-v1"; rnActorAddress; targetKind].

The current no-PTCS-core-change route is one target key → one proxy actor/spec:

Dynamic selected key:
[ proxyActorAddress; "proxy-v1"; rnActorAddress; targetKind ]

PTCS sends:
ActorArguTargetCommand.ActorAddress = proxyActorAddress
ActorArguTargetCommand.RawArgu      = user command text

RN DurableProxy binding:
ActorArguRawStringDurableProxySpec.ActorKey = rnActorAddress or deployment-specific native target
InvokeLegacy captures that native target and sends the converted cell there.

If a future design wants one shared proxy actor to choose among many native targets at send time, PTCS must first add an explicit route envelope/resolver field. Until that RFC exists, do not implement hidden parsing of Dynamic key tails inside RN DurableProxy.

Non-goals for this first slice:

  • no public /mcp listener;
  • no OAuth/bearer policy;
  • no embedded SQL/PCSL concrete provider implementation inside clean ResourceNode core or DurableProxy; they consume the shared provider contract supplied by provider packages;
  • no embedded PTCS.Host ShardingDelivery runtime;
  • no embedded GitHub/PAT/realworld writer implementation inside clean ResourceNode core or clean AOE package;
  • bounded outer ProcSupervisor-as-Windows-Service install/start/verify/uninstall proof exists; production RN child service-window restart, rolling update, and long-running soak remain open.
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (8)

Showing the top 5 NuGet packages that depend on PulseTrade.Comm.ResourceNode:

Package Downloads
PulseTrade.Comm.ResourceNode.DurableProxy

Package Description

PulseTrade.Comm.ResourceNode.Pcsl

Package Description

PulseTrade.Comm.ResourceNode.SqlServer

Package Description

PulseTrade.Comm.ResourceNode.TAResearch

Resource Node operation adapter for low-cognitive PTCS TAResearch fCell2 native actors.

PulseTrade.Comm.ResourceNode.GitHub

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.1 4 10/21/2026
0.1.0-alpha1 920 10/2/2026