Skip to content
API reference

fleet

Import
import * as api from "@fungi.computer/shiitake/fleet";
Kind Export Description
class AgentGrantError Refusal of supplied authority; no host policy lookup is performed.
class DirectoryError Directory input, replay or storage refusal.
type alias AgentDelegationRequestKeyInput Inputs shared by Local and hosted delegation request identity.
type alias AgentAction One host-admitted fleet operation.
type alias AgentGrant A trusted host’s bounded, addressed authority for fleet operations.
type alias AgentLifecycleFact A committed directory transition, returned in the host’s transaction.
type alias AgentId An ordinary Agent directory identity.
type alias AgentCreation One idempotent directory reservation.
type alias AgentRename Input to createAgentDirectory’s rename.
type alias DirectoryAgent One durable Agent directory record.
type alias AgentDelegationTask A caller reuses this task unchanged while polling Pending.
type alias AgentDelegationOutcome Exact settled Session facts, including Pi usage and tool-call records.
type alias FleetDelegationOptions Ordinary runtime and mail transports; these ports do not decide host policy.
type alias AuthenticatedDelegationReply The delegation meta the host attaches to an authenticated reply: the caller’s own path plus the verified reply, whose agentId is the reply’s author.
type alias DelegationSendMeta The host metadata a delegated send carries, as JSON.
type alias DelegationReplyMeta The host metadata on one authenticated reply line, as JSON.
type alias OutstandingDelegation Delegated work an owner still waits on; unreadable says why its state could not be read, when it could not.
type alias FleetAgentAccess Acquire ordinary Session access; an in-process host applies meta with withMeta.
type alias FleetMessage One idempotent prompt, using the Session owner’s existing delivery grammar.
constant commandSettlementSchema Exact command facts shared by Session clients and host fleet transports.
constant agentActionSchema Operations explicitly admitted by the host.
constant agentProvenanceSchema Attribution supplied by the admitting host, without Team semantics.
constant agentGrantSchema Fleet authority is supplied, never looked up in host policy.
constant agentIds Stable Agent identities, retained across host compositions.
constant agentCreationSchema Stable replay input; configuration is an opaque host creation choice.
constant agentRenameSchema Owner-only rename input: an Agent’s new display name.
constant agentDelegationTaskSchema Replay identity and work, with the parent supplied exclusively by the grant.
function agentDelegationRequestKey() One idempotency identity for a caller-owned delegation request. The target Session is deliberately excluded: a sessionless send learns it only after acceptance, when recall must still resolve the original receipt.
function assertAgentGrant() Check every operation against its explicit authority.
function createAgentDirectory() Agent identities, replay receipts and erasure roster. Mutations belong inside the caller’s storage transaction, so lifecycle facts and host projections commit together. Physical table names retain the existing Hub store layout.
function delegationProvenance() Provenance for one delegated send from the invoking Agent’s Session. The model program’s digest is frozen with the replay input, so a retried tool call that changed its code conflicts instead of replaying.
function delegationSendMeta() The host metadata one delegated send carries: the sending Agent as author and only the path inherited from the invoking line. A reply’s verified facts stay on that reply’s own line and never travel onward.
function delegationReplyMeta() The host metadata for one authenticated reply line. An ordinary reply is authored by its replying Agent; a delivery failure is a Hub/system fact, while the verified reply retains the failed recipient’s identity.
function createFleetCorrespondence() BirdDog submission and reply authentication. The durable row freezes correspondence before transport; an ambiguous delivery reuses that exact mail. Shiitake owns work deduplication, execution and settlement; Post owns replies.
function createFleetDelegation() Local hosts may observe exact work directly; remote correspondence never pulls it.
function createFleetSessions() Addressed Session operations over the existing Shiitake client. Each operation checks a fresh supplied grant and releases its transport without stopping work.

Refusal of supplied authority; no host policy lookup is performed.

  • Error
Signature
new AgentGrantError(reason): AgentGrantError;
Parameter Type
reason "agent" | "action" | "expired" | "delegation_loop" | "delegation_depth"

AgentGrantError

Signature
Error.constructor;
Signature
readonly reason: "agent" | "action" | "expired" | "delegation_loop" | "delegation_depth";

Directory input, replay or storage refusal.

  • Error
