Rulvar API reference / @rulvar/rulvar / ExternalRegistry
Class: ExternalRegistry
Defined in: packages/core/dist/index.d.ts
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
new ExternalRegistry(
replayer,
emitEvent?,
now?): ExternalRegistry;Defined in: packages/core/dist/index.d.ts
Parameters
| Parameter | Type |
|---|---|
replayer | Replayer |
emitEvent? | (body) => void |
now? | () => number |
Returns
ExternalRegistry
Accessors
closed
Get Signature
get closed(): boolean;Defined in: packages/core/dist/index.d.ts
Returns
boolean
Methods
awaitApproval()
awaitApproval(options): Promise<ApprovalDecision>;Defined in: packages/core/dist/index.d.ts
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
| Parameter | Type | Description |
|---|---|---|
options | { deadlineAt?: string; input: Json; onPending?: (entry, replayed) => void; risk?: string; scope: string; spanId: string; toolName: string; } | - |
options.deadlineAt? | string | The 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.input | Json | - |
options.onPending? | (entry, replayed) => void | - |
options.risk? | string | - |
options.scope | string | - |
options.spanId | string | - |
options.toolName | string | - |
Returns
Promise<ApprovalDecision>
awaitDecision()
awaitDecision(options): Promise<{
entryRef: number;
value: Json;
}>;Defined in: packages/core/dist/index.d.ts
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
| Parameter | Type | Description |
|---|---|---|
options | { deadlineAt: string; input: Json; onPending?: (entry, replayed) => void; scope: string; signal?: AbortSignal; spanId: string; toolName: string; } | - |
options.deadlineAt | string | - |
options.input | Json | - |
options.onPending? | (entry, replayed) => void | - |
options.scope | string | - |
options.signal? | AbortSignal | The 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.spanId | string | - |
options.toolName | string | - |
Returns
Promise<{ entryRef: number; value: Json; }>
awaitExternal()
awaitExternal(
scope,
spanId,
key,
options?): Promise<Json>;Defined in: packages/core/dist/index.d.ts
ctx.awaitExternal: journal (or re-match) the suspended entry and park until a resolution wins the first-closing-wins fold.
Parameters
| Parameter | Type |
|---|---|
scope | string |
spanId | string |
key | string |
options? | { prompt?: string; schema?: SchemaSpec<unknown>; } |
options.prompt? | string |
options.schema? | SchemaSpec<unknown> |
Returns
Promise<Json>
close()
close(): void;Defined in: packages/core/dist/index.d.ts
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()
enter(): () => void;Defined in: packages/core/dist/index.d.ts
Wraps every non-suspension async operation (agents, steps).
Returns
() => void
onQuiesce()
onQuiesce(listener): void;Defined in: packages/core/dist/index.d.ts
Parameters
| Parameter | Type |
|---|---|
listener | (pending) => void |
Returns
void
pending()
pending(): PendingExternal[];Defined in: packages/core/dist/index.d.ts
Returns
resolveExternal()
resolveExternal(key, value): Promise<ResolutionOutcome>;Defined in: packages/core/dist/index.d.ts
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
| Parameter | Type |
|---|---|
key | string |
value | Json |
Returns
Promise<ResolutionOutcome>
revokeApproval()
revokeApproval(key, options): Promise<ApprovalRevocationOutcome>;Defined in: packages/core/dist/index.d.ts
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
| Parameter | Type |
|---|---|
key | string |
options | { principal: string; reason: string; } |
options.principal | string |
options.reason | string |
Returns
Promise<ApprovalRevocationOutcome>
submitResolution()
submitResolution(entryRef, attempt): Promise<ResolutionOutcome>;Defined in: packages/core/dist/index.d.ts
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
| Parameter | Type |
|---|---|
entryRef | number |
attempt | ResolutionAttempt |
Returns
Promise<ResolutionOutcome>
approvalKey()
static approvalKey(entryRef): string;Defined in: packages/core/dist/index.d.ts
The synthesized resolveExternal key of an approval suspension.
Parameters
| Parameter | Type |
|---|---|
entryRef | number |
Returns
string
suspensionKeyOf()
static suspensionKeyOf(entry): string | undefined;Defined in: packages/core/dist/index.d.ts
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
| Parameter | Type |
|---|---|
entry | JournalEntry |
Returns
string | undefined