Scoped Registration

The scope package supplies the identity, carrier, and scoped-layer vocabulary that makes one registration context mean both per-agent visibility and shared lifetime ownership. It is a library primitive rather than a Cordis service; the agent-scope runtime-design Agent Note owns the lifecycle rationale, the shared-storage Agent Note owns the registry-layer decision, and the package README owns the callable API and filtering semantics.

Sources: packages/core/scope/src/index.ts and packages/core/scope/src/store.ts.

Identity and dispatch carrier

ScopeKey is an opaque object identity. The shipped loop uses the live Agent object as its own key, but the primitive never inspects the object.

/** An opaque, identity-compared scope key. */
type ScopeKey = object

Scoped<T> is the compile-time brand on the opaque routing receiver returned by scopeTarget(base, key). Scope-filtered event declarations require this carrier as their this type, while the real event subject remains an explicit argument.

/**
 * A routing-only event receiver built by {@link scopeTarget}. The type
 * parameter records the subject type for dispatch checking; the carrier does
 * not expose the subject's properties. Event payloads carry the real subject.
 */
type Scoped<T extends object> = object & { readonly [ScopedBrand]: T }

Owned registration context

Scope pairs the tagged registration context with two teardown paths. rawDispose preserves the exact Cordis disposer identity needed by an ordered composite effect; dispose() is the public shared quiescence boundary for direct and racing callers.

/** A minted registration scope and its quiescent disposal boundaries. */
interface Scope {
  /** Context through which scope-owned registrations are made. */
  ctx: Context
  /** Exact Cordis disposer, used when nesting this scope in an ordered composite effect. */
  rawDispose: () => Promise<void> | void
  /** Dispose every scope-owned registration; racing calls await the same completion. */
  dispose(): Promise<void>
}

Scoped registry layer

ScopeLayer represents one registry's complete contribution at the global or exact-scope level. A concrete layer may aggregate multiple named and anonymous tables; whole-layer emptiness lets ScopedLayers reclaim scoped state without discarding a sibling table.

/** One scope's aggregate contribution to a registry. */
interface ScopeLayer {
  /** Whether every table in this layer is empty. */
  isEmpty(): boolean
}

ScopedLayers<L> owns the eager global layer and lazily created exact-scope layers. Reads do not create layers: peek(undefined) means no overlay, while merge() materializes insertion-ordered global named entries followed by scoped shadows. Registrations use one context for both visibility and Cordis effect ownership, collect one synchronous undo before optional notification, return Cordis's exact disposer, and reclaim a scoped layer only when its complete ScopeLayer is empty.

NamedEntries<V> supplies insertion-ordered lookup and live iteration with caller-owned duplicate errors. AnonymousEntries<V> gives every append a unique identity so equal values remain independent. Iteration stays live within one nonempty table generation; draining the table detaches existing iterators from later insertions. Both return idempotent exact-entry undos; the shared EntryValues implementation interface is not public.

作用域注册

scope 包提供身份、载体与作用域层词汇,使同一注册上下文同时表达每个 agent(智能体)的可见性和共享生命周期所有权。它是库原语,而不是 Cordis 服务;生命周期设计理由由 agent-scope 运行时设计 Agent Note规定,注册表层决策由共享存储 Agent Note规定,可调用 API 与过滤语义则由包 README规定。

源码:packages/core/scope/src/index.tspackages/core/scope/src/store.ts

身份标识与分发载体

ScopeKey 是一个不透明的对象身份标识。已交付的 agent loop(智能体循环)使用活跃的 Agent 对象作为自身的 key,但该原语从不检视该对象。

/** An opaque, identity-compared scope key. */
type ScopeKey = object

Scoped<T> 是编译期品牌标记,标注在 scopeTarget(base, key) 返回的不透明路由接收器上。作用域过滤的事件声明要求以此载体作为 this 类型,而真正的事件主体仍作为显式参数传入。

/**
 * A routing-only event receiver built by {@link scopeTarget}. The type
 * parameter records the subject type for dispatch checking; the carrier does
 * not expose the subject's properties. Event payloads carry the real subject.
 */
type Scoped<T extends object> = object & { readonly [ScopedBrand]: T }

拥有所有权的注册上下文

Scope 将带标签的注册上下文与两个拆卸接口配对。rawDispose 保留有序复合 effect 所需的 Cordis disposer 的确切身份;dispose() 是面向直接调用方和竞态调用方的公共完全停稳边界。

/** A minted registration scope and its quiescent disposal boundaries. */
interface Scope {
  /** Context through which scope-owned registrations are made. */
  ctx: Context
  /** Exact Cordis disposer, used when nesting this scope in an ordered composite effect. */
  rawDispose: () => Promise<void> | void
  /** Dispose every scope-owned registration; racing calls await the same completion. */
  dispose(): Promise<void>
}

带作用域的注册表层

ScopeLayer 表示一个注册表在全局或确切作用域层级的完整贡献。具体 layer 可以聚合多个具名与匿名 table;整个 layer 为空时,ScopedLayers 可以回收带作用域状态,而不会丢弃兄弟 table。

/** One scope's aggregate contribution to a registry. */
interface ScopeLayer {
  /** Whether every table in this layer is empty. */
  isEmpty(): boolean
}

ScopedLayers<L> 拥有立即创建的全局 layer,以及惰性创建的确切作用域 layer。读取不会创建 layer:peek(undefined) 表示不存在作用域覆盖层,而 merge() 会依次物化按插入顺序排列的全局具名条目和带作用域的遮蔽项。注册使用同一个上下文表示可见性与 Cordis effect 所有权,在可选通知前取得一个同步撤销函数,返回 Cordis 的原始 disposer,并且只在带作用域 layer 的完整 ScopeLayer 为空时回收它。

NamedEntries<V> 提供按插入顺序的查找和动态迭代,重复项错误由调用方处理。AnonymousEntries<V> 为每次 append 分配唯一标识,因此值相等的条目仍彼此独立。在同一轮非空 table 生命周期内,迭代器可以观察后续变化;table 被清空后,现有迭代器不会再观察后续插入。两者都返回幂等、精确对应相应条目的撤销函数;共享实现接口 EntryValues 不对外公开。