Signature
new DirectoryError(status, code): DirectoryError;
Parameter Type
status 400 | 403 | 404 | 409 | 503
code | "not_found" | "request_conflict" | "invalid_input" | "name_taken" | "computer_team_conflict" | "partial_init"

DirectoryError

Signature
Error.constructor;
Signature
readonly status: 400 | 403 | 404 | 409 | 503;
Signature
readonly code:
| "not_found"
| "request_conflict"
| "invalid_input"
| "name_taken"
| "computer_team_conflict"
| "partial_init";

AgentDelegationRequestKeyInputtype alias

Section titled “AgentDelegationRequestKeyInput”
Signature
type AgentDelegationRequestKeyInput = Readonly<{
owner:
| Readonly<{
kind: "local";
agentId: string;
}>
| Readonly<{
kind: "hosted";
scopeId: string;
agentId: string;
}>;
sourceSessionId: string;
targetAgentId: string;
requestId: string;
}>;

Inputs shared by Local and hosted delegation request identity.


AgentActiontype alias

Section titled “AgentAction”
Signature
type AgentAction = z.infer<typeof agentActionSchema>;

One host-admitted fleet operation.


AgentGranttype alias

Section titled “AgentGrant”
Signature
type AgentGrant = z.infer<typeof agentGrantSchema>;

A trusted host’s bounded, addressed authority for fleet operations.


AgentLifecycleFacttype alias

Section titled “AgentLifecycleFact”
Signature
type AgentLifecycleFact = Readonly<{
kind: "created" | "deleted";
agentId: string;
provenance: AgentGrant["provenance"];
}>;

A committed directory transition, returned in the host’s transaction.


Signature
type AgentId = CairnId<"agent", "agent">;

An ordinary Agent directory identity.


AgentCreationtype alias

Section titled “AgentCreation”
Signature
type AgentCreation = z.infer<typeof agentCreationSchema>;

One idempotent directory reservation.


AgentRenametype alias

Section titled “AgentRename”
Signature
type AgentRename = z.infer<typeof agentRenameSchema>;

Input to createAgentDirectory’s rename.


DirectoryAgenttype alias

Section titled “DirectoryAgent”
Signature
type DirectoryAgent = Readonly<{
agentId: AgentId;
createdBy: string | null;
name: string;
createdAt: number;
updatedAt: number;
}>;

One durable Agent directory record.


AgentDelegationTasktype alias

Section titled “AgentDelegationTask”
Signature
type AgentDelegationTask = z.infer<typeof agentDelegationTaskSchema>;

A caller reuses this task unchanged while polling Pending.


AgentDelegationOutcometype alias

Section titled “AgentDelegationOutcome”
Signature
type AgentDelegationOutcome = Readonly<{
kind: "settled";
agentId: string;
sessionId: string;
}> &
CommandSettlement;

Exact settled Session facts, including Pi usage and tool-call records.


FleetDelegationOptionstype alias

Section titled “FleetDelegationOptions”
Signature
type FleetDelegationOptions = Readonly<{
storage: WatchdogSqliteOwner;
deliver: (mail) => Promise<DelegationReceipt>;
readSettlement: (
agentId,
sessionId,
commandId,
) => Promise<CommandSettlement | undefined>;
open: (agentId) => Promise<
Readonly<{
agent: ShiitakeAgent;
release: () => Promise<void>;
}>
>;
}>;

Ordinary runtime and mail transports; these ports do not decide host policy.


AuthenticatedDelegationReplytype alias

Section titled “AuthenticatedDelegationReply”
Signature
type AuthenticatedDelegationReply = Readonly<{
ancestors: readonly string[];
maxDepth: number;
reply: VerifiedAgentReply;
}>;

The delegation meta the host attaches to an authenticated reply: the caller’s own path plus the verified reply, whose agentId is the reply’s author.


DelegationSendMetatype alias

Section titled “DelegationSendMeta”
Signature
type DelegationSendMeta = object;

The host metadata a delegated send carries, as JSON.

Signature
author: AuthorMeta["author"];
Signature
optional delegation?: object;
Signature
ancestors: string[];
Signature
maxDepth: number;

DelegationReplyMetatype alias

Section titled “DelegationReplyMeta”
Signature
type DelegationReplyMeta = Readonly<{
author: AuthorMeta["author"];
delegation: Readonly<{
ancestors: readonly string[];
maxDepth: number;
reply: VerifiedAgentReply;
}>;
}>;

