# Branded Types for ID Semantic Attribution in the Magnitude Codebase

> Discover how Magnitude uses Effect-TS branded types for type-safe ID attribution. Learn to create nominal types to prevent accidental mixing across domains.

- Repository: [Magnitude/magnitude](https://github.com/magnitudedev/magnitude)
- Tags: internals
- Published: 2026-09-08

---

**Magnitude leverages Effect-TS branded types to enforce type-safe ID boundaries, intersecting primitive strings with `Brand.Brand<"…">` to create nominal types that cannot be accidentally mixed across domains.**

The `magnitudedev/magnitude` repository implements a defensive type-safety strategy using branded types to distinguish semantically different identifiers. By combining primitive strings with unique brand markers from the Effect-TS library, the codebase prevents subtle runtime bugs caused by passing the wrong ID to the wrong function. This pattern creates **opaque, nominal types** that exist only at compile time while remaining plain strings at runtime, ensuring zero performance overhead with maximum type safety.

## Effect-TS Branding Pattern Implementation

The codebase constructs branded types by intersecting the base `string` type with `Brand.Brand<"Label">`, then exposing a nominal constructor through `Brand.nominal<T>()`. This approach treats structurally identical types as distinct, preventing accidental cross-contamination between different ID domains.

### The Nominal Type Constructor

In [`packages/launcher/src/cli-binary-resolver.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/launcher/src/cli-binary-resolver.ts), the pattern appears as:

```typescript
import { Brand } from "effect"

export type ExecutablePath = string & Brand.Brand<"ExecutablePath">
export const ExecutablePath = Brand.nominal<ExecutablePath>()

```

The `Brand.nominal<T>()` function generates a companion object (here also named `ExecutablePath`) containing the `.of()` method. This method narrows a plain string into the branded type at compile time without adding runtime wrapper objects, preserving the string primitive for serialization and storage.

## Core Branded ID Types by Domain

Magnitude defines specific branded types across its monorepo packages to enforce semantic boundaries between unrelated identifier concepts.

### ExecutablePath for Launcher Binaries

Located in [`packages/launcher/src/cli-binary-resolver.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/launcher/src/cli-binary-resolver.ts), the **ExecutablePath** type represents absolute file system paths to launcher binaries:

```typescript
export type ExecutablePath = string & Brand.Brand<"ExecutablePath">

```

This prevents accidental passing of relative paths or arbitrary strings to functions expecting resolved, absolute binary locations.

### Mutation State Identifiers in Effect-Query

The [`packages/effect-query/src/Model.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/effect-query/src/Model.ts) file defines two complementary branded types for cache management:

- **MutationStateId**: `string & Brand.Brand<"MutationStateId">` — Uniquely identifies a persisted mutation state in the query-layer cache.
- **MutationScope**: `string & Brand.Brand<"MutationScope">` — Scopes mutation IDs to specific logical domains (e.g., user sessions or project contexts).

These types ensure that cache keys cannot be confused with scope identifiers, preventing invalidation logic errors.

### Agent Runtime Event IDs

In [`packages/agent/src/events.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/agent/src/events.ts), the **UserBashCommandId** type tracks user-issued shell commands:

```typescript
export type UserBashCommandId = string & Brand.Brand<'UserBashCommandId'>

```

This separates bash command event identifiers from other event types in the agent's event bus system.

### ACN Protocol Recovery Tags

The [`packages/acn-protocol/src/transport/recovery.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/acn-protocol/src/transport/recovery.ts) defines **RecoveryDeclared** using a slightly different pattern:

```typescript
export type RecoveryDeclared = Brand.Brand<"RpcRecoveryDeclared">

```

Unlike the ID types, this acts as a structural tag rather than a string intersection, allowing the ACN protocol to distinguish recovery declarations from ordinary RPCs at the type level.

## Practical Usage Examples

Constructing branded type instances requires using the `.of()` method provided by the nominal brand constructor. The following patterns appear throughout the codebase:

**Creating an ExecutablePath:**

```typescript
import { ExecutablePath } from "@magnitudedev/launcher"

const path: ExecutablePath = ExecutablePath.of("/usr/local/bin/magnitude")

```

**Using MutationStateId in cache operations:**

```typescript
import { MutationStateId } from "@magnitudedev/effect-query"

const stateId: MutationStateId = MutationStateId.of("state-123")

```

**Emitting events with UserBashCommandId:**

```typescript
import { UserBashCommandId } from "@magnitudedev/agent"

const cmdId: UserBashCommandId = UserBashCommandId.of("cmd-42")
eventBus.emit({ type: "UserBashCommand", id: cmdId, command: "ls -la" })

```

At runtime, all branded IDs remain plain JavaScript strings, ensuring compatibility with JSON serialization and external APIs while maintaining strict compile-time contracts.

## Summary

- **ExecutablePath** ([`packages/launcher/src/cli-binary-resolver.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/launcher/src/cli-binary-resolver.ts)) brands absolute binary paths to prevent relative path injection.
- **MutationStateId** and **MutationScope** ([`packages/effect-query/src/Model.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/effect-query/src/Model.ts)) enforce separation between cache keys and scoping domains.
- **UserBashCommandId** ([`packages/agent/src/events.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/agent/src/events.ts)) provides type-safe tracking of shell command events.
- **RecoveryDeclared** ([`packages/acn-protocol/src/transport/recovery.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/acn-protocol/src/transport/recovery.ts)) tags RPC recovery declarations distinctly from standard procedure calls.
- The `Brand.nominal<T>()` constructor pattern creates zero-cost abstractions that disappear at runtime while preventing cross-domain ID misuse during development.

## Frequently Asked Questions

### What are branded types in TypeScript?

Branded types are a compile-time pattern that creates distinct types from identical underlying structures, typically by intersecting a primitive with a unique marker type. In Magnitude, this allows two strings representing different ID types (like `MutationStateId` and `MutationScope`) to be treated as incompatible by the TypeScript compiler, preventing accidental assignment between them despite both being strings at runtime.

### Why does Magnitude use Effect-TS Brand instead of nominal typing libraries?

Magnitude uses `effect/Brand` because it provides a standardized, well-tested implementation of nominal typing specifically designed for functional TypeScript patterns. The `Brand.nominal<T>()` constructor automatically generates the `.of()` factory method and type guards, reducing boilerplate while integrating seamlessly with Effect's ecosystem of type-safe utilities used throughout the `magnitudedev/magnitude` codebase.

### How do you convert a plain string to a branded ID at runtime?

You must use the branded type's `.of()` method, which is exposed by the `Brand.nominal()` constructor. For example, `ExecutablePath.of("/path/to/binary")` narrows a `string` to `ExecutablePath`. Direct casting or type assertions bypass the brand's safety guarantees and should be avoided in production code.

### Can branded types prevent ID confusion across network boundaries?

Branded types only enforce safety at compile time within the TypeScript codebase. Once serialized to JSON for network transmission, the brand information is lost. Magnitude relies on domain-specific parsing layers at API boundaries to reconstruct branded types using the same `.of()` constructors, ensuring that external string inputs are validated and properly branded before entering internal type-safe flows.