WACP: Identity

WACP: Identity & Addressing

Metadata

title: "WACP: Identity & Addressing"
id: wacp-spec-identity
type: constituent-spec
tier: abstract
category: primitives
status: complete
created: 2026-02-24
lineage: PROTOCOL.md (wacp-v0.1)
protocol_sections:
  - §4.7 (identity)
  - §4.8 (user identity)
depends_on: []
authors:
  - Akil Abderrahim (Lead)
  - Claude Opus 4.6 (co-author)
tags: [wacp, identity, addressing, identifiers, naming, references]

Table of Contents

  1. Purpose
  2. Identifier Rules
  3. Uniqueness Scopes
  4. Addressing Model
  5. Reference Integrity
  6. Conformance Requirements
  7. Implementation Notes
  8. References

1. Purpose

Every protocol object — workspace, envelope, signal, checkpoint, trail entry — carries an identifier. Users also carry an identifier — user_id — with adapted rules (PROTOCOL §4.8). Identifiers are how the protocol names things, how objects reference each other, and how the trail links events to their subjects.

This spec defines the rules that all identifiers must follow, the uniqueness scope for each identifier type, and the addressing model that governs how agents and the coordinator direct messages to specific workspaces. It is the protocol’s naming system — the equivalent of an address space in an operating system.

Without well-defined identity rules, deduplication breaks, trail references become ambiguous, recovery cannot reconstruct state, and integrity verification loses its anchor points.

2. Identifier Rules

Six rules govern all identifiers in the protocol. These are universal — they apply to every identifier type without exception.

Rule 1: Runtime-assigned. All identifiers are generated by the runtime, never by agents. An agent cannot choose its workspace ID, its checkpoint IDs, or its envelope IDs. This prevents collisions, spoofing, and any dependency on agent cooperation for identity integrity.

Rule 1 adaptation for user_id. User identifiers are the one exception to runtime-assignment. user_id is assigned at the authentication boundary, not generated by the runtime — the runtime accepts and validates the identity but does not create it (PROTOCOL §4.8). This adaptation exists because users are not protocol objects created by the runtime; they are external principals whose identity originates in a deployment’s authentication layer.

Rule 2: Opaque. Identifiers are opaque strings. The protocol does not prescribe a format — UUIDs, ULIDs, sequential integers, URIs, or any scheme is valid. Implementations MUST NOT encode semantic meaning that the protocol depends on. A workspace’s parent cannot be derived from its ID. A checkpoint’s workspace cannot be inferred from its ID. Semantic relationships are expressed through explicit fields (parent, from, to, workspace), never through ID structure.

Rule 3: Unique within scope. Each identifier type has a defined uniqueness scope (see §3). No two objects of the same type within the same scope may share an identifier. The runtime MUST guarantee this at generation time.

Rule 4: Immutable. Once assigned, an identifier never changes. A workspace does not get a new ID when it transitions states. An envelope does not get a new ID when it is redelivered. Immutability is what makes the trail’s references stable — a trail entry written at minute one and read at month six points to the same object.

Rule 5: Referenceable. Any identifier can appear in another object’s fields. The protocol uses explicit reference fields — from, to, parent, workspace, checkpoint_ref, in_reply_to, ref — to express relationships. References are always by identifier, never by position, index, or implicit ordering.

Rule 6: Non-recyclable. An identifier MUST NOT be reused after the object it identifies reaches a terminal state or is no longer active. A closed workspace’s ID is retired permanently. This prevents phantom references — a trail entry referencing ws-042 always means the same workspace, regardless of when the trail is read.

3. Uniqueness Scopes

Every identifier type has a scope within which it must be unique. The scope determines how far the uniqueness guarantee extends — within a single run or across all runs the implementation has ever seen.

IdentifierScopeRationale
workspace_idGlobal (across all runs)Workspaces may be referenced in cross-run analysis, trail compaction archives, and comparison views. A workspace ID from run A must never collide with one from run B.
envelope_idGlobalRedelivery uses the same ID for deduplication (PROTOCOL §4.2). Cross-run trail analysis may compare envelope flows.
signal_idGlobalDelivery receipts in the trail reference signal IDs. Cross-run analysis requires global uniqueness.
checkpoint_idGlobalIntegration references checkpoints across workspace boundaries. Cross-run comparison references checkpoints across runs.
trail_entry_idGlobalTrail integrity mechanisms link entries by ID. Trail compaction archives entries that must remain addressable indefinitely. Monotonic within the global trail.
task_idGlobal (across runs)Tasks may be referenced in cross-run comparisons and audit. PROTOCOL §4.6 requires globally unique task IDs.
user_idGlobal (across all runs)Users persist across runs, sessions, and deployments. Cross-run audit (“what did user X do?”) requires global uniqueness. Non-recyclable: a deactivated user’s ID is retired permanently (PROTOCOL §4.8).

Global scope means the implementation’s generation scheme must produce identifiers that are unique across all runs, all workspaces, and all time. UUIDs and ULIDs satisfy this naturally. Sequential integers do not — unless prefixed with a run identifier or another disambiguation mechanism.

4. Addressing Model

Addressing determines how protocol operations target their destination. WACP uses a single addressing mechanism: workspace ID.

Workspace-addressed, not role-addressed. An envelope goes to a specific workspace, not to “the reviewer” or “a worker.” If a role has multiple workspaces, the coordinator decides which workspace receives the envelope. This keeps routing under coordinator control and ensures the permission matrix (PROTOCOL §5.5) is evaluated per-envelope against a specific sender-receiver pair.

No broadcast. The protocol has no mechanism for sending an envelope to all workspaces, to all workspaces with a given role, or to any group of workspaces. Broadcast is a coordinator-level pattern — the coordinator sends individual envelopes to each target. This is deliberate: every envelope must pass through permission validation individually. A broadcast mechanism would either bypass the permission matrix or hide the fact that N separate validations occurred.