The host metadata on one authenticated reply line, as JSON.


OutstandingDelegationtype alias

Section titled “OutstandingDelegation”
Signature
type OutstandingDelegation = Readonly<{
agentId: string;
sessionId: string;
commandId: string;
unreadable?: string;
}>;

Delegated work an owner still waits on; unreadable says why its state could not be read, when it could not.


FleetAgentAccesstype alias

Section titled “FleetAgentAccess”
Signature
type FleetAgentAccess = (
agentId,
meta?,
) => Promise<
Readonly<{
agent: ShiitakeAgent;
release: () => Promise<void>;
}>
>;

Acquire ordinary Session access; an in-process host applies meta with withMeta.

Parameter Type
agentId string
meta? Json

Promise<Readonly<{ agent: ShiitakeAgent; release: () => Promise<void>; }>>


FleetMessagetype alias

Section titled “FleetMessage”
Signature
type FleetMessage = Readonly<{
requestId: string;
text: string;
delivery?: "steer" | "followUp";
}>;

One idempotent prompt, using the Session owner’s existing delivery grammar.

commandSettlementSchemaconstant

Section titled “commandSettlementSchema”
Signature
const commandSettlementSchema: Schema.Codec<CommandSettlement>;

Exact command facts shared by Session clients and host fleet transports.


agentActionSchemaconstant

Section titled “agentActionSchema”
Signature
const agentActionSchema: ZodEnum<{
send: "send";
read: "read";
create: "create";
manage: "manage";
delegate: "delegate";
}>;

Operations explicitly admitted by the host.


agentProvenanceSchemaconstant

Section titled “agentProvenanceSchema”
Signature
const agentProvenanceSchema: ZodLazy<
ZodObject<
{
actor: ZodString;
workflowRunId: ZodOptional<ZodString>;
toolCallInputDigest: ZodOptional<ZodString>;
session: ZodOptional<
ZodObject<
{
agentId: ZodString;
sessionId: ZodString;
},
$strict
>
>;
},
$strict
>
>;

Attribution supplied by the admitting host, without Team semantics.


agentGrantSchemaconstant

Section titled “agentGrantSchema”
Signature
const agentGrantSchema: ZodLazy<
ZodObject<
{
agents: ZodUnion<readonly [ZodLiteral<"all">, ZodArray<ZodString>]>;
actions: ZodArray<
ZodEnum<{
send: "send";
read: "read";
create: "create";
manage: "manage";
delegate: "delegate";
}>
>;
expiresAt: ZodNumber;
provenance: ZodLazy<
ZodObject<
{
actor: ZodString;
workflowRunId: ZodOptional<ZodString>;
toolCallInputDigest: ZodOptional<ZodString>;
session: ZodOptional<
ZodObject<
{
agentId: ZodString;
sessionId: ZodString;
},
$strict
>
>;
},
$strict
>
>;
meta: ZodOptional<ZodJSONSchema>;
maxDepth: ZodOptional<ZodNumber>;
},
$strict
>
>;

Fleet authority is supplied, never looked up in host policy.


agentIdsconstant

Section titled “agentIds”
Signature
const agentIds: Readonly<{
agent: IdCodec<"agent", "agent", 1>;
}>;

Stable Agent identities, retained across host compositions.


agentCreationSchemaconstant

Section titled “agentCreationSchema”
Signature
const agentCreationSchema: ZodLazy<
ZodObject<
{
name: ZodString;
requestId: ZodString;
configuration: ZodString;
createdBy: ZodOptional<ZodNullable<ZodString>>;
},
$strict
>
>;

Stable replay input; configuration is an opaque host creation choice.


agentRenameSchemaconstant

Section titled “agentRenameSchema”
Signature
const agentRenameSchema: ZodLazy<
ZodObject<
{
name: ZodString;
},
$strict
>
>;

Owner-only rename input: an Agent’s new display name.


agentDelegationTaskSchemaconstant

Section titled “agentDelegationTaskSchema”
Signature
const agentDelegationTaskSchema: ZodLazy<
ZodObject<
{
requestId: ZodString;
agentId: ZodString;
sessionId: ZodOptional<ZodString>;
text: ZodString;
},
$strict
>
>;

