NPS-Release

NPS Change Request: Split Gateway Node into Anchor Node + Bridge Node

CR ID: NPS-CR-0001 Target version: v1.0-alpha.3 Status: Implemented (v1.0.0-alpha.3, 2026-04-26) Type: Breaking change (spec-level role split) Author: Ori, LabAcacia Affected components: NWP spec, .NET SDK, conformance tests, public docs


1. Summary

The current NWP node taxonomy includes a single Gateway Node type whose definition has, on inspection, been carrying two distinct roles that should not share one name:

  1. Cluster control plane and external entrypoint — accepts inbound traffic addressed to a cluster, maintains topology of member nodes, dispatches tasks, aggregates responses. State-aware.
  2. Protocol translator — bridges NPS frames to and from non-NPS protocols (HTTP, gRPC, MCP, A2A). Stateless per-request.

This CR splits Gateway Node into two distinct node types:

The original term Gateway Node is retired.

2. Motivation

The conflation produces concrete harm even at alpha stage:

The cost of fixing this now (alpha.3, no production users) is near zero. The cost of fixing it after v1.0 freeze would be measured in deprecation cycles, downstream SDK breakage, and ecosystem confusion.

3. Specification changes

3.1 New node type: Anchor Node

Add to spec/NPS-2-NWP.md, Node Types section:

Anchor Node

An Anchor Node is the control plane and external entrypoint of an NPS cluster. It MUST:

  1. Maintain a topology of member nodes within its cluster, including their NIDs, declared capabilities, and activation_mode.
  2. Accept inbound NWP Action and Query frames addressed to the cluster (rather than to a specific member NID).
  3. Dispatch frames to appropriate member nodes based on capability declaration and current load.
  4. Aggregate outbound responses from member nodes into single response streams toward the originating caller.

Member nodes register with their Anchor Node on cluster join via NDP Announce frames carrying a cluster_anchor field referencing the Anchor Node’s NID. Deregistration follows standard NDP offline semantics.

A cluster MUST have at least one Anchor Node. High-availability deployments MAY operate multiple Anchor Nodes for the same cluster; consensus protocol between Anchor Nodes is implementation-defined and outside this specification (deferred to NPS-AaaS Profile L3).

An Anchor Node MAY simultaneously carry other node-type roles (e.g. Memory Node) in deployments where role separation is unnecessary.

3.2 New node type: Bridge Node

Add to spec/NPS-2-NWP.md, Node Types section:

Bridge Node

A Bridge Node translates between NPS frames and non-NPS protocols. It MUST:

  1. Accept inbound NWP frames carrying a bridge_target parameter identifying the external protocol and endpoint.
  2. Produce outbound requests in the target protocol’s format.
  3. Translate target protocol responses back into NWP frames.

Bridge Nodes are stateless per request and do not participate in cluster topology. A single Bridge Node MAY translate to multiple distinct external protocols; deployments MAY operate dedicated Bridge Nodes per protocol for isolation.

Standard external protocols expected to be supported by reference Bridge Node implementations:

Additional protocol adapters MAY be registered through future CRs.

3.3 Removal of Gateway Node

In spec/NPS-2-NWP.md:

3.4 Wire format changes

Migration note (NDP v0.8 / NWP v0.13): The node_kind field introduced by this CR was renamed to node_roles (array-only form) as part of the M1 naming-disambiguation fix. Parsers MUST accept node_kind as an alias through alpha.5. References to node_kind below are historical and describe the state at the time this CR was implemented (NDP v0.8 / NWP v0.13).

In NDP Announce frame, the node_kind field:

Old wire value Status New wire value(s)
"gateway" Removed "anchor" and/or "bridge" (a node MAY declare multiple)

The node_kind field is redefined to accept either a string (single role) or an array of strings (multiple roles). Implementations MUST support both forms when parsing.

New optional fields in Announce:

3.5 Specification files affected

File Change
spec/NPS-2-NWP.md Add Anchor Node section, add Bridge Node section, remove Gateway Node section, update wire format tables, update examples
spec/NPS-4-NDP.md Update Announce frame schema with node_kind array form, cluster_anchor, bridge_protocols
spec/services/NPS-AaaS-Profile.md Update L1/L2/L3 conformance requirements to reference Anchor and Bridge separately
spec/services/conformance/NPS-Node-L1.md Add separate test items for Anchor Node basic registry and Bridge Node basic translation (where applicable to L1 scope)
spec/services/conformance/L2.md, L3.md Same alignment
README.md Update node type list
CHANGELOG.md Record breaking change under v1.0-alpha.3