No anonymous addressing. Every envelope has a from and a to. There is no mechanism for anonymous messages, messages with no sender, or messages routed to a pool. The trail must record who sent what to whom — anonymity would break auditability.

Signals are not addressed. Signals propagate upward through the workspace tree — from child to parent — and are not addressed to a specific workspace. The coordinator observes all signals — via direct delivery from its children and via the global trail for signals deeper in the tree. This is not addressing; it is propagation. The distinction matters: an envelope is routed to a target, a signal is emitted from a source.

Cross-reference is not cross-access. An object may reference another object’s ID — a checkpoint referencing its parent, an envelope’s in_reply_to pointing to a previous envelope, an integration event citing a checkpoint_ref. The reference does not grant access. Visibility rules (PROTOCOL §6.8) govern whether the referencing agent can actually read the referenced object. Possessing an ID is not authorization.

5. Reference Integrity

Identifiers create a web of references across protocol objects. This section defines what the protocol guarantees about those references.

Every reference MUST resolve. If an object’s field contains an identifier — an envelope’s to, a checkpoint’s parent, an integration event’s checkpoint_ref — that identifier MUST correspond to an existing object. The runtime MUST reject any operation that would create a dangling reference. There is one exception: in_reply_to and parent may be null to indicate the first message in a thread or the first checkpoint in a workspace.

References are never invalidated. Because identifiers are immutable (rule 4) and non-recyclable (rule 6), and because workspaces are never destroyed (PROTOCOL §6.4), a valid reference remains valid forever. A trail entry from the first minute of a run can be followed to its referenced objects months later. This is the foundation of the trail’s long-term auditability.

Circular references are impossible by construction. The protocol’s structure prevents reference cycles:

  • Workspaces form a tree (parent references point strictly upward).
  • Checkpoints form a chain (parent references point strictly backward in time).
  • Envelopes reference previous envelopes via in_reply_to (strictly backward).
  • Trail entries are ordered and monotonic (each entry’s ID is strictly greater than the previous).
  • Integration references checkpoints (cross-type, not self-referential).

No protocol operation can create a reference that, when followed, leads back to the originating object.

Orphan detection. If recovery encounters a trail entry whose referenced object cannot be found — a checkpoint ID that doesn’t match any known checkpoint, an envelope ID with no corresponding creation event — the entry is flagged as orphaned. Orphans indicate data loss (storage corruption, incomplete recovery) and are recorded as integrity violations in the trail.

6. Conformance Requirements

RequirementLevelDescription
Six identifier rulesCoreAll six rules (§2) MUST be satisfied for every identifier type.
Uniqueness within scopeCoreRuntime MUST guarantee uniqueness per the scope table (§3).
No dangling referencesCoreRuntime MUST reject operations that would create references to non-existent objects.
Workspace addressingCoreAll envelopes MUST be addressed by workspace ID. No broadcast, no anonymous messages.
Global scope for 7 ID typesStandardworkspace_id, envelope_id, signal_id, checkpoint_id, trail_entry_id, task_id, user_id MUST be globally unique across runs. user_id follows the Rule 1 adaptation (§2).
Reference integrity after recoveryStandardRecovery MUST detect and flag orphaned references as integrity violations.
Opaqueness enforcementFullImplementations SHOULD verify that no protocol logic depends on ID structure.

7. Implementation Notes

These notes are non-normative. They capture practical guidance for implementers.

UUIDs (v4). Random UUIDs satisfy global uniqueness with negligible collision probability. They are opaque, non-recyclable by nature, and widely supported. The tradeoff is size (36 characters) and no inherent ordering — trail entry IDs benefit from monotonicity, which random UUIDs do not provide.

ULIDs. A ULID embeds a millisecond timestamp and a random component in a single sortable string. This satisfies global uniqueness, provides natural monotonicity for trail entry IDs, and is lexicographically sortable. The embedded timestamp is a convenience for humans, not a protocol dependency — the protocol’s ordering comes from the Clock spec, not from ID structure. ULIDs are the recommended scheme for implementations that want a single ID format across all types.

Sequential integers with run prefix. A scheme like run-007:ws-042 satisfies global uniqueness through the run prefix and is compact and human-readable. The tradeoff is that the prefix introduces structure — implementations must ensure no protocol logic parses or depends on it (rule 2). This scheme works well for single-runtime deployments where simplicity is valued over portability.

Trail entry IDs. Trail entry IDs have a unique requirement: they must be monotonic within the global trail to support integrity verification. ULIDs satisfy this naturally. Sequential integers satisfy this trivially. Random UUIDs do not — if using UUIDs for trail entries, the implementation must maintain a separate monotonic counter or sequence number alongside the UUID.

8. References

PROTOCOL.md

SectionReferenced inTopic
§4.2§3Envelope — redelivery deduplication uses envelope ID
§4.6§3Task — globally unique task IDs
§4.7§1, §2, §3Identity rules (defines this spec)
§4.8§2, §3User identity — user_id adaptation, non-recyclable
§5.5§4Permission matrix — evaluated per sender-receiver pair
§6.4§5Workspaces are never destroyed — references never invalidated
§6.8§4Visibility and authority — possessing an ID is not authorization

Constituent Specs

SpecReferenced inTopic
Recovery spec§5Orphan detection during recovery
Security spec§5Integrity violations — orphaned references
Trail spec§3, §5Trail entry ID monotonicity, integrity mechanisms

WACP constituent specification — authored by Akil Abderrahim and Claude Opus 4.6 Protocol: PROTOCOL.md | Taxonomy: TAXONOMY.md