Replay identity and work, with the parent supplied exclusively by the grant.

agentDelegationRequestKey()function

Section titled “agentDelegationRequestKey()”
Signature
function agentDelegationRequestKey(input): Promise<string>;

One idempotency identity for a caller-owned delegation request. The target Session is deliberately excluded: a sessionless send learns it only after acceptance, when recall must still resolve the original receipt.

Parameter Type
input AgentDelegationRequestKeyInput

Promise<string>


assertAgentGrant()function

Section titled “assertAgentGrant()”
Signature
function assertAgentGrant(grant, action, agentId?): void;

Check every operation against its explicit authority.

Parameter Type Description
grant { agents: string[] | "all"; actions: ("send" | "read" | "create" | "manage" | "delegate")[]; expiresAt: number; provenance: { actor: string; workflowRunId?: string; toolCallInputDigest?: string; session?: { agentId: string; sessionId: string; }; }; meta?: JSONType; maxDepth?: number; } -
grant.agents string[] | "all" -
grant.actions ("send" | "read" | "create" | "manage" | "delegate")[] -
grant.expiresAt? number -
grant.provenance? { actor: string; workflowRunId?: string; toolCallInputDigest?: string; session?: { agentId: string; sessionId: string; }; } -
grant.provenance.actor? string -
grant.provenance.workflowRunId? string -
grant.provenance.toolCallInputDigest? string Host fingerprint of the enclosing model program, frozen with replay input.
grant.provenance.session? { agentId: string; sessionId: string; } -
grant.provenance.session.agentId? string -
grant.provenance.session.sessionId? string -
grant.meta? JSONType -
grant.maxDepth? number Delegation abuse bound; inherited paths may only narrow it.
action? "send" | "read" | "create" | "manage" | "delegate" -
agentId? string -

void


createAgentDirectory()function

Section titled “createAgentDirectory()”
Signature
function createAgentDirectory(sql): object;

Agent identities, replay receipts and erasure roster. Mutations belong inside the caller’s storage transaction, so lifecycle facts and host projections commit together. Physical table names retain the existing Hub store layout.

Parameter Type
sql Readonly<{ exec: (statement, …bindings) => WatchdogSqliteCursor; }>
Name Type Default value Description
readCreation() (grant, raw) => | Readonly<{ agentId: AgentId; createdBy: string | null; name: string; createdAt: number; updatedAt: number; }> | null - Resolve a matching creation receipt before host admission of a new reservation.
create() (grant, raw) => | { agent: Readonly<{ agentId: AgentId; createdBy: string | null; name: string; createdAt: number; updatedAt: number; }>; fact: null; } | { agent: Readonly<{ agentId: AgentId; createdBy: string | null; name: string; createdAt: number; updatedAt: number; }>; fact: { kind: "created"; agentId: CairnId<"agent", "agent", 1>; provenance: { actor: string; workflowRunId?: string; toolCallInputDigest?: string; session?: { agentId: string; sessionId: string; }; }; }; } - Reserve an Agent once and return its committed lifecycle fact.
read() (grant, agentId) => | Readonly<{ agentId: AgentId; createdBy: string | null; name: string; createdAt: number; updatedAt: number; }> | null - Read one admitted Agent identity.
list() (grant) => readonly Readonly<{ agentId: AgentId; createdBy: string | null; name: string; createdAt: number; updatedAt: number; }>[] - List only identities covered by the supplied grant.
remove() (grant, agentId) => | Readonly<{ kind: "deleted" | "created"; agentId: string; provenance: { actor: string; workflowRunId?: string; toolCallInputDigest?: string; session?: { agentId: string; sessionId: string; }; }; }> | null - Remove an identity while retaining its erasure address.
rename() (grant, agentId, raw) => DirectoryAgent - Rename an existing Agent; refuses a name already held by another one. Owner-only rename; refuses a name already held by another Agent.
readCreator() (grant, agentId) => string | null - Read the host actor recorded at creation. The user who created an Agent; that user’s own credentials follow it.
listErasureIds() () => readonly string[] store.listErasureIds Enumerate retained addresses for host erasure.
erasureRosterComplete() () => boolean store.erasureRosterComplete Whether the retained erasure roster covers this store.

delegationProvenance()function

Section titled “delegationProvenance()”
Signature
function delegationProvenance(
session,
toolCallCode?,
): Promise<{
actor: string;
workflowRunId?: string;
toolCallInputDigest?: string;
session?: {
agentId: string;
sessionId: string;
};
}>;

Provenance for one delegated send from the invoking Agent’s Session. The model program’s digest is frozen with the replay input, so a retried tool call that changed its code conflicts instead of replaying.

Parameter Type
session Readonly<{ agentId: string; sessionId: string; }>
toolCallCode? string

Promise<{ actor: string; workflowRunId?: string; toolCallInputDigest?: string; session?: { agentId: string; sessionId: string; }; }>


delegationSendMeta()function

Section titled “delegationSendMeta()”
Signature
function delegationSendMeta(sender, invocationMeta?): DelegationSendMeta;

The host metadata one delegated send carries: the sending Agent as author and only the path inherited from the invoking line. A reply’s verified facts stay on that reply’s own line and never travel onward.

Parameter Type
sender Readonly<{ id: string; name: string; }>
invocationMeta? Json

DelegationSendMeta


delegationReplyMeta()function

Section titled “delegationReplyMeta()”
Signature
function delegationReplyMeta(delegation, replierName): DelegationReplyMeta;

The host metadata for one authenticated reply line. An ordinary reply is authored by its replying Agent; a delivery failure is a Hub/system fact, while the verified reply retains the failed recipient’s identity.

Parameter Type
delegation AuthenticatedDelegationReply
replierName string

DelegationReplyMeta


createFleetCorrespondence()function

Section titled “createFleetCorrespondence()”
Signature
function createFleetCorrespondence(options): object;

BirdDog submission and reply authentication. The durable row freezes correspondence before transport; an ambiguous delivery reuses that exact mail. Shiitake owns work deduplication, execution and settlement; Post owns replies.

