Skip to content

Rulvar API reference


Rulvar API reference / @rulvar/core / ExternalRegistry

Class: ExternalRegistry

Defined in: packages/core/src/engine/external.ts:234

Per-run registry of open external suspensions plus the run's activity counter: when every in-flight branch is blocked on suspensions (activity zero, waiters open), the run quiesces into outcome 'suspended'.

Constructors

Constructor

ts
new ExternalRegistry(
   replayer, 
   emitEvent?, 
   now?): ExternalRegistry;

Defined in: packages/core/src/engine/external.ts:247

Parameters

ParameterTypeDefault value
replayerReplayerundefined
emitEvent?(body) => voidundefined
now?() => numberDate.now

Returns

ExternalRegistry

Accessors

closed

Get Signature

ts
get closed(): boolean;

Defined in: packages/core/src/engine/external.ts:363

Returns

boolean

Methods

awaitApproval()

ts
awaitApproval(options): Promise<ApprovalDecision>;

Defined in: packages/core/src/engine/external.ts:458

Tool-approval suspension (M3-T03): journals (or re-matches) the suspended approval entry keyed by (toolName, input) in the agent's child scope and parks until a resolution closes it. The ask verdict is journaled together with the turn checkpoint; on resume an already-resolved entry applies its decision immediately and is never re-suspended.

Parameters

ParameterTypeDescription
options{ deadlineAt?: string; input: Json; onPending?: (entry, replayed) => void; risk?: string; scope: string; spanId: string; toolName: string; }-
options.deadlineAt?stringThe opt-in approval deadline (RV1107), journaled ON the suspension entry so it survives resume; the armed timer always reads the ENTRY's deadline, never the caller's config, so a config change can never move an already-journaled deadline.
options.inputJson-
options.onPending?(entry, replayed) => voidCalled with the suspended entry once it is open (live or re-parked).
options.risk?string-
options.scopestring-
options.spanIdstring-
options.toolNamestring-

Returns

Promise&lt;ApprovalDecision&gt;


awaitDecision()

ts
awaitDecision(options): Promise<{
  entryRef: number;
  value: Json;
}>;

Defined in: packages/core/src/engine/external.ts:573

Flavor B escalation suspension (M3-T07): the escalate tool suspends the agent on the SAME machinery as approvals (kind 'approval', toolName 'escalate') with a journaled deadlineAt so deadlines survive resume; the resolution VALUE is the raw EscalationDecision. A timeout is expressed as a resolution by 'timeout' through the arbiter; first-closing-wins guarantees the defaultDecision and a racing live decision never both apply.

Parameters

ParameterTypeDescription
options{ deadlineAt: string; input: Json; onPending?: (entry, replayed) => void; scope: string; signal?: AbortSignal; spanId: string; toolName: string; }-
options.deadlineAtstring-
options.inputJson-
options.onPending?(entry, replayed) => void-
options.scopestring-
options.signal?AbortSignalThe branch/run signal: an abort while parked releases the held activity, removes the waiter, and rejects with EscalationDecisionAbortedError (v1.35.0 review P1). The suspension entry stays open for resume.
options.spanIdstring-
options.toolNamestring-

Returns

Promise<{ entryRef: number; value: Json; }>


awaitExternal()

ts
awaitExternal(
   scope, 
   spanId, 
   key, 
options?): Promise<Json>;

Defined in: packages/core/src/engine/external.ts:388

ctx.awaitExternal: journal (or re-match) the suspended entry and park until a resolution wins the first-closing-wins fold.

Parameters

ParameterType
scopestring
spanIdstring
keystring
options?{ prompt?: string; schema?: SchemaSpec; }
options.prompt?string
options.schema?SchemaSpec

Returns

Promise&lt;Json&gt;


close()

ts
close(): void;

Defined in: packages/core/src/engine/external.ts:358

Settling the run closes this execution segment permanently: every parked waiter is detached, so a resolution arriving after handle.result settled appends durably through the fold and wakes NOTHING; exactly one subsequent engine.resume owns the continuation. Idempotent. (Suspension ownership rule; v1.10 deep E2E review.)

Returns

void


enter()

ts
enter(): () => void;

Defined in: packages/core/src/engine/external.ts:284

Wraps every non-suspension async operation (agents, steps).

Returns

() => void


onQuiesce()

ts
onQuiesce(listener): void;

Defined in: packages/core/src/engine/external.ts:313

Parameters

ParameterType
listener(pending) => void

Returns

void


pending()

ts
pending(): PendingExternal[];

Defined in: packages/core/src/engine/external.ts:317

Returns

PendingExternal[]


resolveExternal()

ts
resolveExternal(key, value): Promise<ResolutionOutcome>;

Defined in: packages/core/src/engine/external.ts:754

RunHandle.resolveExternal: the live path validates BEFORE append and throws InvalidResolutionError without journaling; a winning attempt settles the waiting promise in place. Without an open waiter the attempt goes through the journal fold instead: a repeated resolution is the documented journaled no-op ('already_resolved'), and once the segment settled the resolution appends durably WITHOUT waking the closed body (exactly one engine.resume owns the continuation).

Parameters

ParameterType
keystring
valueJson

Returns

Promise&lt;ResolutionOutcome&gt;


revokeApproval()

ts
revokeApproval(key, options): Promise<ApprovalRevocationOutcome>;

Defined in: packages/core/src/engine/external.ts:810

Revokes a tool approval (RV4008). A still-open approval is denied through the ordinary first-closing-wins arbitration (a race with a live allow stays deterministic by the journal). A RECORDED allow cannot be unwritten (history is immutable): the revocation appends an approval_revoked decision that beats the allow at the consumption recheck, so an allow granted, crashed over, and revoked never dispatches its tool on resume. A denied or abandoned approval has nothing to revoke.

Parameters

ParameterType
keystring
options{ principal: string; reason: string; }
options.principalstring
options.reasonstring

Returns

Promise&lt;ApprovalRevocationOutcome&gt;


submitResolution()

ts
submitResolution(entryRef, attempt): Promise<ResolutionOutcome>;

Defined in: packages/core/src/engine/external.ts:720

Submits a resolution attempt for a parked suspension and, when it wins the first-closing-wins fold, settles the in-process waiter with the value (timers and engine-side deciders use this; operator resolutions ride resolveExternal).

Parameters

ParameterType
entryRefnumber
attemptResolutionAttempt

Returns

Promise&lt;ResolutionOutcome&gt;


approvalKey()

ts
static approvalKey(entryRef): string;

Defined in: packages/core/src/engine/external.ts:327

The synthesized resolveExternal key of an approval suspension.

Parameters

ParameterType
entryRefnumber

Returns

string


suspensionKeyOf()

ts
static suspensionKeyOf(entry): string | undefined;

Defined in: packages/core/src/engine/external.ts:337

The resolveExternal key a journaled suspension answers to: externals carry the workflow-chosen key in the payload; approvals and Flavor B decisions synthesize approval:<seq>. Undefined for anything that is not a suspended entry.

Parameters

ParameterType
entryJournalEntry

Returns

string | undefined