.NET / SQL / Enterprise Engineering
UAIX-Compliant .NET NuGet Package for AI-to-AI Communication
Report summary
UAIX’s current published posture is that UAI-1 is the portable, reviewable exchange and evidence layer , while runtime execution remains outside UAIX . Its capability-adaptive interoperability record defines levels L0 through L7 , says unknown clients should downgrade to L0/L1 , and makes GET-Action
Key topics
- .NET / SQL / Enterprise Engineering
- .NET
- SQL
- Enterprise Engineering
- AI
- UAIX
- UAI
- Agentic Web
- C#
Research provenance
For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.
Source availability: 37 citation markers in the source export have no recoverable source links. Those markers are omitted from this reader; any supplied bibliography and ordinary links remain. Check the original sources before relying on the cited claims.
This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.
Full report
On this page
Executive summary
UAIX’s current published posture is that UAI-1 is the portable, reviewable exchange and evidence layer, while runtime execution remains outside UAIX. Its capability-adaptive interoperability record defines levels L0 through L7, says unknown clients should downgrade to L0/L1, and makes GET-Action and No-Op explicit fallback mechanisms rather than substitutes for structured POST APIs. UAIX’s standards-fit guidance also draws a sharp boundary: MCP remains the host-session/tool layer, A2A remains the peer-agent discovery/delegation layer, and UAI-1 is the durable message, trust, provenance, validation, and evidence layer.
For a .NET 6+ implementation, the best design is not a monolithic “agent runtime,” but a bridge SDK that can emit and consume UAIX/UAI-1 records, automatically adapt behavior across UAIX levels, and expose optional connectors for transports, auth, execution adapters, and evidence capture. The package should treat HTTPS + keyed JSON as the canonical surface, expose L0/L1 discovery and fallback artifacts automatically, support L3+ structured JSON POST, add L4 authenticated mutations, require L5 restore/readback verification, support L6 lifecycle packets such as handoff/final-report/memory-proposal, and implement L7 as an extension negotiation layer rather than as a hard-coded first-class core profile, because the current published schema catalog has client profiles through L6, while L7 appears in the matrix as site-specific negotiation guidance.
The recommended security posture is a stacked model: TLS 1.3 for transport, OAuth 2.0 for authorization, mTLS for server-to-server owned mutations where practical, DPoP where sender-constrained tokens are needed without mTLS, JWS for signed-envelope integrity/non-repudiation, JCS for deterministic JSON canonicalization when hashing or signing, a quarantine-first memory firewall for all imported packets, and out-of-process or container isolation for untrusted plugins or tool executors because modern .NET no longer honors Code Access Security as an in-process sandbox.
Given your instruction that unspecified constraints should be assumed to have no specific constraint, my default assumptions in the rest of this report are: public transport = HTTPS REST, canonical payload = keyed JSON, optimized transport form = UAIX keyless ordered JSON where useful, internal high-throughput transport = optional gRPC, server host = ASP.NET Core, and no hosted broker is required by default. That aligns with UAIX’s documented machine-facing surface, which is published as JSON + OpenAPI 3.1 with catalog/discovery/validation/mock routes, plus transport/trust registries, rather than as a hosted runtime bus.
Standards baseline and assumptions
The published UAIX implementation-facing surface is unusually explicit, which is good news for a NuGet package author. UAIX says implementers should start with catalog and discovery, then move into schemas, registry, field-registry, transport-bindings, trust-channels, conformance-levels, validator, mock-exchange, and the OpenAPI 3.1 export. It also states that machine JSON routes are the execution surface, while the human documentation pages are the preferred citation surface. That means your package can be designed around a deterministic bootstrap path instead of reverse-engineering pages or hard-coding route assumptions.
At the message-model level, UAIX publishes a stable canonical envelope with ordered root fields: uai_version, profile, message_id, source, target, conversation, delivery, trust, body, provenance, integrity, and extensions. It also publishes stable nested component order and a field registry for the optimized keyless JSON form. That is important because it gives a .NET implementation a clean separation between domain model, readable keyed JSON, and transport-optimized ordered JSON without inventing a local “compact” format.
The UAIX schema catalog is broader than the high-level UAI request/response pair. In addition to uai.intent.request.v1, uai.intent.response.v1, uai.capability.statement.v1, uai.error.v1, uai.conformance.result.v1, and uai.task.status.v1, UAIX publishes the Agent Communication Operating Model profiles: uai.agent.message.v1, uai.agent.ack.v1, uai.agent.task-status.v1, uai.agent.blocker.v1, uai.agent.memory-proposal.v1, uai.agent.handoff.v1, uai.agent.final-report.v1, and uai.agent.correction.v1, plus capability profiles and negotiation profiles. This means a serious package should model both the request/response exchange path and the longer-lived agent communication lifecycle.
The .NET-specific UAIX pages also matter because they define a support boundary. UAIX’s .NET Bridge Track says the bridge should preserve the public UAI-1 contract while mapping it to service-side execution, and it explicitly warns against hidden runtime-only behavior that contradicts public schemas, registry, examples, or validator output. The .NET NuGet Package page documents an existing package, Protocol5.UAI.CSharp, but also says to treat it as a Protocol5 implementation distribution tied back to UAIX for standards truth, not as a general-purpose UAIX SDK or standards authority. That is relevant for branding, claims, and package scope.
An important architectural consequence of the UAIX material is that UAI-1 should be your durable contract layer, not your whole runtime layer. UAIX’s “Standards Fit” page says MCP owns host/client tool sessions, A2A owns peer-agent discovery and task coordination, and UAI-1 owns the portable exchange record. It also gives concrete bridge rules: an MCP tool call can map into uai.intent.request.v1, and an A2A Agent Card can map into uai.capability.statement.v1, but UAI-1 does not take over those runtime protocols. For a NuGet package, this strongly argues for a bridge/adapter architecture with optional MCP/A2A translators, not a package that pretends UAIX replaces them.
Recommended architecture
The most defensible package shape is a single umbrella package with a small, stable core and optional add-ons:
UaiBridge.Net.Corefor models, serialization, canonicalization, negotiation, errors, and policy.UaiBridge.Net.AspNetCorefor discovery endpoints, L0/L1 artifacts, REST handlers, Problem Details, and DI.UaiBridge.Net.Grpcfor internal high-throughput transport bindings.UaiBridge.Net.Pluginsfor plugin discovery/loading.UaiBridge.Net.Testingfor fixtures, golden files, validator adapters, and interop harnesses.
If you want only one public package ID, ship UaiBridge.Net as the meta-package and keep the others as implementation packages. I would not recommend using UAIX in the package ID unless you control that branding or have permission, because UAIX’s public governance pages explicitly warn against inferring broader endorsement, certification, or trademark rights from public availability alone.
flowchart LR
A[Calling Agent or Runtime] --> B[UaiBridge.Net Facade]
B --> C[Discovery and Negotiation]
B --> D[Message Pipeline]
B --> E[Policy Engine]
B --> F[Execution Adapters]
B --> G[Conformance Bridge]
C --> C1[Catalog / Discovery]
C --> C2[Capability Statement]
C --> C3[Capability Negotiation]
C --> C4[L0 L1 Artifact Generator]
D --> D1[System.Text.Json Codecs]
D --> D2[Keyless Ordered JSON Codec]
D --> D3[JCS Canonicalization]
D --> D4[JWS Envelope Signing]
E --> E1[Matrix Resolver]
E --> E2[GET-Action Guardrails]
E --> E3[No-Op Generator]
E --> E4[Memory Firewall]
E --> E5[Idempotency and Replay Control]
F --> F1[HTTPS REST Adapter]
F --> F2[gRPC Adapter]
F --> F3[Browser Fallback Adapter]
F --> F4[Worker Process or Container Sandbox]
G --> G1[UAIX Validator]
G --> G2[Mock Exchange]
G --> G3[Conformance Pack]
G --> G4[Golden Fixtures]
F1 <--> H[Peer UAIX Agent or Service]
F2 <--> H
C1 --> I[UAIX Public Records]
G1 --> I
G2 --> I
G3 --> I
This diagram intentionally mirrors the published UAIX split between discovery, profiles, validation, examples, and runtime execution boundaries. The bridge owns the public contract, policy, downgrade logic, and evidence generation; execution adapters own transport and local tool/runtime invocation; and the validator bridge keeps the implementation anchored to live schemas, examples, and conformance artifacts. That lines up with the Bridge Track boundary, the published route inventory, the memory firewall guidance, and the capability-adaptive records.
The most important internal abstraction is a single source-of-truth route and capability registry. From that one registry, the package should generate the L0 static artifacts (llms.txt, sitemap references, human-readable docs links), the L1 machine discovery records (capability statement, schema links, supported operations, constraints), the L2 browser fallback declarations, the L3+ structured POST handlers, and the No-Op / human_review_required responses. That follows directly from the matrix requirement that route records name ability level, method, content type, side-effect status, result URL field, restore/readback field, browser-form equivalent, and blocked-fallback behavior.
UAIX level mapping and protocol design
The table below is the recommended .NET mapping synthesized from the Agent Executability Matrix, the published client profiles, the schema catalog, and the GET-Action / No-Op / memory firewall records, with Microsoft’s HTTP/gRPC/plugin guidance used for concrete .NET surface choices.
| UAIX level | Published expectation | Recommended .NET surface | Primary data models and automatic behavior |
|---|---|---|---|
| L0 | Static route discovery; no implied POST/auth/tooling | Static file + minimal discovery middleware | UaixManifest, NoOpResponse; emit llms.txt, sitemap hints, canonical docs links, review URLs |
| L1 | Manifest/schema discovery; explicit capability limits | GET /uaix/discovery, GET /uaix/capabilities; typed HttpClient fetch | CapabilityStatementBody, CapabilityProfileBody; emit safe-read status, unsupported actions, low-capability fallbacks |
| L2 | Browser-open plus visible form submission | Browser fallback descriptors and HTML form adapters | BrowserFallbackDescriptor; require human-visible flow, no autonomous write authority |
| L3 | Structured HTTP JSON POST | ASP.NET Core REST endpoints + typed clients | uai.intent.*, uai.agent.message, uai.agent.ack, uai.error; POST-first, Problem Details errors |
| L4 | Authenticated owner mutation | Auth handlers + idempotency/replay stores | OAuth2/mTLS/DPoP + uai.capability.negotiation; signed envelopes for evidence-bearing writes |
| L5 | Restore/readback verification | Resource readback/status endpoints + consistency checker | uai.task.status, restore URL/result URL tracking; post-write public-safe verification route |
| L6 | Multi-agent handoff/reporting | Orchestration adapters + durable state/evidence sinks | uai.agent.handoff, uai.agent.final-report, uai.agent.memory-proposal, uai.agent.correction |
| L7 | Site-specific capability negotiation with named fallbacks | Extension registry + negotiation plug-ins | Extension manifest + uai.capability.negotiation; downgrade to L3/L1/no-op when extension unsupported |
A key design insight is that L7 should not be a hard-coded “super-agent mode.” In the currently published material, L7 appears in the matrix as site-specific negotiation, but the published client/body profiles in the main schema catalog run through L6. In practice, that means your package should implement L7 as namespaced extension negotiation driven by a capability-extension registry and explicit fallback contracts, not by special-casing an undocumented protocol layer in the core serializer.
For the protocol itself, I recommend a three-phase interaction model:
discovery, negotiation, and execution. During discovery, the caller fetches low-cost machine-readable metadata and canonical human links. During negotiation, the caller either sends an explicit capability profile or the server derives one from the current channel and selects the highest safe supported level using uai.capability.negotiation.v1. During execution, the caller uses the selected route family: low-capability GET/No-Op for L0/L1, browser fallback for L2, structured JSON POST for L3+, plus auth, readback, and evidence requirements layered on at L4-L6. When the required level cannot be proven, the server should stop safely and return a No-Op / human-review response instead of guessing, retrying, or synthesizing hidden steps.
The package should also expose capability discovery in two forms. First, there should be out-of-band discovery, which is cheap for crawlers, low-capability agents, and preflight tooling. Second, there should be in-band discovery, represented by uai.capability.statement.v1, which is the proper typed message contract for discovery-facing operations, input/output profiles, async profiles, security schemes, transport bindings, endpoints, and extensions. The out-of-band surface should be auto-generated from the same internal registry as the in-band capability statement to prevent drift.
The example flows below show what “automatic accommodation across all levels” should look like in practice. These are implementation recommendations grounded in the published matrix, the GET-Action and No-Op records, and the published UAI examples for capability negotiation, agent message, acknowledgement, task-status, handoff, and final-report.
| Level | Example flow |
|---|---|
| L0 | GET / → discover canonical docs / review URL / llms.txt → if action requested, return human_review_required with a public URL |
| L1 | GET /uaix/discovery → fetch schema/registry/capability statement → if unsupported, return explicit fallback or no-op |
| L2 | GET /uaix/browser-flow/{operation} → open visible form / browser workflow → human completes or approves → public confirmation URL |
| L3 | POST /uaix/negotiate with uai.capability.profile.v1 → selected uai.capability.negotiation.v1 → POST /uaix/agents/messages with uai.agent.message.v1 → uai.agent.ack.v1 or uai.agent.blocker.v1 |
| L4 | L3 flow + OAuth2 client credentials + mTLS or DPoP → signed envelope / owned mutation → async accept or structured error |
| L5 | L4 create/update → uai.task.status.v1 or restore URL → GET /uaix/readback/{id} → verify state, checksum, or public-safe status |
| L6 | L4/L5 flow + uai.agent.task-status.v1 updates → optional uai.agent.memory-proposal.v1 / uai.agent.handoff.v1 → uai.agent.final-report.v1 with conformance evidence |
| L7 | GET /uaix/extensions or extension block in capability statement → select named site-specific extension → if unsupported, downgrade to L3/L1 or emit No-Op |
Message formats, versioning, security, and extensibility
The format decision is straightforward once the UAIX sources are read together: keyed JSON should be the canonical representation of every message, because that is the form directly aligned with the published schemas, examples, registry, field order, validator, mock exchange, and OpenAPI surface. Keyless ordered JSON is useful as an optimization because UAIX publishes a field registry and ordered body definitions for it, but it should remain a secondary wire optimization. JSON-LD is attractive for semantic interoperability, but it should be an optional overlay for discovery or graph-export scenarios rather than the baseline UAI wire form, because UAIX today publishes keyed/keyless JSON contracts rather than JSON-LD contexts as the public validator truth. Protobuf, MessagePack, and CBOR are valuable optional codecs for internal links, but they should round-trip through the canonical keyed JSON model before signing, hashing, or validator submission.
| Category | Option | Best fit | Pros | Cons | Recommendation |
|---|---|---|---|---|---|
| Serialization | Keyed JSON | Public UAIX surface | Human-readable; validator-aligned; OpenAPI-friendly | Larger payloads | Primary canonical form |
| Serialization | Keyless ordered JSON | Trusted or bandwidth-sensitive links | Smaller than keyed JSON; UAIX field order is published | Harder debugging and ad hoc tooling | Optional optimization |
| Serialization | JSON-LD | Semantic overlays / graph export | Linked-data semantics; extensible contexts | More processing complexity; not current UAIX validator baseline | Optional adjunct only |
| Serialization | Protobuf | Internal L3-L6 high-throughput | Compact, typed, fast | Requires schema translation; not canonical UAIX truth | Optional secondary binding |
| Serialization | MessagePack / CBOR | Embedded or constrained transport | Compact, cross-language | Harder inspection/signature workflows; not public UAIX baseline | Niche binding |
| Transport | HTTPS REST | Default public transport | Matches UAIX routes and OpenAPI 3.1 | Higher overhead than binary RPC | Default |
| Transport | GET-Action | L0/L1 bounded fallback | Reachable by low-capability agents | Severe security limits; not a POST replacement | Use sparingly |
| Transport | gRPC | Internal .NET-to-.NET or trusted partner links | Strong streaming, auth, DI, logging integration | Poor fit for L0/L1 and public evidence surface | Secondary binding |
| Authentication | HTTPS public-web | Discovery/read-only | Simple and universal | No mutation ownership | Discovery only |
| Authentication | JWS signed envelope | Evidence-bearing exchange | Integrity/non-repudiation; detached signing possible | Canonicalization overhead | Add for high-assurance flows |
| Authentication | OAuth2 + mTLS | Server-to-server owned mutation | Strong service identity; sender-constrained tokens | PKI and cert lifecycle overhead | Preferred L4/L5 default |
| Authentication | OAuth2 + DPoP | Clients where mTLS is awkward | Sender-constrained without mTLS | Replay-state and proof validation complexity | Good alternative |
This comparison follows the UAIX route and schema model, the W3C JSON-LD recommendation, the Protobuf and CBOR standards, the MessagePack spec, Microsoft’s gRPC guidance, UAIX’s GET-Action guidance, the TLS/JWS/OAuth RFCs, and the DPoP/mTLS extensions.
For versioning, I recommend two parallel tracks. The NuGet package version should use SemVer 2.0.0, with the package version as the primary public version number in your docs, and prerelease suffixes for non-stable drops. The wire contract should remain anchored to uai_version and profile, with additive evolution happening through new profiles, optional extension namespaces, or transport-specific bindings that preserve canonical semantics. Do not silently reinterpret existing profile semantics under the same profile ID; that defeats the value of UAIX’s schema/registry/field-order model.
Security needs to be treated as a policy pipeline, not as a couple of decorators. UAIX’s API reference says failures should use RFC 9457-style application/problem+json with UAIX codes, retry guidance, and evidence flags. UAIX’s GET-Action guidance requires idempotency, human consent for sensitive actions, auditability, crawler protection, and no secrets in query strings, and its security guidance explicitly starts from the assumption that URLs leak. The memory firewall adds another critical rule: incoming packets are quarantined public data until validated and accepted by local policy, and ambiguous authority, missing provenance, missing integrity, or conflicting memory should trigger No-Op plus human review.
For .NET specifically, the package should assume that in-process code loading is not a security boundary. Microsoft documents that CAS is deprecated and not honored in modern .NET, and the current plugin tutorial positions AssemblyLoadContext and AssemblyDependencyResolver as dependency-isolation mechanisms for plugin loading. The right split is therefore: use AssemblyLoadContext for compatibility and unloadability of trusted plugins, but use a worker process, sidecar service, or container for anything untrusted or tool-executing.
The package’s plugin model should therefore be capability-oriented. I recommend plug-in contracts for transports, trust channels, capability extensions, policy evaluators, and execution adapters. In practical terms: IUaixTransportBinding, IUaixTrustChannel, IUaixCapabilityExtension, IUaixPolicyEvaluator, and IUaixExecutionAdapter. The IUaixCapabilityExtension path is the cleanest place to handle L7. That keeps site-specific negotiation out of the canonical serializer and makes downgrade/no-op logic testable. The package loader can use custom AssemblyLoadContext for trusted extensions and redirect untrusted execution adapters to isolated workers.
A representative C# API surface is below. It is intentionally centered on the canonical envelope, negotiation, and lifecycle packets instead of on a custom runtime object model.
using System.ComponentModel.DataAnnotations;
namespace UaiBridge.Net;
/// <summary>
/// Sends and receives UAI envelopes after capability discovery and negotiation.
/// </summary>
public interface IUaixAgentClient
{
/// <summary>
/// Discovers a remote UAIX surface and negotiates the safest supported execution level.
/// </summary>
/// <param name="baseUri">The remote agent or service base URI.</param>
/// <param name="capabilityProfile">The local capability profile to advertise.</param>
/// <param name="cancellationToken">The cancellation token.</param>
Task<UaiEnvelope<CapabilityNegotiationBody>> DiscoverAndNegotiateAsync(
Uri baseUri,
UaiEnvelope<CapabilityProfileBody> capabilityProfile,
CancellationToken cancellationToken = default);
/// <summary>
/// Sends a UAI agent message over the negotiated transport and returns the first structured response.
/// </summary>
/// <param name="request">The agent message envelope to transmit.</param>
/// <param name="cancellationToken">The cancellation token.</param>
Task<UaiEnvelope<AgentAckBody>> SendAsync(
UaiEnvelope<AgentMessageBody> request,
CancellationToken cancellationToken = default);
}
/// <summary>
/// Represents the canonical UAI envelope.
/// </summary>
/// <typeparam name="TBody">The profile-specific body type.</typeparam>
public sealed class UaiEnvelope<TBody>
{
[Display(Name = "Uai Version")]
public string UaiVersion { get; set; } = "1.0";
[Display(Name = "Profile")]
public string Profile { get; set; } = string.Empty;
[Display(Name = "Message")]
public string MessageId { get; set; } = string.Empty;
[Display(Name = "Source")]
public UaiParty Source { get; set; } = new();
[Display(Name = "Target")]
public UaiParty Target { get; set; } = new();
[Display(Name = "Conversation")]
public UaiConversation Conversation { get; set; } = new();
[Display(Name = "Delivery")]
public UaiDelivery Delivery { get; set; } = new();
[Display(Name = "Trust")]
public UaiTrust Trust { get; set; } = new();
[Display(Name = "Body")]
public TBody Body { get; set; } = default!;
[Display(Name = "Integrity")]
public UaiIntegrity Integrity { get; set; } = new();
}
public sealed class UaiParty
{
[Display(Name = "Type")]
public string Type { get; set; } = "agent";
[Display(Name = "Label")]
public string Label { get; set; } = string.Empty;
[Display(Name = "Uri")]
public Uri? Uri { get; set; }
[Display(Name = "Did")]
public string? Did { get; set; }
[Display(Name = "Role")]
public string? Role { get; set; }
[Display(Name = "Implementation")]
public string? Implementation { get; set; }
[Display(Name = "Project")]
public string? Project { get; set; }
[Display(Name = "Id")]
public string Id { get; set; } = string.Empty;
}
public sealed class UaiConversation
{
[Display(Name = "Conversation")]
public string ConversationId { get; set; } = string.Empty;
[Display(Name = "Turn")]
public string TurnId { get; set; } = string.Empty;
[Display(Name = "Parent Message")]
public string? ParentMessageId { get; set; }
[Display(Name = "Traceparent")]
public string? Traceparent { get; set; }
[Display(Name = "Sequence")]
public int Sequence { get; set; }
}
public sealed class UaiDelivery
{
[Display(Name = "Mode")]
public string Mode { get; set; } = "sync";
[Display(Name = "Priority")]
public string Priority { get; set; } = "interactive";
[Display(Name = "Expires At")]
public DateTimeOffset? ExpiresAt { get; set; }
[Display(Name = "Reply Requested")]
public bool ReplyRequested { get; set; }
[Display(Name = "Ack Required")]
public bool AckRequired { get; set; }
[Display(Name = "Task Ref")]
public string? TaskRef { get; set; }
[Display(Name = "Idempotency Key")]
public string? IdempotencyKey { get; set; }
[Display(Name = "Timeout Ms")]
public int? TimeoutMs { get; set; }
[Display(Name = "Fallback Directive")]
public string? FallbackDirective { get; set; }
}
public sealed class UaiTrust
{
[Display(Name = "Channel")]
public string Channel { get; set; } = "signed-envelope";
[Display(Name = "Auth Scheme")]
public string AuthScheme { get; set; } = "https";
[Display(Name = "Principal")]
public string? Principal { get; set; }
[Display(Name = "Credential Ref")]
public Uri? CredentialRef { get; set; }
[Display(Name = "Signature Ref")]
public Uri? SignatureRef { get; set; }
[Display(Name = "Replay Window")]
public string? ReplayWindowId { get; set; }
}
public sealed class UaiIntegrity
{
[Display(Name = "Version")]
public int Version { get; set; } = 1;
[Display(Name = "Algorithm")]
public string Algorithm { get; set; } = "sha256";
[Display(Name = "Canonicalization")]
public string Canonicalization { get; set; } = "jcs";
[Display(Name = "Checksum")]
public string? Checksum { get; set; }
}
public sealed class CapabilityProfileBody
{
[Display(Name = "Client Level")]
public string ClientLevel { get; set; } = "L3";
[Display(Name = "Client Name")]
public string ClientName { get; set; } = "UaiBridge.Net";
[Display(Name = "Can Fetch Static")]
public bool CanFetchStatic { get; set; } = true;
[Display(Name = "Can Fetch Json")]
public bool CanFetchJson { get; set; } = true;
[Display(Name = "Can Post Data")]
public bool CanPostData { get; set; } = true;
[Display(Name = "Can Authenticate")]
public bool CanAuthenticate { get; set; }
[Display(Name = "Can Call Tools")]
public bool CanCallTools { get; set; }
[Display(Name = "Can Run Long Tasks")]
public bool CanRunLongTasks { get; set; }
[Display(Name = "Can Store Memory")]
public bool CanStoreMemory { get; set; }
[Display(Name = "Can Coordinate Agents")]
public bool CanCoordinateAgents { get; set; }
[Display(Name = "Fallback Behavior")]
public string FallbackBehavior { get; set; } = "downgrade-or-no-op";
[Display(Name = "Known Limits")]
public string[] KnownLimits { get; set; } = Array.Empty<string>();
[Display(Name = "Evidence Requirements")]
public string[] EvidenceRequirements { get; set; } = Array.Empty<string>();
}
public sealed class CapabilityNegotiationBody
{
[Display(Name = "Negotiation")]
public string NegotiationId { get; set; } = string.Empty;
[Display(Name = "Requested Client Level")]
public string RequestedClientLevel { get; set; } = string.Empty;
[Display(Name = "Observed Client Level")]
public string ObservedClientLevel { get; set; } = string.Empty;
[Display(Name = "Selected Client Level")]
public string SelectedClientLevel { get; set; } = string.Empty;
[Display(Name = "Selected Profile")]
public string SelectedProfile { get; set; } = string.Empty;
[Display(Name = "Requested Operation")]
public string RequestedOperation { get; set; } = string.Empty;
[Display(Name = "Unsupported Features")]
public string[] UnsupportedFeatures { get; set; } = Array.Empty<string>();
[Display(Name = "Fallback Behavior")]
public string FallbackBehavior { get; set; } = string.Empty;
[Display(Name = "Consent Boundaries")]
public string[] ConsentBoundaries { get; set; } = Array.Empty<string>();
[Display(Name = "Evidence Requirements")]
public string[] EvidenceRequirements { get; set; } = Array.Empty<string>();
[Display(Name = "Safe Default Response")]
public string SafeDefaultResponse { get; set; } = string.Empty;
}
public sealed class AgentMessageBody
{
[Display(Name = "Message Type")]
public string MessageType { get; set; } = "directive";
[Display(Name = "Content")]
public string Content { get; set; } = string.Empty;
[Display(Name = "Context Refs")]
public Uri[] ContextRefs { get; set; } = Array.Empty<Uri>();
[Display(Name = "Requires Acknowledgement")]
public bool RequiresAcknowledgement { get; set; } = true;
[Display(Name = "Intent Semantics")]
public string IntentSemantics { get; set; } = "delegation";
[Display(Name = "Action Type")]
public string? ActionType { get; set; }
[Display(Name = "Execution Constraints")]
public Dictionary<string, object?> ExecutionConstraints { get; set; } = new();
[Display(Name = "Support Boundary")]
public string SupportBoundary { get; set; } =
"Agent runtimes execute. UAI records the reviewed communication boundary.";
}
public sealed class AgentAckBody
{
[Display(Name = "Acknowledged Message")]
public string AcknowledgedMessageId { get; set; } = string.Empty;
[Display(Name = "Status")]
public string Status { get; set; } = "validated";
[Display(Name = "Received At Utc")]
public DateTimeOffset ReceivedAtUtc { get; set; }
[Display(Name = "Closes Acknowledgement Loop")]
public bool ClosesAcknowledgementLoop { get; set; } = true;
[Display(Name = "Support Boundary")]
public string SupportBoundary { get; set; } =
"Agent runtimes execute. UAI records the reviewed communication boundary.";
}
This API shape follows the published UAI envelope and body fields, preserves the separation between discovery/negotiation/execution, and leaves room for multiple transport bindings and trust channels without letting any one of them redefine the canonical model. It is also intentionally conservative about security: the trust model is declarative in the envelope, while actual credential validation and execution stay in separate layers.
Testing, performance, packaging, and roadmap
A credible UAIX package needs unit tests, integration tests, and interop tests that are shaped by the published artifacts, not just by local code paths. UAIX explicitly publishes schemas, examples, a validator, a mock exchange route, an adoption kit, and a conformance pack. That gives you a rare advantage: your CI can test not only internal correctness but also live profile compatibility, negative cases, and evidence production.
| Test layer | Sample cases | Success criteria |
|---|---|---|
| Unit | Envelope serialization keyed ↔ keyless; body order matches field registry; JCS hash stable for semantically identical keyed JSON; level downgrade logic; no-op trigger mapping | Exact field order; deterministic checksum; unknown or higher-than-supported levels downgrade correctly |
| Integration | REST negotiation endpoint; agent message POST; Problem Details error path; GET-Action secret rejection; restore/readback route; auth middleware | Correct HTTP status/content-type; RFC 9457-style body; blocked URLs with secrets; idempotency and replay checks enforced |
| Interop | Submit generated packets to UAIX validator; compare against published examples; exercise mock exchange; ingest conformance pack fixtures | Validator pass for supported profiles; expected fail/warn on negative fixtures; no drift from published examples |
| Security negative | Expired message; missing integrity; conflicting memory; unsupported capability; missing human consent | uai.error.v1, uai.agent.blocker.v1, or no-op/human_review_required returned as appropriate |
| Performance | JSON serialization throughput; canonicalization cost; gRPC transport throughput; ack/status flow latency | p50/p95/p99 targets documented and repeatable in CI perf job |
The most valuable interop plan is a matrix plan. Stand up one test peer for each level L0-L7, publish the same operation through progressively richer route families, and verify that the package always picks the highest safe path, not the most featureful path. That means, for example: a requested L5 operation from an observed L3 client should produce a negotiation result like the published UAIX example does; a write-capable request routed through GET-Action should be rejected if it tries to place protected material in the URL; and missing restore/readback on an L5 claim should fail your own conformance gate even before live release.
Performance-wise, the clear default is System.Text.Json with source generation for the canonical JSON path, because Microsoft documents both metadata-based and serialization-optimized modes, and because UAIX’s field-order governance is deterministic enough to make source-generated serializers practical. Use IHttpClientFactory for outbound REST clients, and add gRPC only for secondary trusted bindings where streaming or throughput justifies it. Compute JCS canonicalization only at signature/hash boundaries, not on every in-memory transform, because canonicalization is a correctness mechanism first and a throughput trade-off second.
Packaging and release should follow modern NuGet conventions. Build with dotnet pack; use an SPDX license expression; include a README in the package; publish symbols as .snupkg; keep a nuget.config in the repo for repeatability; use GitHub Actions with setup-dotnet; prefer nuget.org Trusted Publishing to long-lived API keys; and sign release packages where your release process and certificate management justify it. Signed packages provide integrity/authenticity benefits, and modern .NET/NuGet tooling can verify signatures during restore or with explicit verification commands.
A representative package metadata baseline would look like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<PackageId>UaiBridge.Net</PackageId>
<Version>0.1.0-alpha.1</Version>
<Authors>Your Organization</Authors>
<Description>UAIX-compliant UAI-1 bridge for .NET 6+ with capability-adaptive discovery, negotiation, execution, and evidence support.</Description>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/your-org/uai-bridge-net</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
</Project>
A minimal GitHub Actions release flow should do restore → build → test → pack → publish, with a separate release job gated on tags or GitHub Releases and configured for OIDC-based trusted publishing to nuget.org. If you adopt package signing, make it part of the release job and verify the signed artifact before push.
The implementation roadmap below is prioritized for delivery order, not for parallel staffing.
| Milestone | Scope | Estimated effort |
|---|---|---|
| Core contract | Canonical envelope, profile bodies, keyed/keyless codecs, field-order mapping, Problem Details error model, package scaffolding | 8 person-days |
| Discovery layer | Catalog/discovery endpoints, capability statement generation, L0/L1 artifact generation, no-op responses | 7 person-days |
| Negotiation layer | Capability profile + negotiation model, downgrade resolver, route selection, level-aware dispatcher | 8 person-days |
| Execution layer | L3 REST handlers/clients, agent message/ack/blocker/task-status flows, idempotency store | 10 person-days |
| Auth and owned mutation | OAuth2 integration hooks, mTLS/DPoP abstractions, replay control, audit hooks for L4 | 10 person-days |
| Restore/readback and async | L5 verification routes, task-status model, correlation/readback verification | 7 person-days |
| Handoff and evidence | L6 handoff/final-report/memory-proposal/correction, conformance evidence capture | 9 person-days |
| L7 extension model | Extension registry, plug-in contracts, downgrade rules, site-specific capability adapter model | 8 person-days |
| Plugin isolation | Trusted plugin loading with AssemblyLoadContext; isolated worker adapter for untrusted execution | 6 person-days |
| CI/CD and docs | GitHub Actions, package metadata, symbols, samples, README, live validator interop pipeline | 7 person-days |
Total estimated effort: 80 person-days for a production-grade first release, or 43–48 person-days for a narrower initial release that stops at L4 and defers L5-L7 plus plugin isolation. That estimate is justified by the breadth of the published profile catalog, the need for live validator interop, the multiple transport/auth layers, and the requirement to accommodate every matrix level rather than just the L3 happy path.
Legal, IP, licensing, and open questions
The first legal point is authority and branding. UAIX’s .NET NuGet page says UAIX.org remains the public authority for UAI-1 and that the existing Protocol5 package distribution should not be cited as standards authority, registry authority, governance authority, certification, endorsement, or a broader SDK program. UAIX’s governance pages also say that packaged artifacts should be evaluated against their own shipped headers, notices, and bundled source terms, and that public availability alone should not be read as a broader trademark, certification, or endorsement right. So if you ship an independent package, the safest posture is: UAIX-compliant, UAI-1 compatible, or UAI bridge for .NET—not “official UAIX SDK” unless you actually control that designation.
For the package’s own open-source license, my recommendation is:
| License | Best use | Rationale |
|---|---|---|
| Apache-2.0 | Core library | Strong permissive choice for infrastructure libraries; clean for NuGet SPDX metadata |
| MIT | Samples, playgrounds, simple adapters | Minimal friction for example code and community uptake |
| MPL-2.0 | Optional alternative if you want contribution reciprocity without full copyleft | Good middle ground when you want modified files returned to the community |
On NuGet, express the license with an SPDX license expression rather than an old licenseUrl, and keep the package README and notices inside the package itself.
If you sign packages, treat package metadata as effectively immutable for release purposes. NuGet recommends package signing, and signed package validation is part of modern tooling, but NuGet also notes that editing package metadata after upload changes the nuspec and invalidates signatures. That argues for a release process in which package metadata, README, licenses, and release notes are finalized before artifact signing and publish.
The biggest substantive limitation in the current public materials is L7. The matrix clearly defines L7 as site-specific capability negotiation, but the primary published client/body profiles in the schema catalog top out at L6. That is why I recommend implementing L7 as an extension negotiation framework instead of as a fixed built-in schema. A second limitation is that while UAIX publishes transport-bindings and trust-channels routes in the API inventory, this report did not inspect their full live payloads; before you freeze security scheme names or transport IDs in code, your CI should pull those live records and verify alignment.
References
The following primary references are the ones I would treat as the authoritative engineering baseline for this package design:
- UAIX capability and execution records: Capability-Adaptive Agent Interoperability, Agent Executability Matrix, GET-Action Pattern, GET-Action Security Boundaries, No-Op Protocol, Memory Firewall, Schemas, Registry, API Reference, .NET Bridge Track, .NET NuGet Package, Standards Fit, Policy and Security.
- IETF / W3C protocol references: RFC 9457 Problem Details, RFC 8785 JCS, RFC 7515 JWS, RFC 6749 OAuth 2.0, RFC 8705 OAuth mTLS, RFC 9449 DPoP, RFC 8446 TLS 1.3, JSON-LD 1.1, RFC 8949 CBOR.
- Major .NET and NuGet docs:
IHttpClientFactory,System.Text.Jsonsource generation, gRPC on .NET, plugin support withAssemblyLoadContext, NuGet package creation, versioning guidance, package signing/verification, Trusted Publishing, README support, symbol packages,nuget.config, and GitHub Actions .NET guidance.