4. SDK changes (.NET reference SDK)

Type renames:

Old New
GatewayNode (class) Removed; replaced by AnchorNode and BridgeNode classes
NodeKind.Gateway (enum) Removed; replaced by NodeKind.Anchor and NodeKind.Bridge
[Flags] semantics on NodeKind Newly required — a node may declare multiple kinds

New types:

[Flags]
public enum NodeKind
{
    None = 0,
    Memory = 1 << 0,
    Action = 1 << 1,
    Complex = 1 << 2,
    Anchor = 1 << 3,
    Bridge = 1 << 4,
}

public sealed record AnchorNodeDescriptor(
    Nid Nid,
    IReadOnlyList<Nid> ClusterMembers,
    /* HA group, dispatch policy etc. — TBD per L3 spec */
);

public sealed record BridgeNodeDescriptor(
    Nid Nid,
    IReadOnlySet<string> SupportedProtocols /* "http", "grpc", "mcp", "a2a" */
);

Serialization:

NodeKind flag combinations serialize to JSON arrays in NDP Announce:

Deserializer MUST accept both string and array forms.

Deprecation aids:

For one alpha release window (alpha.3 only), the SDK SHOULD include:

This stub is removed in alpha.4.

Error codes (M2 fix):

The wire-level rejection MUST use the specific error codes registered in spec/error-codes.md v1.1:

Both -REMOVED responses SHOULD include a hint field (string) containing a reference to NPS-CR-0001 and the migration guidance ("gateway""anchor" or "bridge").

5. Conformance test changes

conformance/L1-test/:

L1-CERTIFIED.md template: split the Gateway Node checkbox into two:

Implementations MAY claim L1 with one but not both, and MUST declare which.

6. Migration impact

External impact: None known. v1.0-alpha.2 has no production deployments. No third-party SDKs or implementations exist as of CR submission.

Internal impact:

Migration window: Single release. alpha.3 introduces the split with the deprecation stub described in §4. alpha.4 removes the stub.

7. Out of scope (explicit non-changes)

To prevent scope creep, the following are explicitly NOT part of this CR:

8. Acceptance criteria

This CR is considered accepted and ready to merge when:

9. CHANGELOG entry (proposed text)

## [v1.0-alpha.3] - YYYY-MM-DD

### Breaking changes

- **NWP**: Removed `Gateway Node` type. Split into `Anchor Node` (cluster
  control plane + external entrypoint) and `Bridge Node` (NPS↔non-NPS
  protocol translation). The two roles previously conflated under
  Gateway Node have distinct semantics, state requirements, and
  conformance criteria, and are now independently declarable. See
  NPS-CR-0001 for full rationale and migration notes.

- **NDP**: `Announce` frame `node_kind` field now accepts both string
  (single role) and array (multiple roles) forms. New optional fields
  `cluster_anchor` and `bridge_protocols` introduced. Wire value
  `"gateway"` removed; `"anchor"` and `"bridge"` introduced.

- **.NET SDK**: `NodeKind` enum updated with `[Flags]` semantics.
  `GatewayNode` type removed (deprecation stub present in alpha.3, to
  be removed in alpha.4). New `AnchorNodeDescriptor` and
  `BridgeNodeDescriptor` types.

### Migration

No production deployments affected. Implementations consuming alpha.2
must update wire field values and SDK type references before
upgrading to alpha.3. The deprecation stub in alpha.3 will throw
informative errors on legacy usage to aid migration.

10. Open questions

All three OQs resolved at implementation time (v1.0-alpha.3):

  1. node_kind array vs. single-string — Resolved: array form is canonical; single-string accepted as a parse-time alias. In NDP v0.6 (alpha.6) the field was further renamed from node_kind to node_roles, with node_kind retained as a backward-compatibility alias through alpha.5.

  2. cluster_anchor mandatory vs. optional — Resolved: optional with implicit standalone default. Single-node deployments omit the field.

  3. bridge_protocols open-ended vs. enum — Resolved: open-ended with reserved standard values ("http", "grpc", "mcp", "a2a"). Third-party adapters may register additional values via future CRs.

11. Implementation notes

Shipped in v1.0.0-alpha.3 (2026-04-26). Corrections to the framing in §1/§2: