@rulvar/core 1.48.0 → 1.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.d.ts +236 -12
  2. package/dist/index.js +497 -127
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -28,7 +28,7 @@ type WireError = {
28
28
  * 'agent' is carried by the AgentError value projection, not by a
29
29
  * RulvarError subclass.
30
30
  */
31
- type ErrorCode = "agent" | "config" | "non_serializable_value" | "script_rejected" | "journal_compat" | "invalid_resolution" | "journal_order_violation" | "plan_invariant" | "replay_plan_hash_mismatch" | "orchestrator_cap_config" | "journal_miss" | "budget_exhausted" | "fail_run" | "admission_rejected" | "sandbox_limit" | "lease_held" | "knowledge_cas";
31
+ type ErrorCode = "agent" | "config" | "non_serializable_value" | "script_rejected" | "journal_compat" | "invalid_resolution" | "journal_order_violation" | "plan_invariant" | "replay_plan_hash_mismatch" | "orchestrator_cap_config" | "journal_miss" | "budget_exhausted" | "fail_run" | "admission_rejected" | "sandbox_limit" | "lease_held" | "knowledge_cas" | "determinism";
32
32
  /** An alias for the registry type; both names are public. */
33
33
  type RulvarErrorCode = ErrorCode;
34
34
  /**
@@ -264,6 +264,25 @@ declare class KnowledgeCasError extends RulvarError {
264
264
  });
265
265
  }
266
266
  /**
267
+ * A workflow-origin bare-nondeterminism violation under
268
+ * `determinism.mode: 'error'` (RV-209): bare `Date.now()` or
269
+ * `Math.random()` called from workflow code inside a run. Thrown at the
270
+ * offending call site (and re-thrown at settle if the workflow swallowed
271
+ * it), so the run rejects instead of recording a value replay cannot
272
+ * reproduce. `data` carries the structured localization: `category`,
273
+ * `frame`, and the parsed `file`/`line`/`column` when the frame names
274
+ * one. Never journaled as its own entry; the run settles 'error' with
275
+ * this wire error. Exempt provenances (installed dependencies, Node
276
+ * runtime frames, allowlisted patterns) never raise it.
277
+ */
278
+ declare class DeterminismError extends RulvarError {
279
+ readonly code = "determinism";
280
+ constructor(message: string, opts?: {
281
+ data?: Json;
282
+ cause?: unknown;
283
+ });
284
+ }
285
+ /**
267
286
  * The vendored Standard Schema issue shape: validation issues carried
268
287
  * on AgentError and surfaced to the
269
288
  * model during bounded schema re-prompts.
@@ -3088,6 +3107,13 @@ interface AgentResult<T> {
3088
3107
  * cancellation or ordinary cap hits.
3089
3108
  */
3090
3109
  abortClass?: AbortClass;
3110
+ /**
3111
+ * Transport retries across the span's phase activations, present only
3112
+ * when greater than zero. Live telemetry only: the ctx layer surfaces
3113
+ * it as `agent:end` retryCount; it is never journaled, so a replayed
3114
+ * result omits it (absent means "zero or unknown").
3115
+ */
3116
+ transportRetries?: number;
3091
3117
  }
3092
3118
  type EscalatedResult<T> = AgentResult<T> & {
3093
3119
  status: "escalated";
@@ -4408,7 +4434,19 @@ type CoreEvents = {
4408
4434
  scope: string;
4409
4435
  status: string;
4410
4436
  };
4411
- /** Agent lifecycle. */
4437
+ /**
4438
+ * Agent lifecycle. One logical agent dispatch emits EXACTLY ONE
4439
+ * `agent:start`/`agent:end` pair on its span (the start carries the
4440
+ * primary role), and each model invocation phase inside the span
4441
+ * (`loop`, then possibly `summarize` activations, `finalize`,
4442
+ * `extract`) emits its own `agent:phase:start`/`agent:phase:end` pair,
4443
+ * so durations, per-phase usage, and attempts are derivable without
4444
+ * heuristics (the RV-207 event-model contract; before it, every phase
4445
+ * emitted an unpaired extra `agent:start` and consumers pairing starts
4446
+ * with the single end computed the LAST phase's duration as the
4447
+ * agent's). `reduceInvocationTable` is the official reducer over this
4448
+ * vocabulary.
4449
+ */
4412
4450
  type AgentEvents = {
4413
4451
  type: "agent:queued";
4414
4452
  agentType: string;
@@ -4419,6 +4457,39 @@ type AgentEvents = {
4419
4457
  label?: string;
4420
4458
  model: string;
4421
4459
  role: string;
4460
+ } | {
4461
+ type: "agent:phase:start";
4462
+ agentType: string;
4463
+ label?: string; /** The invocation role this phase activation runs as. */
4464
+ role: string; /** The model the activation resolved to (fallbacks may serve another; the end event reports the server). */
4465
+ model: string;
4466
+ /**
4467
+ * 1-based activation ordinal within the span, unique per
4468
+ * activation (a summarize that fires three times gets three
4469
+ * pairs). Key phases by (spanId, invocation).
4470
+ */
4471
+ invocation: number;
4472
+ } | {
4473
+ type: "agent:phase:end";
4474
+ agentType: string;
4475
+ label?: string;
4476
+ role: string; /** The model that actually served the activation's last attempt. */
4477
+ model: string;
4478
+ invocation: number;
4479
+ /**
4480
+ * Wall-clock activation duration. Live telemetry only: replayed
4481
+ * phase pairs (reconstructed from the terminal entry's usage
4482
+ * slices) carry 0.
4483
+ */
4484
+ durationMs: number; /** The usage this activation added to its (role, model) slices. */
4485
+ usage: Usage; /** That usage priced at each serving model's own rate. */
4486
+ costUsd: number;
4487
+ outcome: "ok" | "error";
4488
+ /**
4489
+ * Transport retries inside this activation. Present only when
4490
+ * greater than zero; live telemetry only (absent on replay).
4491
+ */
4492
+ retries?: number;
4422
4493
  } | {
4423
4494
  type: "agent:end";
4424
4495
  agentType: string;
@@ -4435,6 +4506,13 @@ type AgentEvents = {
4435
4506
  * terminal journal entry's usageApprox.
4436
4507
  */
4437
4508
  usageApprox?: boolean;
4509
+ /**
4510
+ * Total transport retries across the span's activations. Present
4511
+ * only when greater than zero; live telemetry only, never
4512
+ * journaled, so a replayed agent:end omits it (absent means "zero
4513
+ * or unknown").
4514
+ */
4515
+ retryCount?: number;
4438
4516
  } | {
4439
4517
  type: "agent:error";
4440
4518
  agentType: string;
@@ -4472,6 +4550,34 @@ type ToolEvents = {
4472
4550
  advisory?: Json;
4473
4551
  };
4474
4552
  /**
4553
+ * Bare-nondeterminism detection (RV-209). Emitted LIVE by the segment
4554
+ * that observed the call, at most once per (category, provenance) per
4555
+ * execution segment; never journaled and never re-emitted with the
4556
+ * `replayed` flag. Because replay re-executes the workflow body, a
4557
+ * violation that survives in the code fires again on every replay of
4558
+ * the run, so the event appears organically in both live and replayed
4559
+ * streams. Exempt provenances (installed dependencies under
4560
+ * node_modules and Node runtime frames) never emit: they are
4561
+ * classified and silenced, which is what keeps an SDK's internal
4562
+ * `Math.random()` from branding the run nondeterministic.
4563
+ */
4564
+ type DeterminismEvents = {
4565
+ type: "determinism:warning"; /** Which patched global fired. */
4566
+ category: "bare-date-now" | "bare-math-random";
4567
+ /**
4568
+ * 'workflow': the caller is workflow-origin code (the violation the
4569
+ * guard exists for; rejects the run under `determinism.mode:
4570
+ * 'error'`). 'allowlisted': the caller matched a configured
4571
+ * `determinism.allowlist` pattern and is exempt by explicit host
4572
+ * decision; emitted for visibility, never rejects.
4573
+ */
4574
+ provenance: "workflow" | "allowlisted"; /** The calling stack frame, after the configured redaction hook. */
4575
+ frame: string; /** Parsed location when the frame carries one, after redaction. */
4576
+ file?: string;
4577
+ line?: number;
4578
+ column?: number;
4579
+ };
4580
+ /**
4475
4581
  * Adaptive orchestration, resolutions, and
4476
4582
  * accounting: emitted only by runs where the corresponding machinery is
4477
4583
  * active (applicability per mode:
@@ -4618,7 +4724,7 @@ type AdaptiveEvents = {
4618
4724
  found: number;
4619
4725
  window: [number, number];
4620
4726
  };
4621
- type WorkflowEventBody = CoreEvents | AgentEvents | ToolEvents | AdaptiveEvents;
4727
+ type WorkflowEventBody = CoreEvents | AgentEvents | ToolEvents | DeterminismEvents | AdaptiveEvents;
4622
4728
  /**
4623
4729
  * The envelope: seq is an independent per-run
4624
4730
  * telemetry counter, strictly increasing in emission order and DISTINCT
@@ -4751,13 +4857,15 @@ type OnEscalation = (result: EscalatedResult<unknown>) => EscalationDecision | P
4751
4857
  /**
4752
4858
  * The mode (a) runner for human-authored closures. Determinism is enforced
4753
4859
  * by convention, lint, and the ctx shims, NOT by a VM: only the sequence
4754
- * of keys must be stable. Dev mode (NODE_ENV !== 'production') detects
4755
- * bare Date.now and Math.random and emits one warning per run pointing at
4756
- * ctx.now()/ctx.random(). Detection is attributed by AsyncLocalStorage:
4757
- * only code inside the workflow body's async context can trigger it, so
4758
- * host code running concurrently, engine internals outside the body, and
4759
- * other runs never produce a false warning, and nothing is ever restored,
4760
- * so concurrent executes cannot race the patch state.
4860
+ * of keys must be stable. Bare-nondeterminism detection is ENGINE-owned
4861
+ * since RV-209: the engine wraps its `execute` call in
4862
+ * `withDeterminismDetection` (runner/determinism.ts), which classifies
4863
+ * bare Date.now/Math.random callers, emits the structured
4864
+ * `determinism:warning` event on the run's stream, and under
4865
+ * `determinism.mode: 'error'` rejects the run with a typed
4866
+ * DeterminismError. The runner itself is a pure executor, so the frozen
4867
+ * ScriptRunner seam carries no detection surface; a standalone execute
4868
+ * outside an engine runs without detection.
4761
4869
  */
4762
4870
  declare class InProcessRunner implements ScriptRunner {
4763
4871
  private readonly onEscalation?;
@@ -4769,6 +4877,39 @@ declare class InProcessRunner implements ScriptRunner {
4769
4877
  execute<A, R>(wf: Workflow<A, R> | CompiledWorkflow, ctx: Ctx<never>, args: A): Promise<R>;
4770
4878
  }
4771
4879
  //#endregion
4880
+ //#region src/runner/determinism.d.ts
4881
+ /**
4882
+ * Detection modes. 'off': never detect. 'warn' (the default, and the
4883
+ * pre-RV-209 behavior): detect outside production (NODE_ENV !==
4884
+ * 'production'), emit one `determinism:warning` event and one process
4885
+ * warning per category per segment, never reject. 'error': detect in
4886
+ * EVERY environment including production, and reject the run at the
4887
+ * first workflow-origin call with a typed DeterminismError (the strict
4888
+ * gate for replay-verified pipelines).
4889
+ */
4890
+ type DeterminismMode = "off" | "warn" | "error";
4891
+ /** Host configuration for the guard (CreateEngineOptions.determinism). */
4892
+ interface DeterminismConfig {
4893
+ mode?: DeterminismMode;
4894
+ /**
4895
+ * Caller frames matching any pattern are exempt by explicit host
4896
+ * decision: classified 'allowlisted' in the emitted event, never a
4897
+ * process warning, never a rejection. A string matches as a
4898
+ * substring of the frame; a RegExp matches by test. Patterns match
4899
+ * the RAW frame, before any redaction. Installed dependencies
4900
+ * (node_modules) and Node runtime frames (`node:` specifiers) are
4901
+ * exempt WITHOUT configuration and emit nothing at all.
4902
+ */
4903
+ allowlist?: ReadonlyArray<string | RegExp>;
4904
+ /**
4905
+ * Redaction hook for public telemetry: applied to the frame and the
4906
+ * parsed file path before they leave in events, process warnings, and
4907
+ * DeterminismError data, so absolute host paths need not reach an
4908
+ * OTel backend. Default: identity.
4909
+ */
4910
+ redact?: (frame: string) => string;
4911
+ }
4912
+ //#endregion
4772
4913
  //#region src/model/pricing.d.ts
4773
4914
  interface PriceTable {
4774
4915
  /** Monotonic version string; recorded in decision entries. */
@@ -4916,6 +5057,18 @@ interface CreateEngineOptions {
4916
5057
  redaction?: {
4917
5058
  maskEvents?: boolean;
4918
5059
  };
5060
+ /**
5061
+ * Bare-nondeterminism detection over in-process workflow bodies
5062
+ * (RV-209): mode 'off' | 'warn' (default; detects outside production)
5063
+ * | 'error' (detects everywhere and rejects the run at the first
5064
+ * workflow-origin bare Date.now/Math.random with a typed
5065
+ * DeterminismError), plus the frame `allowlist` for confirmed-safe
5066
+ * callers and the `redact` hook for public telemetry. Workflow-origin
5067
+ * violations emit the structured `determinism:warning` event with the
5068
+ * caller frame and parsed file/line; installed dependencies and Node
5069
+ * runtime frames are classified exempt and stay silent.
5070
+ */
5071
+ determinism?: DeterminismConfig;
4919
5072
  }
4920
5073
  interface RunOptions {
4921
5074
  /** Explicit id; otherwise the engine mints a ULID. */
@@ -5065,6 +5218,19 @@ declare function workflowSourceRef(runId: string): string;
5065
5218
  * `argsHash` field docs).
5066
5219
  */
5067
5220
  declare function hashRunArgs(args: unknown): string | undefined;
5221
+ /**
5222
+ * sha256 hex over the JCS canonical serialization of a run's result
5223
+ * value: the digest the engine records as `outputHash` on the journaled
5224
+ * run-settle decision when the settling segment computed a value, and
5225
+ * the value `rulvar replay --compare-output-hash` compares a replayed
5226
+ * result against (RV-209). Best-effort by design: returns undefined for
5227
+ * undefined values and for values JCS cannot serialize (functions,
5228
+ * cycles, non-finite numbers), so an unhashable result records no
5229
+ * baseline rather than failing the settle. Like `hashRunArgs`, the
5230
+ * digest is deterministic and unsalted: treat it as sensitive-derived
5231
+ * metadata for low-entropy results.
5232
+ */
5233
+ declare function hashRunOutput(value: unknown): string | undefined;
5068
5234
  declare function createEngine(options: CreateEngineOptions): Engine;
5069
5235
  //#endregion
5070
5236
  //#region src/orchestrator/finish-validators.d.ts
@@ -6845,10 +7011,16 @@ declare function assertFencedWrites(stores: {
6845
7011
  //#region src/stores/reconcile.d.ts
6846
7012
  /** The decisionType of the journaled run settle entry. */
6847
7013
  declare const RUN_SETTLE_DECISION_TYPE = "run_settle";
6848
- /** The last journaled run settle of a journal, if any. */
7014
+ /**
7015
+ * The last journaled run settle of a journal, if any. `outputHash` is
7016
+ * present when that settle recorded the result digest (RV-209; settles
7017
+ * written before it, or over undefined/non-serializable results, carry
7018
+ * none).
7019
+ */
6849
7020
  declare function lastRunSettle(entries: readonly JournalEntry[]): {
6850
7021
  runStatus: RunStatus;
6851
7022
  seq: number;
7023
+ outputHash?: string;
6852
7024
  } | undefined;
6853
7025
  type RunAuditVerdict = "consistent" | "meta-behind" | "stranded" | "suspect";
6854
7026
  interface RunStateAudit {
@@ -7300,6 +7472,58 @@ declare class EventBus {
7300
7472
  iterate(): AsyncIterable<WorkflowEvent>;
7301
7473
  }
7302
7474
  //#endregion
7475
+ //#region src/l0/telemetry-reduce.d.ts
7476
+ /** One phase activation of one agent span. */
7477
+ interface PhaseRow {
7478
+ invocation: number;
7479
+ role: string;
7480
+ model: string;
7481
+ /** 0 until the end event arrives, and on replayed rows. */
7482
+ durationMs: number;
7483
+ usage: Usage;
7484
+ costUsd: number;
7485
+ outcome?: "ok" | "error";
7486
+ retries: number;
7487
+ replayed: boolean;
7488
+ /** True when the phase's end event never arrived. */
7489
+ open: boolean;
7490
+ }
7491
+ /** One logical agent span. */
7492
+ interface AgentInvocationRow {
7493
+ spanId: string;
7494
+ agentType: string;
7495
+ label?: string;
7496
+ /** The primary role from agent:start. */
7497
+ role?: string;
7498
+ /** From agent:end; absent while the span is open. */
7499
+ status?: string;
7500
+ usage: Usage;
7501
+ costUsd: number;
7502
+ usageApprox: boolean;
7503
+ retryCount: number;
7504
+ replayed: boolean;
7505
+ /** True when the span's agent:end never arrived. */
7506
+ open: boolean;
7507
+ phases: PhaseRow[];
7508
+ }
7509
+ /** The reduced table plus the per-role aggregate across every span. */
7510
+ interface InvocationTable {
7511
+ agents: AgentInvocationRow[];
7512
+ /** Aggregated over COMPLETED phase pairs, keyed by role. */
7513
+ byRole: Record<string, {
7514
+ usage: Usage;
7515
+ costUsd: number;
7516
+ }>;
7517
+ /** Sum of agent:end costUsd over settled spans. */
7518
+ totalCostUsd: number;
7519
+ }
7520
+ /**
7521
+ * Reduces one run's event stream (or any slice of it) to the invocation
7522
+ * table. Feed it the events in emission order; both a live stream and a
7523
+ * replayed one produce the same usage and cost columns.
7524
+ */
7525
+ declare function reduceInvocationTable(events: Iterable<WorkflowEvent>): InvocationTable;
7526
+ //#endregion
7303
7527
  //#region src/runner/sandbox-bridge.d.ts
7304
7528
  /** Methods a sandbox script may proxy to the host ctx. */
7305
7529
  type SandboxMethod = "agent" | "step" | "workflow" | "awaitExternal" | "parallel" | "pipeline" | "phase" | "budget.spent" | "budget.remaining";
@@ -7372,4 +7596,4 @@ interface SandboxBridge {
7372
7596
  declare const SANDBOX_AGENT_OPT_KEYS: readonly string[];
7373
7597
  declare function createSandboxBridge(ctx: Ctx<never>, options: SandboxBridgeOptions): SandboxBridge;
7374
7598
  //#endregion
7375
- export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, AgentOpts, AgentProfile, AgentProfilePermissions, AgentResult, AgentResultMeta, AgentStatus, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditRunsOptions, BUDGET_ABORT_REASON, BaseAppend, BriefOpts, BudgetAccountView, BudgetDefaults, BudgetExhaustedError, BudgetExhaustionDiagnostics, BudgetHooks, BudgetReserve, type Bytes, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, CacheHint, CacheTtl, CanUseTool, CanonicalId, CanonicalIdentity, CanonicalLadderSpec, CanonicalModelSpec, ChatEvent, ChatRequest, CheckpointState, ChildArtifactPage, ChildIdentityInput, ChildResultPage, type ClaimClass, type ClaimOp, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, type CoreEvents, CostAttribution, CostAttributionFacts, CostReport, CreateEngineOptions, Ctx, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DerivedKey, DeriverRegistry, DispositionRule, DispositionTable, DonorCandidate, DonorRef, DroppedItem, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EntryKind, EntryRef, EntryStatus, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, type EvidenceRef, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, FinishInfo, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, INBOX_PROPOSAL_TTL_DAYS, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, InvocationRole, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, JournalSerializationHook, type JournalStore, type Json, JsonSchema, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, type KbProposal, type KbProposalTrigger, KeyDeriver, KeyRing, KeyedLimiter, KnowledgeCasError, type KnowledgeSnapshot, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LadderSpec, type LeasableStore, type Lease, LeaseHeldError, Ledger, LineageCounters, LineageIndex, LineageRef, LineageRelation, LineageStats, LogicalTaskId, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, type MetaLookupStore, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, OrchestrateAcceptance, OrchestrateOptions, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, PhaseTarget, PipelineCollected, PipelineOpts, PlanInvariantError, PriceTable, PricedUsage, type Pricing, type PricingTier, type ProviderAdapter, QualityFloors, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStateAudit, RunStatus, RuntimeEventSink, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxBridge, SandboxBridgeOptions, SandboxError, SandboxHostToWorker, SandboxMethod, SandboxWorkerToHost, SchemaPair, SchemaSpec, SchemaValidationResult, ScopeSegment, ScriptRejected, ScriptRunner, ScrubNote, Semaphore, SerializationHook, Settled, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, StructuredOutputTier, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, TranscriptSerializationHook, type TranscriptStore, TriggerClass, TtlState, Usage, UsageLimits, UsageSlice, VerifiedRecommendation, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, WakeBudgetBlock, WakeDigest, WakeTrigger, WireError, Workflow, WorkflowCallOpts, type WorkflowEvent, type WorkflowEventBody, WorkflowRegistry, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileVerifiedLayer, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, readRunMeta, readTerminationInit, reconcileRunMeta, registryKeyRing, remeasureQueue, replayDisposition, requiredFieldsValidator, requiredSectionsValidator, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, snapshotUsage, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
7599
+ export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentResult, AgentResultMeta, AgentStatus, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditRunsOptions, BUDGET_ABORT_REASON, BaseAppend, BriefOpts, BudgetAccountView, BudgetDefaults, BudgetExhaustedError, BudgetExhaustionDiagnostics, BudgetHooks, BudgetReserve, type Bytes, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, CacheHint, CacheTtl, CanUseTool, CanonicalId, CanonicalIdentity, CanonicalLadderSpec, CanonicalModelSpec, ChatEvent, ChatRequest, CheckpointState, ChildArtifactPage, ChildIdentityInput, ChildResultPage, type ClaimClass, type ClaimOp, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, type CoreEvents, CostAttribution, CostAttributionFacts, CostReport, CreateEngineOptions, Ctx, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DonorCandidate, DonorRef, DroppedItem, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EntryKind, EntryRef, EntryStatus, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, type EvidenceRef, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, FinishInfo, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, INBOX_PROPOSAL_TTL_DAYS, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, InvocationRole, type InvocationTable, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, JournalSerializationHook, type JournalStore, type Json, JsonSchema, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, type KbProposal, type KbProposalTrigger, KeyDeriver, KeyRing, KeyedLimiter, KnowledgeCasError, type KnowledgeSnapshot, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LadderSpec, type LeasableStore, type Lease, LeaseHeldError, Ledger, LineageCounters, LineageIndex, LineageRef, LineageRelation, LineageStats, LogicalTaskId, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, type MetaLookupStore, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, OrchestrateAcceptance, OrchestrateOptions, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, type PhaseRow, PhaseTarget, PipelineCollected, PipelineOpts, PlanInvariantError, PriceTable, PricedUsage, type Pricing, type PricingTier, type ProviderAdapter, QualityFloors, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStateAudit, RunStatus, RuntimeEventSink, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxBridge, SandboxBridgeOptions, SandboxError, SandboxHostToWorker, SandboxMethod, SandboxWorkerToHost, SchemaPair, SchemaSpec, SchemaValidationResult, ScopeSegment, ScriptRejected, ScriptRunner, ScrubNote, Semaphore, SerializationHook, Settled, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, StructuredOutputTier, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, TranscriptSerializationHook, type TranscriptStore, TriggerClass, TtlState, Usage, UsageLimits, UsageSlice, VerifiedRecommendation, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, WakeBudgetBlock, WakeDigest, WakeTrigger, WireError, Workflow, WorkflowCallOpts, type WorkflowEvent, type WorkflowEventBody, WorkflowRegistry, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileVerifiedLayer, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, readRunMeta, readTerminationInit, reconcileRunMeta, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, requiredFieldsValidator, requiredSectionsValidator, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, snapshotUsage, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/dist/index.js CHANGED
@@ -289,6 +289,27 @@ var KnowledgeCasError = class extends RulvarError {
289
289
  }
290
290
  };
291
291
  /**
292
+ * A workflow-origin bare-nondeterminism violation under
293
+ * `determinism.mode: 'error'` (RV-209): bare `Date.now()` or
294
+ * `Math.random()` called from workflow code inside a run. Thrown at the
295
+ * offending call site (and re-thrown at settle if the workflow swallowed
296
+ * it), so the run rejects instead of recording a value replay cannot
297
+ * reproduce. `data` carries the structured localization: `category`,
298
+ * `frame`, and the parsed `file`/`line`/`column` when the frame names
299
+ * one. Never journaled as its own entry; the run settles 'error' with
300
+ * this wire error. Exempt provenances (installed dependencies, Node
301
+ * runtime frames, allowlisted patterns) never raise it.
302
+ */
303
+ var DeterminismError = class extends RulvarError {
304
+ code = "determinism";
305
+ constructor(message, opts) {
306
+ super(message, {
307
+ retryable: false,
308
+ ...opts
309
+ });
310
+ }
311
+ };
312
+ /**
292
313
  * Projects an AgentError to its WireError form: code 'agent', with kind,
293
314
  * retryAfterMs, and issues carried in data. Issue paths are flattened to
294
315
  * JSON-safe segments.
@@ -6580,7 +6601,12 @@ const TERMINAL = /* @__PURE__ */ new Set([
6580
6601
  "exhausted"
6581
6602
  ]);
6582
6603
  const wallClock = Date.now.bind(globalThis);
6583
- /** The last journaled run settle of a journal, if any. */
6604
+ /**
6605
+ * The last journaled run settle of a journal, if any. `outputHash` is
6606
+ * present when that settle recorded the result digest (RV-209; settles
6607
+ * written before it, or over undefined/non-serializable results, carry
6608
+ * none).
6609
+ */
6584
6610
  function lastRunSettle(entries) {
6585
6611
  for (let i = entries.length - 1; i >= 0; i -= 1) {
6586
6612
  const entry = entries[i];
@@ -6588,7 +6614,8 @@ function lastRunSettle(entries) {
6588
6614
  const value = entry.value;
6589
6615
  if (value?.decisionType === "run_settle" && typeof value.runStatus === "string" && RUN_STATUSES.has(value.runStatus)) return {
6590
6616
  runStatus: value.runStatus,
6591
- seq: entry.seq
6617
+ seq: entry.seq,
6618
+ ...typeof value.outputHash === "string" ? { outputHash: value.outputHash } : {}
6592
6619
  };
6593
6620
  }
6594
6621
  }
@@ -8515,7 +8542,7 @@ const ZERO_USAGE$1 = {
8515
8542
  cacheReadTokens: 0,
8516
8543
  cacheWriteTokens: 0
8517
8544
  };
8518
- function addUsage(total, turn) {
8545
+ function addUsage$1(total, turn) {
8519
8546
  const sum = {
8520
8547
  inputTokens: total.inputTokens + turn.inputTokens,
8521
8548
  outputTokens: total.outputTokens + turn.outputTokens,
@@ -8625,7 +8652,7 @@ async function streamTurn(adapter, req, options) {
8625
8652
  cacheWriteTokens: cleaned.cacheWriteTokens ?? 0
8626
8653
  };
8627
8654
  if (cleaned.reasoningTokens !== void 0) delta.reasoningTokens = cleaned.reasoningTokens;
8628
- reported = addUsage(reported, delta);
8655
+ reported = addUsage$1(reported, delta);
8629
8656
  options.onUsage?.(delta);
8630
8657
  break;
8631
8658
  }
@@ -8872,9 +8899,73 @@ async function runAgent(options) {
8872
8899
  usageByPhaseModel.set(key, {
8873
8900
  role,
8874
8901
  servedBy: ref,
8875
- usage: addUsage(prior?.usage ?? ZERO_USAGE$1, usage)
8902
+ usage: addUsage$1(prior?.usage ?? ZERO_USAGE$1, usage)
8903
+ });
8904
+ };
8905
+ let invocationCounter = 0;
8906
+ let transportRetries = 0;
8907
+ const roleUsageSnapshot = (role) => {
8908
+ const snapshot = /* @__PURE__ */ new Map();
8909
+ for (const [key, slice] of usageByPhaseModel) if (slice.role === role) snapshot.set(key, slice.usage);
8910
+ return snapshot;
8911
+ };
8912
+ const usageDelta = (after, before) => {
8913
+ const base = before ?? ZERO_USAGE$1;
8914
+ const delta = {
8915
+ inputTokens: Math.max(0, after.inputTokens - base.inputTokens),
8916
+ outputTokens: Math.max(0, after.outputTokens - base.outputTokens),
8917
+ cacheReadTokens: Math.max(0, after.cacheReadTokens - base.cacheReadTokens),
8918
+ cacheWriteTokens: Math.max(0, after.cacheWriteTokens - base.cacheWriteTokens)
8919
+ };
8920
+ const reasoning = (after.reasoningTokens ?? 0) - (base.reasoningTokens ?? 0);
8921
+ if (reasoning > 0) delta.reasoningTokens = reasoning;
8922
+ return delta;
8923
+ };
8924
+ const beginPhase = (role, model) => {
8925
+ invocationCounter += 1;
8926
+ events?.emit({
8927
+ type: "agent:phase:start",
8928
+ agentType,
8929
+ label: options.label,
8930
+ role,
8931
+ model,
8932
+ invocation: invocationCounter
8933
+ });
8934
+ return {
8935
+ invocation: invocationCounter,
8936
+ role,
8937
+ model,
8938
+ before: roleUsageSnapshot(role),
8939
+ startedAtMs: now(),
8940
+ retriesBefore: transportRetries
8941
+ };
8942
+ };
8943
+ const endPhase = (phase, outcome, servedModel) => {
8944
+ let phaseUsage = ZERO_USAGE$1;
8945
+ let phaseUsd = 0;
8946
+ for (const [key, slice] of usageByPhaseModel) {
8947
+ if (slice.role !== phase.role) continue;
8948
+ const delta = usageDelta(slice.usage, phase.before.get(key));
8949
+ phaseUsage = addUsage$1(phaseUsage, delta);
8950
+ const priced = options.priceUsd?.(slice.servedBy, delta) ?? 0;
8951
+ if (Number.isFinite(priced) && priced > 0) phaseUsd += priced;
8952
+ }
8953
+ const retries = transportRetries - phase.retriesBefore;
8954
+ events?.emit({
8955
+ type: "agent:phase:end",
8956
+ agentType,
8957
+ label: options.label,
8958
+ role: phase.role,
8959
+ model: servedModel ?? phase.model,
8960
+ invocation: phase.invocation,
8961
+ durationMs: Math.max(0, now() - phase.startedAtMs),
8962
+ usage: phaseUsage,
8963
+ costUsd: phaseUsd,
8964
+ outcome,
8965
+ ...retries > 0 ? { retries } : {}
8876
8966
  });
8877
8967
  };
8968
+ const phaseOutcome = () => status === "error" || status === "cancelled" ? "error" : "ok";
8878
8969
  let turns = 0;
8879
8970
  let schemaAttempts = 0;
8880
8971
  let output = null;
@@ -9181,6 +9272,7 @@ async function runAgent(options) {
9181
9272
  model: servedBy,
9182
9273
  role: primaryRole
9183
9274
  });
9275
+ const loopPhase = beginPhase(primaryRole, servedBy);
9184
9276
  let invariantViolation;
9185
9277
  const recordUsage = (usage, reported, adapterId, ref, role, streamViolation) => {
9186
9278
  if (streamViolation !== void 0) invariantViolation ??= `adapter '${adapterId}' violated the Usage invariant: ${streamViolation}`;
@@ -9188,7 +9280,7 @@ async function runAgent(options) {
9188
9280
  const violation = usageInvariantViolation(snapshot, adapterId);
9189
9281
  if (violation !== void 0) invariantViolation ??= violation;
9190
9282
  const safe = violation === void 0 ? snapshot : sanitizeUsage(snapshot);
9191
- totalUsage = addUsage(totalUsage, safe);
9283
+ totalUsage = addUsage$1(totalUsage, safe);
9192
9284
  addPhaseUsage(role, ref, safe);
9193
9285
  const remainder = {
9194
9286
  inputTokens: Math.max(0, safe.inputTokens - reported.inputTokens),
@@ -9290,13 +9382,16 @@ async function runAgent(options) {
9290
9382
  target
9291
9383
  };
9292
9384
  const retryAfter = (outcome.wireError?.data)?.retryAfterMs;
9293
- if (outcome.wireError !== void 0) events?.emit({
9294
- type: "agent:error",
9295
- agentType,
9296
- label: options.label,
9297
- error: outcome.wireError,
9298
- willRetry: true
9299
- });
9385
+ if (outcome.wireError !== void 0) {
9386
+ transportRetries += 1;
9387
+ events?.emit({
9388
+ type: "agent:error",
9389
+ agentType,
9390
+ label: options.label,
9391
+ error: outcome.wireError,
9392
+ willRetry: true
9393
+ });
9394
+ }
9300
9395
  await backoffWait(retryDelayMs(retryPolicy, tries - 1, typeof retryAfter === "number" ? retryAfter : void 0, retryRandom));
9301
9396
  const abortedAfter = abortKind();
9302
9397
  if (abortedAfter !== void 0) return {
@@ -9528,13 +9623,7 @@ async function runAgent(options) {
9528
9623
  ...options.compaction?.threshold === void 0 ? {} : { threshold: options.compaction.threshold }
9529
9624
  })) {
9530
9625
  const summarizeResolved = options.summarize.resolved;
9531
- events?.emit({
9532
- type: "agent:start",
9533
- agentType,
9534
- label: options.label,
9535
- model: summarizeResolved.ref,
9536
- role: "summarize"
9537
- });
9626
+ const summarizePhase = beginPhase("summarize", summarizeResolved.ref);
9538
9627
  for (const scrub of summarizeResolved.scrubs) events?.emit({
9539
9628
  type: "log",
9540
9629
  level: "warn",
@@ -9548,6 +9637,7 @@ async function runAgent(options) {
9548
9637
  kind: "budget",
9549
9638
  retryable: false
9550
9639
  };
9640
+ endPhase(summarizePhase, "error");
9551
9641
  break;
9552
9642
  }
9553
9643
  turns += 1;
@@ -9586,9 +9676,11 @@ async function runAgent(options) {
9586
9676
  retryable: false
9587
9677
  };
9588
9678
  errorMessage = thrown.message;
9679
+ endPhase(summarizePhase, "error");
9589
9680
  break;
9590
9681
  }
9591
- const { outcome: summary } = summaryDispatch;
9682
+ const { outcome: summary, target: summarizeTarget } = summaryDispatch;
9683
+ const summarizeServed = summarizeTarget.resolved.ref;
9592
9684
  usageApprox = usageApprox || summary.usageApprox;
9593
9685
  if (summary.aborted === "budget") {
9594
9686
  status = "cancelled";
@@ -9596,10 +9688,12 @@ async function runAgent(options) {
9596
9688
  kind: "budget",
9597
9689
  retryable: false
9598
9690
  };
9691
+ endPhase(summarizePhase, "error", summarizeServed);
9599
9692
  break;
9600
9693
  }
9601
9694
  if (summary.aborted === "external") {
9602
9695
  status = "cancelled";
9696
+ endPhase(summarizePhase, "error", summarizeServed);
9603
9697
  break;
9604
9698
  }
9605
9699
  if (summary.wireError !== void 0 || summary.aborted === "idle" || summary.turn.text.trim() === "") {
@@ -9609,6 +9703,7 @@ async function runAgent(options) {
9609
9703
  level: "warn",
9610
9704
  msg: "compaction disabled for this run: the summarize invocation " + (summary.wireError !== void 0 ? `failed (${summary.wireError.message})` : summary.aborted === "idle" ? "timed out" : "returned an empty summary")
9611
9705
  });
9706
+ endPhase(summarizePhase, "error", summarizeServed);
9612
9707
  } else {
9613
9708
  const compacted = compactMessages(messages, summary.turn.text);
9614
9709
  messages.length = 0;
@@ -9618,6 +9713,7 @@ async function runAgent(options) {
9618
9713
  inputTokens: 0,
9619
9714
  outputTokens: 0
9620
9715
  };
9716
+ endPhase(summarizePhase, "ok", summarizeServed);
9621
9717
  }
9622
9718
  }
9623
9719
  await saveBoundary();
@@ -9702,15 +9798,11 @@ async function runAgent(options) {
9702
9798
  await saveBoundary();
9703
9799
  continue loop;
9704
9800
  }
9801
+ endPhase(loopPhase, phaseOutcome(), servedBy);
9705
9802
  if (status === "ok" && !finishedViaTool && options.finalize !== void 0) {
9706
9803
  const finalizeResolved = options.finalize.resolved;
9707
- events?.emit({
9708
- type: "agent:start",
9709
- agentType,
9710
- label: options.label,
9711
- model: finalizeResolved.ref,
9712
- role: "finalize"
9713
- });
9804
+ const finalizePhase = beginPhase("finalize", finalizeResolved.ref);
9805
+ let finalizeServed;
9714
9806
  let proceed = true;
9715
9807
  try {
9716
9808
  options.budget?.beforeTurn();
@@ -9769,6 +9861,7 @@ async function runAgent(options) {
9769
9861
  }
9770
9862
  if (finalizeDispatch !== void 0) {
9771
9863
  const { outcome, target: finalizeTarget } = finalizeDispatch;
9864
+ finalizeServed = finalizeTarget.resolved.ref;
9772
9865
  usageApprox = usageApprox || outcome.usageApprox;
9773
9866
  messages.push(assistantMsg(outcome.turn, liftRetainedParts(outcome.providerMetadata, finalizeTarget.adapter)));
9774
9867
  if (invariantViolation !== void 0) {
@@ -9818,16 +9911,12 @@ async function runAgent(options) {
9818
9911
  }
9819
9912
  }
9820
9913
  }
9914
+ endPhase(finalizePhase, phaseOutcome(), finalizeServed);
9821
9915
  }
9822
9916
  if (status === "ok" && !finishedViaTool && separateExtract && options.extract !== void 0 && options.schema !== void 0) {
9823
9917
  const extractResolved = options.extract.resolved;
9824
- events?.emit({
9825
- type: "agent:start",
9826
- agentType,
9827
- label: options.label,
9828
- model: extractResolved.ref,
9829
- role: "extract"
9830
- });
9918
+ const extractPhase = beginPhase("extract", extractResolved.ref);
9919
+ let extractServed;
9831
9920
  const extractTierFor = (target) => selectStructuredOutputTier(target.adapter.caps(target.resolved.model), options.canonicalSchema ?? {});
9832
9921
  const extractChain = [{
9833
9922
  adapter: options.extract.adapter,
@@ -9891,6 +9980,7 @@ async function runAgent(options) {
9891
9980
  break;
9892
9981
  }
9893
9982
  const { outcome, target: extractTarget } = extractDispatch;
9983
+ extractServed = extractTarget.resolved.ref;
9894
9984
  usageApprox = usageApprox || outcome.usageApprox;
9895
9985
  if (invariantViolation !== void 0) {
9896
9986
  status = "error";
@@ -9944,6 +10034,7 @@ async function runAgent(options) {
9944
10034
  }
9945
10035
  }
9946
10036
  }
10037
+ endPhase(extractPhase, phaseOutcome(), extractServed);
9947
10038
  }
9948
10039
  let transcriptRef = "";
9949
10040
  if (options.transcript !== void 0) {
@@ -9967,6 +10058,7 @@ async function runAgent(options) {
9967
10058
  if (abortClass !== void 0) result.abortClass = abortClass;
9968
10059
  if (errorMessage !== void 0) result.errorMessage = errorMessage;
9969
10060
  if (usageApprox) result.usageApprox = true;
10061
+ if (transportRetries > 0) result.transportRetries = transportRetries;
9970
10062
  return result;
9971
10063
  }
9972
10064
  //#endregion
@@ -11833,6 +11925,29 @@ function createCtx(internals, rootWorkflow) {
11833
11925
  durationMs: 0
11834
11926
  }, spanId, true);
11835
11927
  }
11928
+ if (terminal !== void 0) entryUsageSlices(terminal).forEach((slice, index) => {
11929
+ const priced = internals.priceUsd(slice.servedBy, slice.usage) ?? 0;
11930
+ const sliceUsd = Number.isFinite(priced) && priced > 0 ? priced : 0;
11931
+ const common = {
11932
+ agentType,
11933
+ label: opts.label,
11934
+ role: slice.role ?? primaryRole,
11935
+ model: slice.servedBy,
11936
+ invocation: index + 1
11937
+ };
11938
+ internals.events.emit({
11939
+ type: "agent:phase:start",
11940
+ ...common
11941
+ }, spanId, true);
11942
+ internals.events.emit({
11943
+ type: "agent:phase:end",
11944
+ ...common,
11945
+ durationMs: 0,
11946
+ usage: slice.usage,
11947
+ costUsd: sliceUsd,
11948
+ outcome: terminal.status === "error" || terminal.status === "cancelled" ? "error" : "ok"
11949
+ }, spanId, true);
11950
+ });
11836
11951
  internals.events.emit({
11837
11952
  type: "agent:end",
11838
11953
  agentType,
@@ -12323,7 +12438,8 @@ function createCtx(internals, rootWorkflow) {
12323
12438
  usage: result.usage,
12324
12439
  costUsd: result.costUsd,
12325
12440
  entryRef: terminal.seq,
12326
- ...resultUsageApprox ? { usageApprox: true } : {}
12441
+ ...resultUsageApprox ? { usageApprox: true } : {},
12442
+ ...result.transportRetries !== void 0 && result.transportRetries > 0 ? { retryCount: result.transportRetries } : {}
12327
12443
  }, spanId);
12328
12444
  if (result.status === "escalated" && result.escalation !== void 0) {
12329
12445
  let decision = flavorBDecision;
@@ -14298,6 +14414,132 @@ var EventBus = class {
14298
14414
  }
14299
14415
  };
14300
14416
  //#endregion
14417
+ //#region src/l0/telemetry-reduce.ts
14418
+ const ZERO = {
14419
+ inputTokens: 0,
14420
+ outputTokens: 0,
14421
+ cacheReadTokens: 0,
14422
+ cacheWriteTokens: 0
14423
+ };
14424
+ function addUsage(a, b) {
14425
+ const sum = {
14426
+ inputTokens: a.inputTokens + b.inputTokens,
14427
+ outputTokens: a.outputTokens + b.outputTokens,
14428
+ cacheReadTokens: a.cacheReadTokens + b.cacheReadTokens,
14429
+ cacheWriteTokens: a.cacheWriteTokens + b.cacheWriteTokens
14430
+ };
14431
+ const reasoning = (a.reasoningTokens ?? 0) + (b.reasoningTokens ?? 0);
14432
+ if (reasoning > 0) sum.reasoningTokens = reasoning;
14433
+ return sum;
14434
+ }
14435
+ /**
14436
+ * Reduces one run's event stream (or any slice of it) to the invocation
14437
+ * table. Feed it the events in emission order; both a live stream and a
14438
+ * replayed one produce the same usage and cost columns.
14439
+ */
14440
+ function reduceInvocationTable(events) {
14441
+ const rows = /* @__PURE__ */ new Map();
14442
+ const order = [];
14443
+ const openPhases = /* @__PURE__ */ new Map();
14444
+ const byRole = {};
14445
+ let totalCostUsd = 0;
14446
+ const rowFor = (event) => {
14447
+ let row = rows.get(event.spanId);
14448
+ if (row === void 0) {
14449
+ row = {
14450
+ spanId: event.spanId,
14451
+ agentType: event.agentType,
14452
+ ...event.label === void 0 ? {} : { label: event.label },
14453
+ usage: ZERO,
14454
+ costUsd: 0,
14455
+ usageApprox: false,
14456
+ retryCount: 0,
14457
+ replayed: event.replayed === true,
14458
+ open: true,
14459
+ phases: []
14460
+ };
14461
+ rows.set(event.spanId, row);
14462
+ order.push(row);
14463
+ }
14464
+ return row;
14465
+ };
14466
+ for (const event of events) switch (event.type) {
14467
+ case "agent:start": {
14468
+ const row = rowFor(event);
14469
+ row.role = event.role;
14470
+ break;
14471
+ }
14472
+ case "agent:phase:start": {
14473
+ const row = rowFor(event);
14474
+ const phase = {
14475
+ invocation: event.invocation,
14476
+ role: event.role,
14477
+ model: event.model,
14478
+ durationMs: 0,
14479
+ usage: ZERO,
14480
+ costUsd: 0,
14481
+ retries: 0,
14482
+ replayed: event.replayed === true,
14483
+ open: true
14484
+ };
14485
+ row.phases.push(phase);
14486
+ openPhases.set(`${event.spanId}#${event.invocation}`, phase);
14487
+ break;
14488
+ }
14489
+ case "agent:phase:end": {
14490
+ const key = `${event.spanId}#${event.invocation}`;
14491
+ let phase = openPhases.get(key);
14492
+ if (phase === void 0) {
14493
+ phase = {
14494
+ invocation: event.invocation,
14495
+ role: event.role,
14496
+ model: event.model,
14497
+ durationMs: 0,
14498
+ usage: ZERO,
14499
+ costUsd: 0,
14500
+ retries: 0,
14501
+ replayed: event.replayed === true,
14502
+ open: true
14503
+ };
14504
+ rowFor(event).phases.push(phase);
14505
+ }
14506
+ openPhases.delete(key);
14507
+ phase.open = false;
14508
+ phase.role = event.role;
14509
+ phase.model = event.model;
14510
+ phase.durationMs = event.durationMs;
14511
+ phase.usage = event.usage;
14512
+ phase.costUsd = event.costUsd;
14513
+ phase.outcome = event.outcome;
14514
+ phase.retries = event.retries ?? 0;
14515
+ const bucket = byRole[event.role] ??= {
14516
+ usage: ZERO,
14517
+ costUsd: 0
14518
+ };
14519
+ bucket.usage = addUsage(bucket.usage, event.usage);
14520
+ bucket.costUsd += event.costUsd;
14521
+ break;
14522
+ }
14523
+ case "agent:end": {
14524
+ const row = rowFor(event);
14525
+ row.open = false;
14526
+ row.status = event.status;
14527
+ row.usage = event.usage;
14528
+ row.costUsd = event.costUsd;
14529
+ row.usageApprox = event.usageApprox === true;
14530
+ row.retryCount = event.retryCount ?? 0;
14531
+ totalCostUsd += event.costUsd;
14532
+ break;
14533
+ }
14534
+ default: break;
14535
+ }
14536
+ return {
14537
+ agents: order,
14538
+ byRole,
14539
+ totalCostUsd
14540
+ };
14541
+ }
14542
+ //#endregion
14301
14543
  //#region src/l0/run-id.ts
14302
14544
  /**
14303
14545
  * Run id containment (v1.36.0 review SEC-P1). A runId becomes both a
@@ -14323,46 +14565,172 @@ function assertSafeRunId(runId, context) {
14323
14565
  //#endregion
14324
14566
  //#region src/runner/inprocess.ts
14325
14567
  /**
14326
- * ScriptRunner SPI and InProcessRunner (M1-T11).
14568
+ * The mode (a) runner for human-authored closures. Determinism is enforced
14569
+ * by convention, lint, and the ctx shims, NOT by a VM: only the sequence
14570
+ * of keys must be stable. Bare-nondeterminism detection is ENGINE-owned
14571
+ * since RV-209: the engine wraps its `execute` call in
14572
+ * `withDeterminismDetection` (runner/determinism.ts), which classifies
14573
+ * bare Date.now/Math.random callers, emits the structured
14574
+ * `determinism:warning` event on the run's stream, and under
14575
+ * `determinism.mode: 'error'` rejects the run with a typed
14576
+ * DeterminismError. The runner itself is a pure executor, so the frozen
14577
+ * ScriptRunner seam carries no detection surface; a standalone execute
14578
+ * outside an engine runs without detection.
14579
+ */
14580
+ var InProcessRunner = class {
14581
+ onEscalation;
14582
+ constructor(o) {
14583
+ if (o?.onEscalation !== void 0) this.onEscalation = o.onEscalation;
14584
+ }
14585
+ /** The hook is read by the escalation delivery path from M3 onward. */
14586
+ get escalationHook() {
14587
+ return this.onEscalation;
14588
+ }
14589
+ async execute(wf, ctx, args) {
14590
+ if (wf.kind !== "workflow") throw new TypeError("InProcessRunner executes closure Workflow values only; CompiledWorkflow runs in the worker sandbox (@rulvar/planner, M6)");
14591
+ return await wf.body(ctx, args);
14592
+ }
14593
+ };
14594
+ //#endregion
14595
+ //#region src/runner/determinism.ts
14596
+ /**
14597
+ * Bare-nondeterminism detection (RV-209): the engine-owned guard that
14598
+ * classifies bare `Date.now()`/`Math.random()` calls observed inside a
14599
+ * run, localizes workflow-origin ones to a file and line, emits the
14600
+ * structured `determinism:warning` event, and under `mode: 'error'`
14601
+ * rejects the run with a typed DeterminismError instead of letting a
14602
+ * value replay cannot reproduce into the result.
14327
14603
  *
14328
- * Script runner contract: https://docs.rulvar.com/guide/planner
14329
- * Workflow (a closure value) runs in process only; CompiledWorkflow is the
14330
- * only form admissible to the worker sandbox and first exists at M6
14331
- * (compileScript in @rulvar/planner), so until then the engine accepts
14332
- * only in-process Workflow values. The SPI's L0 listing refers
14333
- * to its frozen-seam status; the declaration lives here with its types.
14604
+ * The machinery began life inside InProcessRunner (dev-mode process
14605
+ * warnings only); it lives here so the engine can thread the run's
14606
+ * event channel and the host's DeterminismConfig without touching the
14607
+ * frozen ScriptRunner seam: the engine wraps the in-process
14608
+ * `runner.execute(...)` call in `withDeterminismDetection`, and the
14609
+ * runner itself stays a pure executor.
14610
+ *
14611
+ * Attribution is by AsyncLocalStorage: only code inside the wrapped
14612
+ * execution inherits the detection store, so host code running
14613
+ * concurrently, engine internals outside the body, and other runs never
14614
+ * false-warn. The globals are patched ONCE per process and never
14615
+ * restored (outside a detection context the patch is a transparent
14616
+ * passthrough); the previous per-execute patch/restore pair could race
14617
+ * under concurrent runs (the false RULVAR_BARE_DATE_NOW class the 1.5.2
14618
+ * review reproduced). Rulvar's own internals never reach the check:
14619
+ * every internal real-time read binds the module-load clock
14620
+ * (l0/real-clock.ts and the ULID factory default), never the live
14621
+ * global (v1.18.0 review P2-6).
14334
14622
  */
14335
14623
  const detection = new AsyncLocalStorage();
14336
14624
  let globalsPatched = false;
14625
+ const MODES = /* @__PURE__ */ new Set([
14626
+ "off",
14627
+ "warn",
14628
+ "error"
14629
+ ]);
14337
14630
  /**
14338
- * Stack line 0 names the Error, line 1 this helper, line 2 the patched
14339
- * global, line 3 the caller whose provenance decides (the layout is
14340
- * pinned by construction: this helper is only ever called by the two
14341
- * patched globals). Two origins are exempt: installed dependencies (a
14342
- * provider SDK, any transitive package, rulvar's own published dist),
14343
- * which live under node_modules, and Node's own machinery (the undici
14344
- * transport behind fetch, timers, stream internals), whose frames carry
14345
- * `node:` specifiers and inherit the run's async context. The guard
14346
- * exists for workflow code, which imports from both but lives in
14347
- * neither. Rulvar's own internals never reach this check at all: every
14348
- * internal real-time read binds the module-load clock (l0/real-clock.ts
14349
- * and the ULID factory default), never the live global, so frames from
14350
- * workspace dists or this repo's sources cannot false-warn (v1.18.0
14351
- * review P2-6).
14631
+ * Fail-loud validation at engine construction: an invalid mode, a
14632
+ * non-function redact hook, or a malformed allowlist entry is a
14633
+ * ConfigError before any run can start under it.
14634
+ */
14635
+ function validateDeterminismConfig(config) {
14636
+ if (config === void 0) return;
14637
+ if (config.mode !== void 0 && !MODES.has(config.mode)) throw new ConfigError(`determinism.mode must be 'off', 'warn', or 'error'; got '${String(config.mode)}'`);
14638
+ if (config.allowlist !== void 0) {
14639
+ for (const pattern of config.allowlist) if (typeof pattern !== "string" && !(pattern instanceof RegExp)) throw new ConfigError("determinism.allowlist entries must be strings (substring match) or RegExp values");
14640
+ }
14641
+ if (config.redact !== void 0 && typeof config.redact !== "function") throw new ConfigError("determinism.redact must be a function (frame: string) => string");
14642
+ }
14643
+ function resolveConfig(config) {
14644
+ return {
14645
+ mode: config?.mode ?? "warn",
14646
+ allowlist: config?.allowlist ?? [],
14647
+ redact: config?.redact ?? ((frame) => frame)
14648
+ };
14649
+ }
14650
+ /**
14651
+ * The trailing `path:line:column` of a V8 stack frame, in both layouts:
14652
+ * `at fn (/abs/path.ts:12:5)` and `at file:///abs/path.ts:12:5`. Frames
14653
+ * without one (native frames, nested eval) yield undefined and the
14654
+ * event carries the frame string alone.
14352
14655
  */
14353
- function libraryCaller() {
14656
+ const FRAME_LOCATION = /(?:\(|at\s)([^()]+):(\d+):(\d+)\)?\s*$/;
14657
+ function parseFrameLocation(frame) {
14658
+ const match = FRAME_LOCATION.exec(frame);
14659
+ if (match === null) return;
14660
+ return {
14661
+ file: match[1].replace(/\?.*$/, ""),
14662
+ line: Number(match[2]),
14663
+ column: Number(match[3])
14664
+ };
14665
+ }
14666
+ function matchesAllowlist(frame, allowlist) {
14667
+ return allowlist.some((pattern) => typeof pattern === "string" ? frame.includes(pattern) : pattern.test(frame));
14668
+ }
14669
+ /**
14670
+ * Stack line 0 names the Error, line 1 this observer, line 2 the patched
14671
+ * global, line 3 the caller whose provenance decides (the layout is
14672
+ * pinned by construction: the observer is only ever called by the two
14673
+ * patched globals). Two origins are exempt without configuration:
14674
+ * installed dependencies (a provider SDK, any transitive package,
14675
+ * rulvar's own published dist), which live under node_modules, and
14676
+ * Node's own machinery (the undici transport behind fetch, timers,
14677
+ * stream internals), whose frames carry `node:` specifiers and inherit
14678
+ * the run's async context. The guard exists for workflow code, which
14679
+ * imports from both but lives in neither.
14680
+ */
14681
+ function observeBareCall(category) {
14682
+ const state = detection.getStore();
14683
+ if (state === void 0) return;
14354
14684
  const caller = (/* @__PURE__ */ new Error()).stack?.split("\n")[3];
14355
- if (caller === void 0) return false;
14356
- return caller.includes("node_modules") || /[(\s]node:/.test(caller);
14685
+ if (caller === void 0) return;
14686
+ if (caller.includes("node_modules") || /[(\s]node:/.test(caller)) return;
14687
+ const frame = caller.trim();
14688
+ const provenance = matchesAllowlist(frame, state.config.allowlist) ? "allowlisted" : "workflow";
14689
+ const location = parseFrameLocation(frame);
14690
+ const redact = state.config.redact;
14691
+ const redactedFile = location === void 0 ? void 0 : redact(location.file);
14692
+ const dedupeKey = `${category}:${provenance}`;
14693
+ if (!state.emitted.has(dedupeKey)) {
14694
+ state.emitted.add(dedupeKey);
14695
+ state.emit({
14696
+ type: "determinism:warning",
14697
+ category,
14698
+ provenance,
14699
+ frame: redact(frame),
14700
+ ...location === void 0 || redactedFile === void 0 ? {} : {
14701
+ file: redactedFile,
14702
+ line: location.line,
14703
+ column: location.column
14704
+ }
14705
+ });
14706
+ if (provenance === "workflow" && state.config.mode === "warn") {
14707
+ const globalName = category === "bare-date-now" ? "Date.now()" : "Math.random()";
14708
+ const shim = category === "bare-date-now" ? "ctx.now()" : "ctx.random()";
14709
+ const at = location === void 0 ? "" : ` at ${redactedFile}:${location.line}:${location.column}`;
14710
+ process.emitWarning(`bare ${globalName} called inside a rulvar run${at}; use ${shim} so the value is journaled and stable on replay`, {
14711
+ code: category === "bare-date-now" ? "RULVAR_BARE_DATE_NOW" : "RULVAR_BARE_MATH_RANDOM",
14712
+ type: "RulvarWarning"
14713
+ });
14714
+ }
14715
+ }
14716
+ if (provenance === "workflow" && state.config.mode === "error") {
14717
+ const error = new DeterminismError(`bare ${category === "bare-date-now" ? "Date.now()" : "Math.random()"} called inside a rulvar run${location === void 0 ? "" : ` at ${redactedFile}:${location.line}:${location.column}`} under determinism.mode 'error'; use ${category === "bare-date-now" ? "ctx.now()" : "ctx.random()"} or allowlist the frame`, { data: {
14718
+ category,
14719
+ frame: redact(frame),
14720
+ ...location === void 0 || redactedFile === void 0 ? {} : {
14721
+ file: redactedFile,
14722
+ line: location.line,
14723
+ column: location.column
14724
+ }
14725
+ } });
14726
+ state.rejection ??= error;
14727
+ throw error;
14728
+ }
14357
14729
  }
14358
14730
  /**
14359
14731
  * Patches Date.now and Math.random ONCE per process and never restores:
14360
- * outside a workflow's async context the store is absent and the patch is
14361
- * a transparent passthrough. The previous per-execute patch/restore pair
14362
- * could race under concurrent runs (one run's restore removed another's
14363
- * patch, and the second restore re-installed a stale patched function
14364
- * PERMANENTLY, which could then warn on host code outside any run: the
14365
- * false RULVAR_BARE_DATE_NOW class the 1.5.2 review reproduced).
14732
+ * outside a detection context the store is absent and the patch is a
14733
+ * transparent passthrough.
14366
14734
  */
14367
14735
  function patchGlobalsOnce() {
14368
14736
  if (globalsPatched) return;
@@ -14370,60 +14738,36 @@ function patchGlobalsOnce() {
14370
14738
  const priorNow = Date.now;
14371
14739
  const priorRandom = Math.random;
14372
14740
  Date.now = function rulvarPatchedDateNow() {
14373
- const state = detection.getStore();
14374
- if (state !== void 0 && !state.warnedNow && !libraryCaller()) {
14375
- state.warnedNow = true;
14376
- process.emitWarning("bare Date.now() called inside a rulvar run; use ctx.now() so the value is journaled and stable on replay", {
14377
- code: "RULVAR_BARE_DATE_NOW",
14378
- type: "RulvarWarning"
14379
- });
14380
- }
14741
+ observeBareCall("bare-date-now");
14381
14742
  return priorNow();
14382
14743
  };
14383
14744
  Math.random = function rulvarPatchedMathRandom() {
14384
- const state = detection.getStore();
14385
- if (state !== void 0 && !state.warnedRandom && !libraryCaller()) {
14386
- state.warnedRandom = true;
14387
- process.emitWarning("bare Math.random() called inside a rulvar run; use ctx.random() so the value is journaled and stable on replay", {
14388
- code: "RULVAR_BARE_MATH_RANDOM",
14389
- type: "RulvarWarning"
14390
- });
14391
- }
14745
+ observeBareCall("bare-math-random");
14392
14746
  return priorRandom();
14393
14747
  };
14394
14748
  }
14395
14749
  /**
14396
- * The mode (a) runner for human-authored closures. Determinism is enforced
14397
- * by convention, lint, and the ctx shims, NOT by a VM: only the sequence
14398
- * of keys must be stable. Dev mode (NODE_ENV !== 'production') detects
14399
- * bare Date.now and Math.random and emits one warning per run pointing at
14400
- * ctx.now()/ctx.random(). Detection is attributed by AsyncLocalStorage:
14401
- * only code inside the workflow body's async context can trigger it, so
14402
- * host code running concurrently, engine internals outside the body, and
14403
- * other runs never produce a false warning, and nothing is ever restored,
14404
- * so concurrent executes cannot race the patch state.
14750
+ * Runs `fn` (the in-process execution of a workflow body) under
14751
+ * bare-nondeterminism detection. Detection is active for mode 'warn'
14752
+ * outside production and for mode 'error' everywhere; otherwise `fn`
14753
+ * runs untouched with zero overhead. In error mode, a workflow-origin
14754
+ * violation swallowed by the body is re-thrown after the body settles,
14755
+ * so the segment rejects either way.
14405
14756
  */
14406
- var InProcessRunner = class {
14407
- onEscalation;
14408
- constructor(o) {
14409
- if (o?.onEscalation !== void 0) this.onEscalation = o.onEscalation;
14410
- }
14411
- /** The hook is read by the escalation delivery path from M3 onward. */
14412
- get escalationHook() {
14413
- return this.onEscalation;
14414
- }
14415
- async execute(wf, ctx, args) {
14416
- if (wf.kind !== "workflow") throw new TypeError("InProcessRunner executes closure Workflow values only; CompiledWorkflow runs in the worker sandbox (@rulvar/planner, M6)");
14417
- if (process.env.NODE_ENV !== "production") {
14418
- patchGlobalsOnce();
14419
- return detection.run({
14420
- warnedNow: false,
14421
- warnedRandom: false
14422
- }, () => wf.body(ctx, args));
14423
- }
14424
- return await wf.body(ctx, args);
14425
- }
14426
- };
14757
+ function withDeterminismDetection(config, emit, fn) {
14758
+ const resolved = resolveConfig(config);
14759
+ if (!(resolved.mode === "error" || resolved.mode === "warn" && process.env.NODE_ENV !== "production")) return fn();
14760
+ patchGlobalsOnce();
14761
+ const state = {
14762
+ config: resolved,
14763
+ emit,
14764
+ emitted: /* @__PURE__ */ new Set()
14765
+ };
14766
+ return detection.run(state, fn).then((result) => {
14767
+ if (state.rejection !== void 0) throw state.rejection;
14768
+ return result;
14769
+ });
14770
+ }
14427
14771
  //#endregion
14428
14772
  //#region src/engine/engine.ts
14429
14773
  /**
@@ -14495,6 +14839,26 @@ function hashRunArgs(args) {
14495
14839
  if (args === void 0) return;
14496
14840
  return createHash("sha256").update(jcsSerialize(args), "utf8").digest("hex");
14497
14841
  }
14842
+ /**
14843
+ * sha256 hex over the JCS canonical serialization of a run's result
14844
+ * value: the digest the engine records as `outputHash` on the journaled
14845
+ * run-settle decision when the settling segment computed a value, and
14846
+ * the value `rulvar replay --compare-output-hash` compares a replayed
14847
+ * result against (RV-209). Best-effort by design: returns undefined for
14848
+ * undefined values and for values JCS cannot serialize (functions,
14849
+ * cycles, non-finite numbers), so an unhashable result records no
14850
+ * baseline rather than failing the settle. Like `hashRunArgs`, the
14851
+ * digest is deterministic and unsalted: treat it as sensitive-derived
14852
+ * metadata for low-entropy results.
14853
+ */
14854
+ function hashRunOutput(value) {
14855
+ if (value === void 0) return;
14856
+ try {
14857
+ return createHash("sha256").update(jcsSerialize(value), "utf8").digest("hex");
14858
+ } catch {
14859
+ return;
14860
+ }
14861
+ }
14498
14862
  function createEngine(options) {
14499
14863
  const adapters = buildAdapterRegistry(options.adapters);
14500
14864
  const rawJournal = options.stores?.journal ?? new InMemoryStore();
@@ -14523,6 +14887,7 @@ function createEngine(options) {
14523
14887
  if (profile.escalation?.minSpendUsd !== void 0) requireNonNegativeNumber(profile.escalation.minSpendUsd, `createEngine defaults.profiles['${name}'].escalation.minSpendUsd`);
14524
14888
  if (profile.compaction?.threshold !== void 0) requireFraction(profile.compaction.threshold, `createEngine defaults.profiles['${name}'].compaction.threshold`);
14525
14889
  }
14890
+ validateDeterminismConfig(options.determinism);
14526
14891
  const knowledgeStore = options.stores?.modelKnowledge;
14527
14892
  const knowledge = knowledgeStore === void 0 ? void 0 : { current: () => knowledgeStore.current() };
14528
14893
  const runner = new InProcessRunner(options.onEscalation === void 0 ? void 0 : { onEscalation: options.onEscalation });
@@ -14736,7 +15101,8 @@ function createEngine(options) {
14736
15101
  if (!validation.valid) throw new ConfigError(`arguments for workflow '${wf.name}' do not validate: ` + validation.issues.map((issue) => issue.message).join("; "));
14737
15102
  }
14738
15103
  const ctx = createCtx(internals, wf.kind === "workflow" ? wf : void 0);
14739
- const bodyPromise = (compiled === void 0 ? runner : options.runners?.sandbox).execute(wf, ctx, args);
15104
+ const selectedRunner = compiled === void 0 ? runner : options.runners?.sandbox;
15105
+ const bodyPromise = compiled === void 0 ? withDeterminismDetection(options.determinism, (event) => bus.emit(event, rootSpanId), () => selectedRunner.execute(wf, ctx, args)) : selectedRunner.execute(wf, ctx, args);
14740
15106
  const raced = await Promise.race([bodyPromise.then((result) => ({
14741
15107
  kind: "done",
14742
15108
  result
@@ -14805,19 +15171,23 @@ function createEngine(options) {
14805
15171
  const priorCount = resumeCtx?.priorEntries.length ?? 0;
14806
15172
  const appendedHere = replayer.snapshot().length - priorCount;
14807
15173
  const recorded = lastRunSettle(replayer.snapshot());
14808
- if (appendedHere > 0 || recorded !== void 0 && recorded.runStatus !== status) await replayer.appendSinglePhase({
14809
- scope: "",
14810
- key: deriverV2.deriveKey({ kind: "run-settle" }),
14811
- kind: "decision",
14812
- status: "ok",
14813
- spanId: rootSpanId,
14814
- site: "run-settle",
14815
- value: {
14816
- decisionType: RUN_SETTLE_DECISION_TYPE,
14817
- runStatus: status,
14818
- segment: segmentsBefore + 1
14819
- }
14820
- }).catch(() => void 0);
15174
+ if (appendedHere > 0 || recorded !== void 0 && recorded.runStatus !== status) {
15175
+ const outputHash = hashRunOutput(outcome.value);
15176
+ await replayer.appendSinglePhase({
15177
+ scope: "",
15178
+ key: deriverV2.deriveKey({ kind: "run-settle" }),
15179
+ kind: "decision",
15180
+ status: "ok",
15181
+ spanId: rootSpanId,
15182
+ site: "run-settle",
15183
+ value: {
15184
+ decisionType: RUN_SETTLE_DECISION_TYPE,
15185
+ runStatus: status,
15186
+ segment: segmentsBefore + 1,
15187
+ ...outputHash === void 0 ? {} : { outputHash }
15188
+ }
15189
+ }).catch(() => void 0);
15190
+ }
14821
15191
  }
14822
15192
  await putMeta(status).catch(() => void 0);
14823
15193
  bus.emit({
@@ -15296,4 +15666,4 @@ function createSandboxBridge(ctx, options) {
15296
15666
  };
15297
15667
  }
15298
15668
  //#endregion
15299
- export { AWAIT_SCHEMA, AdmissionController, AdmissionRejectedError, AgentCallError, BUDGET_ABORT_REASON, BudgetExhaustedError, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, ConfigError, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DedupIndex, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EscalationDecisionAbortedError, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GitWorktreeProvider, INBOX_PROPOSAL_TTL_DAYS, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JournalCompatibilityError, JournalMatcher, JournalMissError, JournalOrderViolation, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, KeyedLimiter, KnowledgeCasError, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LeaseHeldError, LineageIndex, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, PlanInvariantError, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxError, ScriptRejected, Semaphore, SpanRegistry, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileVerifiedLayer, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, readRunMeta, readTerminationInit, reconcileRunMeta, registryKeyRing, remeasureQueue, replayDisposition, requiredFieldsValidator, requiredSectionsValidator, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, snapshotUsage, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
15669
+ export { AWAIT_SCHEMA, AdmissionController, AdmissionRejectedError, AgentCallError, BUDGET_ABORT_REASON, BudgetExhaustedError, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, ConfigError, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DedupIndex, DeterminismError, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EscalationDecisionAbortedError, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GitWorktreeProvider, INBOX_PROPOSAL_TTL_DAYS, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JournalCompatibilityError, JournalMatcher, JournalMissError, JournalOrderViolation, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, KeyedLimiter, KnowledgeCasError, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LeaseHeldError, LineageIndex, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, PlanInvariantError, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxError, ScriptRejected, Semaphore, SpanRegistry, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileVerifiedLayer, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, readRunMeta, readTerminationInit, reconcileRunMeta, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, requiredFieldsValidator, requiredSectionsValidator, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, snapshotUsage, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/core",
3
- "version": "1.48.0",
3
+ "version": "1.50.0",
4
4
  "description": "Rulvar core: L0 contracts, journal kernel, ctx primitives, agent runtime, model router, tool system, dynamic orchestrator, InMemory and JSONL stores, event stream.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",