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
<PackageReference Include="PulseTrade.Comm.ResourceNode" Version="0.1.1" />
<PackageVersion Include="PulseTrade.Comm.ResourceNode" Version="0.1.1" />
<PackageReference Include="PulseTrade.Comm.ResourceNode" />
paket add PulseTrade.Comm.ResourceNode --version 0.1.1
#r "nuget: PulseTrade.Comm.ResourceNode, 0.1.1"
#:package PulseTrade.Comm.ResourceNode@0.1.1
#addin nuget:?package=PulseTrade.Comm.ResourceNode&version=0.1.1
#tool nuget:?package=PulseTrade.Comm.ResourceNode&version=0.1.1
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-stoppingtomark-leavingandservice-lefttomark-leftusing 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.Hostexecutable exposing local-only/resource-node/healthzand/resource-node/api/command; it composes clean backend packages, accepts both strictResourceCommandJSON and the existing SPA Host HTTP bridge command shape, and supports Windows ServiceStopAsyncnode-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 tablesResourceNodeResultProjectionandResourceNodeProducerOutboxEvent; database comes from the caller's connection string.PulseTrade.Comm.ResourceNode.Pcsl: PCSL provider with setsresource-node-result-projectionandresource-node-sharding-producer-outbox; backing root comes from the caller'sCommHub/ PCSL root.- file-local fallback:
createFileLocalResultProjectionProvider storeRootwrites 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]forActorArguTargetCommand/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,ResourceNodeShardedFunctionActorprops/dispatch boundary,ResourceNodeShardedFunctionEnvelope, deterministic shard id/message extractor,ResourceNodeShardedFunctionRegion.startWithProps,ResourceNodeShardedFunctionActor.propsWithShardingConsumerControllerStart,ResourceNodeShardingConsumerControllerFactory.props,ResourceNodeShardingProducerControllerFactory.props/start, andResourceNodeShardingProducerLoopoutbox dispatch/redrain/confirm planning; - RN.Host operation catalog:
ResourceNodeOperationShardedSpecCatalogwraps cleanResourceCommandhandlers intoResourceNodeShardedFunctionSpec<ResourceCommand, ResourceCommandReply>and health-projects built-inttc.pingpongplus clean AOE/GitHub/Marvel package operations; - RN.Host catalog region binding:
PulseTrade.Comm.ResourceNode.HostexposesDurableProxyCatalogShardRegionRuntime.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, andrunActorArguRawStringTargetReplyAsync; - typed low-cognitive gate:
DurableProxyJsonCodec<'T>andActorArguJsonStringDurableProxySpec<'Input,'Reply>validate typed RawArgu / legacy reply JSON around the sameCommandToCell/InvokeLegacy/LegacyReplyToCellpath; - 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
/mcplistener; - 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 | Versions 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. |
-
net10.0
- FSharp.Core (>= 10.1.402)
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 |