Agent addressing
LumenFlow’s memory layer can route coordination traffic to a specific live agent session without inventing a pack-specific side channel.
A2A.V1 release contract
Section titled “A2A.V1 release contract”Agent-to-agent coordination is defined by the exported A2A.V1 contract in
@lumenflow/control-plane-sdk/a2a:
A2ASignalV1carriesschema_version,signal_id,sender_identity,recipients[], optionalworkspace_id, thread/reply fields, intent, interrupt class, ACK requirement, message, idempotency key, origin, and existing WU/initiative/lane/role axes.A2AReceiptV1carriessignal_id,reader_identity,read_at,delivery_state, and optional idempotency key. Delivery state starts asdeliveredand is promoted toackedorrejectedwhen the recipient posts a same-threadAGREEorREJECT.- The conformance suite is published from the same package, so local memory adapters and hosted buses can prove the same visibility, routing, receipt, and convergence behavior.
The local implementation stores signals and receipts in .lumenflow/memory/,
surfaces events through generated Claude hooks, and provides mem:watch for
clients without native hooks. Those are adapters. lumenflow.cloud consumes the
same A2A.V1 schema over a hosted transport, where workspace_id is required
as the tenant/workspace routing key even though local worktrees may omit it.
This release is a minor-compatible addition while target_agent remains a
deprecated read-compatible alias for the first entry in recipients[].
Removing that alias would be a major-version change.
Live roster
Section titled “Live roster”Use mem:roster to see active sessions, their ephemeral display_name,
explicit agent_identity, role axes, current WU, lane, and most recent
heartbeat.
display_name is a friendly handle for the current live session. It is not a
stable semantic alias; those still belong to the role contract.
agent_identity is the stable A2A reader identity for sessions that should
share receipt state across restarts or concurrent terminals. Set it explicitly
with pnpm agent:session --agent-identity <owner>:<role>:<purpose> or
LUMENFLOW_AGENT_IDENTITY. LumenFlow does not infer this value from PID,
hostname, or process metadata; when it is absent, receipts use session_id.
Directed signals
Section titled “Directed signals”Send directed coordination signals by session_id, display_name, or
agent_identity. --to accepts a comma-separated recipient list:
The CLI resolves live session IDs and display names to agent_identity when one
is present. Signals persist canonical A2A recipients[]; target_agent remains
only as the deprecated single-recipient compatibility alias. Broadcast signals
without recipients continue to render for every session.
Threads and intents
Section titled “Threads and intents”Use A2A thread and intent fields when a signal needs a machine-readable decision, not just a status note:
Directed root signals get a generated thread_id and default to
interrupt_class: priority. Broadcasts default to interrupt_class: advisory.
Replies inherit the parent thread unless --thread is supplied explicitly.
Valid intents are INFO, PROPOSE, COUNTER, AGREE, and REJECT.
mem:converged --thread <id> exits successfully only when every recipient on
the thread root has replied with AGREE; REJECT replies are reported
separately and keep the thread unconverged.
The local .lumenflow/memory/*.jsonl files are an adapter over the exported
A2ASignalV1 and A2AReceiptV1 contract. Hosted transports should preserve the
same fields and state transitions while replacing storage and delivery.
Session-scoped inboxes
Section titled “Session-scoped inboxes”Read only the messages for one live session with --for:
This view still includes broadcast traffic, so an agent sees both direct messages and lane-wide coordination.
Hook delivery
Section titled “Hook delivery”Claude Code projects with LumenFlow enforcement hooks enabled install
.claude/hooks/signal-received.sh and a PostToolUse settings entry. When
mem:signal --to ... appends an addressed A2ASignalV1 signal for an active
Claude session, LumenFlow writes a per-session pending event under
.lumenflow/state/signal-hooks/. The Claude hook drains that queue at the next
tool boundary and surfaces a structured signal:received prompt prefix.
requires_ack: true events include explicit AGREE and REJECT reply commands
on the same thread. The wu:prep directed-signal gate remains the enforcement
backstop if a session ignores or misses the hook payload.
Clients without native hook delivery use mem:watch as a foreground daemon:
The watcher tails the canonical local A2A signal log, applies the same live
session and reader identity resolution as mem:inbox --for, dispatches
signal:received events through the hook event queue, drains them to stdout,
and records delivered receipts so the same signal is not emitted repeatedly.
Keep the process running in a side terminal for Codex CLI, Cursor, Windsurf,
Aider, Cline, Gemini CLI, or another client that cannot consume the generated
Claude PostToolUse hook.
| Client | Delivery status |
|---|---|
| Claude Code | Supported through generated PostToolUse hook delivery. |
| Codex CLI | Supported through foreground mem:watch daemon fallback. |
| Cursor | Supported through foreground mem:watch daemon fallback. |
| Windsurf | Supported through foreground mem:watch daemon fallback. |
| Aider / Cline / generic clients | Supported through foreground mem:watch daemon fallback. |
Prep gate
Section titled “Prep gate”wu:prep fails before gates when the current reader has unread directed signals
on the WU or its initiative. The failure lists signal IDs, sender, intent, and
ACK requirement when present. Continue only after reading and responding, or use
an audited override:
Roster-aware context
Section titled “Roster-aware context”mem:context now auto-composes a roster from the delegation registry and active
session records. Use --no-roster only when a test or fixture needs stable,
non-live output.
Display-name pool
Section titled “Display-name pool”Friendly names come from .lumenflow/agents/display-name-pool.yaml. A name is
reserved when agent:session starts and returned to the pool when the session
ends, so long-running orchestration stays readable without conflating session
identity with role ownership.
Stable reader identity
Section titled “Stable reader identity”Two live sessions may intentionally use the same agent_identity. That is the
workstation reuse pattern: a restarted reviewer or a second terminal can treat
signals already read by the first session as read without sharing the ephemeral
session_id.