Skip to content

Guided tour

FabrCore 2.0 · Release and package availability

These guides track the current 2.0 source. Stable 2.0.0 publication is pending; package commands show the release target. Until it is published, follow the source quick start or use a matching available prerelease set. Release migration · Runtime modes

MODULE 02 · LESSON 2.2

Address principals, agents, and conversations

Use stable principal, agent and conversation identities.

Lesson 7 of 86 · FabrCore 2.0

Overview

A fully qualified handle has the form principal:agent. The principal partitions ownership; the agent portion identifies an instance. A thread identifies conversation history within that instance. Channel identifies how a turn arrived, not who is authorized to send it.

Principal, instance and thread are different keys

dev:assistant identifies an agent instance owned by dev. The same local name under another principal identifies a different instance. A thread is a history selection inside that instance; it does not create another owner. A registered type alias can back many instances. This is why copying the same agent class into two applications is not necessary to give users separate conversations.

Where identity must come from

At an HTTP boundary the application authenticates the caller and maps that identity to a principal. Message text, channel labels and client-supplied arguments are not identity evidence. Inside trusted code, handle helpers normalize or qualify names. Qualification makes the target unambiguous, but it does not grant permission to cross into another principal's resources.

Use explicit addresses

  1. Give each authenticated principal a stable handle. Resolve relative agent handles through trusted context instead of concatenating unvalidated input.
  2. Use HandleUtilities when parsing or qualifying addresses. Treat legacy UserHandle/GetUserHandle names as principal compatibility names.
  3. Choose stable thread IDs for conversations that should continue, and separate thread IDs when histories must be independent.
HandleUtilities API · reference snippet
HandleUtilities.BuildPrefix("principal1");                         // "principal1:"
HandleUtilities.EnsurePrefix("assistant", "principal1:");          // "principal1:assistant"
HandleUtilities.EnsurePrefix("principal2:assistant", "principal1:"); // "principal2:assistant" (unchanged)
HandleUtilities.StripPrefix("principal1:assistant", "principal1:"); // "assistant"
HandleUtilities.ParseHandle("principal1:assistant");                // ("principal1", "assistant")
HandleUtilities.ParseHandle("assistant");                 // ("", "assistant")

Check isolation with two principals

  1. Create assistant for two disposable development principals, using authenticated test identities when ingress is secured. List or inspect each instance's qualified handle; the owner part should differ.
  2. Send distinguishable inputs such as “Account A marker” and “Account B marker.” Read each conversation through its own identity and confirm the other account's marker is absent.
  3. Within one account, start a second thread using your client's supported thread selection. Verify that selecting the old thread retrieves its history instead of treating the new thread as a new principal.

Different principal names partition ownership; different threads partition conversation context within an instance. This exercise checks identity mapping and history selection together.

If the result is different

A channel name or Args value cannot establish identity. When an API accepts forwarded principal headers, the hosting application must authenticate and validate that boundary.

Go deeper

Explore the related documentation.