Parameter Type
options Omit<FleetDelegationOptions, "readSettlement">
Name Type Description
start() (grant, raw) => Promise<DelegationReceipt> Submit frozen mail or reuse its recorded Session admission receipt.
authenticateReply() (mail) => | Readonly<{ ancestors: readonly string[]; maxDepth: number; reply: | { commandId: string; outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown"; diagnostic?: string; agentId: string; sessionId: string; } | { outcome: "undeliverable"; reason: "recipient_offline" | "recipient_left"; agentId: string; sessionId?: string; }; }> | undefined Match a reply to frozen mail and restore the caller’s delegation path. Authenticate one arriving reply against the frozen mail this owner sent. It must be BirdDog’s single reply key for that mail, mirror its sender and recipient exactly, carry BirdDog’s settlement facts and, once the send’s receipt is recorded, name that receipt’s commandId. The result restores the caller’s own delegation path and the verified reply; it never reads the reply’s text or any settlement metadata.
recordLocalUndeliverable() (original, reply) => boolean Bind exhausted local delivery to its frozen sender correspondence. Bind an exhausted local Carrier row to its frozen sender correspondence.
recordUndeliverableReply() (mailKey) => boolean Prevent replay after a system undeliverable reply is admitted. Make a successfully admitted system disposition replay-ineligible.
receipt() (requestId) => | Readonly<{ status: "accepted"; commandId: string; sessionId?: string; }> | undefined Read an existing acceptance receipt without reserving or delivering mail. Read only the existing acceptance receipt; do not reserve or deliver mail.
recordAcceptedNotice() (mail) => | Readonly<{ status: "accepted"; commandId: string; sessionId?: string; }> | undefined Consume a recipient’s stable <mailKey>:accepted notice. Atomically bind the recipient Session carried by a late acceptance notice.

createFleetDelegation()function

Section titled “createFleetDelegation()”
Signature
function createFleetDelegation(options): object;

Local hosts may observe exact work directly; remote correspondence never pulls it.

Parameter Type
options FleetDelegationOptions
Name Type Description
start() (grant, raw) => Promise<DelegationReceipt> Submit frozen mail or reuse its recorded Session admission receipt.
authenticateReply() (mail) => | Readonly<{ ancestors: readonly string[]; maxDepth: number; reply: | { commandId: string; outcome: "completed" | "failed" | "cancelled" | "interrupted" | "outcome_unknown"; diagnostic?: string; agentId: string; sessionId: string; } | { outcome: "undeliverable"; reason: "recipient_offline" | "recipient_left"; agentId: string; sessionId?: string; }; }> | undefined Match a reply to frozen mail and restore the caller’s delegation path. Authenticate one arriving reply against the frozen mail this owner sent. It must be BirdDog’s single reply key for that mail, mirror its sender and recipient exactly, carry BirdDog’s settlement facts and, once the send’s receipt is recorded, name that receipt’s commandId. The result restores the caller’s own delegation path and the verified reply; it never reads the reply’s text or any settlement metadata.
recordLocalUndeliverable() (original, reply) => boolean Bind exhausted local delivery to its frozen sender correspondence. Bind an exhausted local Carrier row to its frozen sender correspondence.
recordUndeliverableReply() (mailKey) => boolean Prevent replay after a system undeliverable reply is admitted. Make a successfully admitted system disposition replay-ineligible.
receipt() (requestId) => | Readonly<{ status: "accepted"; commandId: string; sessionId?: string; }> | undefined Read an existing acceptance receipt without reserving or delivering mail. Read only the existing acceptance receipt; do not reserve or deliver mail.
recordAcceptedNotice() (mail) => | Readonly<{ status: "accepted"; commandId: string; sessionId?: string; }> | undefined Consume a recipient’s stable <mailKey>:accepted notice. Atomically bind the recipient Session carried by a late acceptance notice.
outstanding() () => Promise< | Readonly<{ agentId: string; sessionId: string; commandId: string; unreadable?: string; }> | undefined> The delegated work this owner still waits on, if any. The newest delegation this owner sent whose work has not settled at its target, so the owner is still waiting for a reply; undefined when none.
delegate() (grant, task) => Promise< | Readonly<{ kind: "pending"; retryAfterMs: number; }> | AgentDelegationOutcome> Submit or poll the exact turn, yielding Agar Pending until settled.

createFleetSessions()function

Section titled “createFleetSessions()”
Signature
function createFleetSessions(open): object;

Addressed Session operations over the existing Shiitake client. Each operation checks a fresh supplied grant and releases its transport without stopping work.

Parameter Type
open FleetAgentAccess
Name Type Description
list() (grant, agentId, after?) => Promise<Readonly<{ sessions: readonly SessionSummaryRow[]; next: string | undefined; }>> Enumerate existing Sessions through the owner’s bounded cursor.
read() (grant, agentId, sessionId) => Promise<Readonly<{ sessionId: string; cursor: string | null; hasMore: boolean; oldestCursor?: string | null; messages: readonly Readonly<{ requestId?: string; meta?: Json; data?: Json; origin?: Readonly<{ extensionId: …; correlation: …; }>; id: string; sequence: number; commandId: string | null; value: ModelMessage; }>[]; terminals: readonly Readonly<{ commandId: string; outcome: "completed" | "failed" | "cancelled" | "interrupted"; sequence: number; diagnostic: string | null; meta?: Json; }>[]; compactions?: readonly Readonly<{ id: string; sequence: number; at: number; tokensBefore: number; tokensAfter: number | null; trigger: SessionCompactionTrigger | null; }>[]; compactionNotices?: readonly Readonly<{ id: string; sequence: number; at: number; trigger: SessionCompactionTrigger; result: "failed" | "nothing_to_compact" | "stale" | "insufficient"; diagnostic: string | null; }>[]; sandboxFailures?: readonly object[]; pending: SessionPendingPrompts; activity: SessionActivity; progress: | Readonly<{ messageId: string; revision: number; text: string; thinking: string; textTruncated: boolean; thinkingTruncated: boolean; }> | null; toolOutput: readonly Readonly<{ toolCallId: string; revision: number; tail: string; droppedBytes: number; totalBytes: number; }>[]; extensions: SessionExtensionSlots; attention: readonly object[]; context?: Readonly<{ tokens: number; window: number | null; }>; }>> Open the exact saved conversation without creating work.
create() (grant, agentId, requestId) => Promise<string> Create a Session once under the caller’s replay identity.
remove() (grant, agentId, sessionId) => Promise<boolean> Remove a Session through its runtime owner.
send() (grant, agentId, sessionId, message) => Promise<{ status: "accepted"; commandId: string; sessionId: string; }> Send once; an omitted Session is created under the same replay identity.