@rulvar/core 1.20.0 → 1.22.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.
package/dist/index.d.ts CHANGED
@@ -656,7 +656,10 @@ interface PricedUsage {
656
656
  * The single pricing fold over one terminal entry, shared by the kernel
657
657
  * ledger and the CostReport fold so a run's total and its per-model
658
658
  * breakdown can never disagree. Each slice is priced at ITS OWN model's
659
- * rate.
659
+ * rate. A price function returning NaN or a negative amount (a broken
660
+ * user-supplied rate) is treated exactly like a missing row: the slice
661
+ * folds as unpriced instead of poisoning or crediting the totals
662
+ * (v1.20.0 review follow-up).
660
663
  */
661
664
  declare function priceEntryUsage(entry: JournalEntry, priceUsd: (servedBy: ModelRef, usage: Usage) => number | undefined): PricedUsage;
662
665
  /**
@@ -703,6 +706,21 @@ type JournalEntry = {
703
706
  * like usageByModel.
704
707
  */
705
708
  costAttribution?: CostAttributionFacts;
709
+ /**
710
+ * The serving adapters' declared usage-telemetry semantics at write
711
+ * time (ProviderAdapter.usageSemantics), stamped so cost numbers stay
712
+ * auditable across normalization corrections: an UNSTAMPED OpenAI
713
+ * entry with cacheWriteTokens > 0 may have been written by rulvar
714
+ * v1.19.0, whose adapter double-counted cache writes into inputTokens
715
+ * (v1.20.0 review P1/P2-2). The stamp unions every adapter that
716
+ * served a slice of the entry, distinct declarations joined with '+'
717
+ * in first-appearance order, so a mixed-adapter call whose primary
718
+ * declares nothing is still dated by its declaring slices. Absent
719
+ * only when NO serving adapter declares semantics, and on all entries
720
+ * written before this shipped. Policy, never identity, exactly like
721
+ * usageByModel.
722
+ */
723
+ usageSemantics?: string;
706
724
  transcriptRef?: string;
707
725
  checkpointRef?: string;
708
726
  /**
@@ -854,6 +872,60 @@ declare function maskSecretsDeep<T>(value: T): T;
854
872
  /** Convenience for hosts: masks a Json value (alias of the deep walk). */
855
873
  declare function maskSecretsJson(value: Json): Json;
856
874
  //#endregion
875
+ //#region src/l0/usage.d.ts
876
+ /**
877
+ * Names every rule the given usage violates; an empty array means the
878
+ * usage satisfies the full canonical invariant: each present count is a
879
+ * finite nonnegative integer and
880
+ * `cacheReadTokens + cacheWriteTokens <= inputTokens`. The subset rule
881
+ * is checked with a negated comparison so a NaN operand counts as a
882
+ * violation rather than vacuously passing.
883
+ */
884
+ declare function usageViolations(usage: Usage): string[];
885
+ /**
886
+ * One count, repaired in the conservative direction: non-numbers and
887
+ * non-finite values floor to zero (no evidence, no charge and no
888
+ * credit), negatives floor to zero (a negative count can only CREDIT
889
+ * the budget, which hostile telemetry must never do), and fractions
890
+ * round UP so a repaired charge is never an undercharge.
891
+ */
892
+ declare function sanitizeTokenCount(value: number | undefined): number;
893
+ /**
894
+ * One field read per property, returning a detached plain copy. Both
895
+ * accounting boundaries validate and consume THIS snapshot, never the
896
+ * adapter-owned object, so a hostile accessor cannot answer the
897
+ * validator with valid counts and the accumulator with garbage.
898
+ */
899
+ declare function snapshotUsage(usage: Usage): Usage;
900
+ /**
901
+ * The per-field repair for DELTAS (mid-stream usage reports and other
902
+ * partial increments): each count is repaired like `sanitizeTokenCount`,
903
+ * but the whole-usage subset rule is deliberately NOT applied, because a
904
+ * delta legitimately carries cache counts without restating the full
905
+ * input in the same event; clamping those to the subset rule would
906
+ * silently drop a paid cache debit. Always returns a fresh object and
907
+ * is the identity on valid deltas.
908
+ */
909
+ declare function sanitizeUsageDelta(delta: Usage): Usage;
910
+ /**
911
+ * Conservative repair for accounting. Pairs with `usageViolations`: the
912
+ * violation fails the call loud, and the sanitized numbers are the only
913
+ * ones the journal, the cost report, and the budget may see. After the
914
+ * per-field repair the cache subsets clamp into the input with reads
915
+ * keeping priority, mirroring the adapter-level subset clamp. Valid
916
+ * usage passes through structurally unchanged.
917
+ */
918
+ declare function sanitizeUsage(usage: Usage): Usage;
919
+ //#endregion
920
+ //#region src/l0/terminal.d.ts
921
+ /**
922
+ * Neutralizes terminal control sequences and control characters in one
923
+ * untrusted string, collapsing each remaining control run to a single
924
+ * space so a value can never inject a newline, an escape sequence, or a
925
+ * hidden byte into a rendered line. Visible text is preserved.
926
+ */
927
+ declare function sanitizeTerminalText(text: string): string;
928
+ //#endregion
857
929
  //#region src/vendor/standard-schema.d.ts
858
930
  // Vendored from @standard-schema/spec@1.1.0 (MIT, Copyright (c) 2024 Colin
859
931
  // McDonnell), file dist/index.d.ts, byte-identical below this header.
@@ -1116,6 +1188,20 @@ interface ProviderAdapter {
1116
1188
  * family share retained blocks and projections; default = id.
1117
1189
  */
1118
1190
  provider?: string;
1191
+ /**
1192
+ * Declares WHICH reading of the provider's usage telemetry this
1193
+ * adapter normalizes under; the engine stamps it on usage-bearing
1194
+ * terminal entries so a journal records not only the numbers but the
1195
+ * semantics they were produced under (v1.20.0 review P1/P2-2). Bump
1196
+ * the string whenever the MEANING of a reported Usage field changes,
1197
+ * even when no pricing rate moves; a rate change is a PriceTable
1198
+ * pricingVersion bump instead. Entries persisted before this shipped
1199
+ * carry no stamp, which is itself information: an unstamped OpenAI
1200
+ * entry with cache writes may predate the v1.20.0 cache-subset
1201
+ * correction. Optional; adapters that never changed semantics can
1202
+ * omit it.
1203
+ */
1204
+ usageSemantics?: string;
1119
1205
  caps(model: string): ModelCaps;
1120
1206
  /** Refresh the capability table from live model lists. */
1121
1207
  refreshCaps?(): Promise<void>;
@@ -2130,6 +2216,8 @@ interface TerminalPatch {
2130
2216
  usageByModel?: UsageSlice[];
2131
2217
  /** Attribution facts behind the CostReport breakdowns; see JournalEntry. */
2132
2218
  costAttribution?: CostAttributionFacts;
2219
+ /** The serving adapter's usage-semantics version; see JournalEntry. */
2220
+ usageSemantics?: string;
2133
2221
  transcriptRef?: string;
2134
2222
  checkpointRef?: string;
2135
2223
  /** Terminal agent entries: Artifact list. */
@@ -3472,6 +3560,8 @@ declare class RunBudget {
3472
3560
  private exhaustedInternal;
3473
3561
  /** Models already warned about; the warning fires once per model per run. */
3474
3562
  private readonly unpricedWarned;
3563
+ /** Models whose price function already returned an invalid USD once. */
3564
+ private readonly invalidPriceWarned;
3475
3565
  constructor(options: {
3476
3566
  ceilingUsd?: number;
3477
3567
  lifetimeSpawnCap?: number;
@@ -6354,6 +6444,7 @@ declare class EventBus {
6354
6444
  private readonly listeners;
6355
6445
  private seq;
6356
6446
  private ended;
6447
+ private listenerErrorReported;
6357
6448
  constructor(options: {
6358
6449
  runId: string;
6359
6450
  spans: SpanRegistry;
@@ -6366,6 +6457,14 @@ declare class EventBus {
6366
6457
  maskEvents?: boolean;
6367
6458
  });
6368
6459
  emit(body: WorkflowEventBody, spanId: string, replayed?: boolean): WorkflowEvent;
6460
+ /**
6461
+ * A throwing on() listener is isolated (its work is best-effort
6462
+ * telemetry), and the failure surfaces ONCE as a warn log on this bus
6463
+ * rather than propagating into the run. The guard is set before the
6464
+ * warn is delivered, so a listener that also throws on the warn cannot
6465
+ * re-arm the report or recurse.
6466
+ */
6467
+ private reportListenerError;
6369
6468
  on<T extends WorkflowEvent["type"]>(type: T, cb: (event: Extract<WorkflowEvent, {
6370
6469
  type: T;
6371
6470
  }>) => void): () => void;
@@ -6438,4 +6537,4 @@ interface SandboxBridge {
6438
6537
  }
6439
6538
  declare function createSandboxBridge(ctx: Ctx<never>, options: SandboxBridgeOptions): SandboxBridge;
6440
6539
  //#endregion
6441
- 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, BUDGET_ABORT_REASON, 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, ChildIdentityInput, 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_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, 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, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EntryKind, EntryRef, EntryStatus, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, type EvidenceRef, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, FinishInfo, 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_DEPTH_CEILING, MatchResult, McpConfig, MechanicalGateProfile, MechanicalGateVerdict, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, 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, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RandIdentityInput, RandPayload, 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, RunBudget, RunEventSink, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStatus, RuntimeEventSink, 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, atCompactionThreshold, 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, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, 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, readTerminationInit, registryKeyRing, remeasureQueue, replayDisposition, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateSchemaSpec, validateTerminationLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
6540
+ 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, BUDGET_ABORT_REASON, 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, ChildIdentityInput, 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_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, 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, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EntryKind, EntryRef, EntryStatus, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, type EvidenceRef, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, FinishInfo, 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_DEPTH_CEILING, MatchResult, McpConfig, MechanicalGateProfile, MechanicalGateVerdict, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, 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, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RandIdentityInput, RandPayload, 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, RunBudget, RunEventSink, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStatus, RuntimeEventSink, 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, atCompactionThreshold, 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, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, 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, readTerminationInit, registryKeyRing, remeasureQueue, replayDisposition, 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, validateSchemaSpec, validateTerminationLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/dist/index.js CHANGED
@@ -547,6 +547,146 @@ function createCanonicalIdMinter(options) {
547
547
  return monotonicUlidFactory(options);
548
548
  }
549
549
  //#endregion
550
+ //#region src/l0/usage.ts
551
+ const COUNT_FIELDS = [
552
+ "inputTokens",
553
+ "outputTokens",
554
+ "cacheReadTokens",
555
+ "cacheWriteTokens",
556
+ "reasoningTokens"
557
+ ];
558
+ /**
559
+ * Names every rule the given usage violates; an empty array means the
560
+ * usage satisfies the full canonical invariant: each present count is a
561
+ * finite nonnegative integer and
562
+ * `cacheReadTokens + cacheWriteTokens <= inputTokens`. The subset rule
563
+ * is checked with a negated comparison so a NaN operand counts as a
564
+ * violation rather than vacuously passing.
565
+ */
566
+ function usageViolations(usage) {
567
+ const out = [];
568
+ for (const field of COUNT_FIELDS) {
569
+ const value = usage[field];
570
+ if (field === "reasoningTokens" && value === void 0) continue;
571
+ if (typeof value !== "number" || !Number.isFinite(value)) out.push(`${field} is ${String(value)}, not a finite number`);
572
+ else if (value < 0) out.push(`${field} is negative (${String(value)})`);
573
+ else if (!Number.isInteger(value)) out.push(`${field} is fractional (${String(value)})`);
574
+ else if (!Number.isSafeInteger(value)) out.push(`${field} is beyond the safe integer range (${String(value)})`);
575
+ }
576
+ if (!(usage.inputTokens >= usage.cacheReadTokens + usage.cacheWriteTokens)) out.push(`inputTokens (${String(usage.inputTokens)}) < cacheReadTokens + cacheWriteTokens (${String(usage.cacheReadTokens)} + ${String(usage.cacheWriteTokens)})`);
577
+ return out;
578
+ }
579
+ /**
580
+ * One count, repaired in the conservative direction: non-numbers and
581
+ * non-finite values floor to zero (no evidence, no charge and no
582
+ * credit), negatives floor to zero (a negative count can only CREDIT
583
+ * the budget, which hostile telemetry must never do), and fractions
584
+ * round UP so a repaired charge is never an undercharge.
585
+ */
586
+ function sanitizeTokenCount(value) {
587
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 0;
588
+ return Math.min(Math.ceil(value), Number.MAX_SAFE_INTEGER);
589
+ }
590
+ /**
591
+ * One field read per property, returning a detached plain copy. Both
592
+ * accounting boundaries validate and consume THIS snapshot, never the
593
+ * adapter-owned object, so a hostile accessor cannot answer the
594
+ * validator with valid counts and the accumulator with garbage.
595
+ */
596
+ function snapshotUsage(usage) {
597
+ const out = {
598
+ inputTokens: usage.inputTokens,
599
+ outputTokens: usage.outputTokens,
600
+ cacheReadTokens: usage.cacheReadTokens,
601
+ cacheWriteTokens: usage.cacheWriteTokens
602
+ };
603
+ const reasoning = usage.reasoningTokens;
604
+ if (reasoning !== void 0) out.reasoningTokens = reasoning;
605
+ return out;
606
+ }
607
+ /**
608
+ * The per-field repair for DELTAS (mid-stream usage reports and other
609
+ * partial increments): each count is repaired like `sanitizeTokenCount`,
610
+ * but the whole-usage subset rule is deliberately NOT applied, because a
611
+ * delta legitimately carries cache counts without restating the full
612
+ * input in the same event; clamping those to the subset rule would
613
+ * silently drop a paid cache debit. Always returns a fresh object and
614
+ * is the identity on valid deltas.
615
+ */
616
+ function sanitizeUsageDelta(delta) {
617
+ const snapshot = snapshotUsage(delta);
618
+ const out = {
619
+ inputTokens: sanitizeTokenCount(snapshot.inputTokens),
620
+ outputTokens: sanitizeTokenCount(snapshot.outputTokens),
621
+ cacheReadTokens: sanitizeTokenCount(snapshot.cacheReadTokens),
622
+ cacheWriteTokens: sanitizeTokenCount(snapshot.cacheWriteTokens)
623
+ };
624
+ if (snapshot.reasoningTokens !== void 0) out.reasoningTokens = sanitizeTokenCount(snapshot.reasoningTokens);
625
+ return out;
626
+ }
627
+ /**
628
+ * Conservative repair for accounting. Pairs with `usageViolations`: the
629
+ * violation fails the call loud, and the sanitized numbers are the only
630
+ * ones the journal, the cost report, and the budget may see. After the
631
+ * per-field repair the cache subsets clamp into the input with reads
632
+ * keeping priority, mirroring the adapter-level subset clamp. Valid
633
+ * usage passes through structurally unchanged.
634
+ */
635
+ function sanitizeUsage(usage) {
636
+ const inputTokens = sanitizeTokenCount(usage.inputTokens);
637
+ const cacheReadTokens = Math.min(sanitizeTokenCount(usage.cacheReadTokens), inputTokens);
638
+ const cacheWriteTokens = Math.min(sanitizeTokenCount(usage.cacheWriteTokens), inputTokens - cacheReadTokens);
639
+ const out = {
640
+ inputTokens,
641
+ outputTokens: sanitizeTokenCount(usage.outputTokens),
642
+ cacheReadTokens,
643
+ cacheWriteTokens
644
+ };
645
+ if (usage.reasoningTokens !== void 0) out.reasoningTokens = sanitizeTokenCount(usage.reasoningTokens);
646
+ return out;
647
+ }
648
+ //#endregion
649
+ //#region src/l0/terminal.ts
650
+ /**
651
+ * Terminal output hygiene (v1.21.0 review P2-1): the rendering-boundary
652
+ * counterpart to maskSecrets. Any UNTRUSTED string a terminal renderer
653
+ * interpolates into a line, provider error messages, tool names, model
654
+ * ids, workflow and label metadata, and log text, can carry control
655
+ * characters and escape sequences that rewrite the screen, recolor to
656
+ * hide forged text, set the window title, drive the clipboard on some
657
+ * terminals, or inject fresh newlines that forge CI log structure.
658
+ * Secret masking does not address this: it targets credential SHAPES,
659
+ * not control bytes.
660
+ *
661
+ * Every line-oriented renderer passes each dynamic value through
662
+ * `sanitizeTerminalText` BEFORE interpolation, and adds its own SGR
663
+ * styling only afterward, so the renderer's own colors survive while
664
+ * nothing an adapter or tool emitted can reach the terminal as a control
665
+ * sequence. The guarantee after sanitization: the result contains no
666
+ * byte in `U+0000..U+001F`, `U+007F..U+009F` (C0, DEL, and the C1 range
667
+ * including every 8-bit sequence introducer), and no ESC-initiated
668
+ * CSI/OSC/DCS/SOS/PM/APC sequence.
669
+ *
670
+ * The patterns are built from escaped codepoints (never literal control
671
+ * bytes in the source) and applied in order: string sequences first (so
672
+ * their printable payload leaves with them), then CSI, then any
673
+ * remaining control run collapses to one space. An unterminated or
674
+ * partial sequence loses its introducer in the final pass, which
675
+ * de-fangs it.
676
+ */
677
+ const ESC_STRING_SEQUENCE = /* @__PURE__ */ new RegExp("(?:\\u001B[\\]PX^_]|[\\u009D\\u0090\\u0098\\u009E\\u009F])[\\s\\S]*?(?:\\u0007|\\u001B\\\\|\\u009C)", "gu");
678
+ const ESC_CSI_SEQUENCE = /* @__PURE__ */ new RegExp("(?:\\u001B\\[|\\u009B)[\\u0030-\\u003F]*[\\u0020-\\u002F]*[\\u0040-\\u007E]", "gu");
679
+ const CONTROL_RUN = /* @__PURE__ */ new RegExp("[\\u0000-\\u001F\\u007F-\\u009F]+", "gu");
680
+ /**
681
+ * Neutralizes terminal control sequences and control characters in one
682
+ * untrusted string, collapsing each remaining control run to a single
683
+ * space so a value can never inject a newline, an escape sequence, or a
684
+ * hidden byte into a rendered line. Visible text is preserved.
685
+ */
686
+ function sanitizeTerminalText(text) {
687
+ return text.replace(ESC_STRING_SEQUENCE, "").replace(ESC_CSI_SEQUENCE, "").replace(CONTROL_RUN, " ");
688
+ }
689
+ //#endregion
550
690
  //#region src/vendor/json-schema/deep-compare-strict.ts
551
691
  function deepCompareStrict(a, b) {
552
692
  const typeofa = typeof a;
@@ -1772,7 +1912,10 @@ function entryUsageSlices(entry) {
1772
1912
  * The single pricing fold over one terminal entry, shared by the kernel
1773
1913
  * ledger and the CostReport fold so a run's total and its per-model
1774
1914
  * breakdown can never disagree. Each slice is priced at ITS OWN model's
1775
- * rate.
1915
+ * rate. A price function returning NaN or a negative amount (a broken
1916
+ * user-supplied rate) is treated exactly like a missing row: the slice
1917
+ * folds as unpriced instead of poisoning or crediting the totals
1918
+ * (v1.20.0 review follow-up).
1776
1919
  */
1777
1920
  function priceEntryUsage(entry, priceUsd) {
1778
1921
  const result = {
@@ -1782,7 +1925,7 @@ function priceEntryUsage(entry, priceUsd) {
1782
1925
  };
1783
1926
  for (const slice of entryUsageSlices(entry)) {
1784
1927
  const usd = priceUsd(slice.servedBy, slice.usage);
1785
- if (usd === void 0) {
1928
+ if (usd === void 0 || !Number.isFinite(usd) || usd < 0) {
1786
1929
  result.unpriced.push(slice);
1787
1930
  continue;
1788
1931
  }
@@ -5535,6 +5678,7 @@ var Replayer = class {
5535
5678
  if (patch.servedBy !== void 0) entry.servedBy = patch.servedBy;
5536
5679
  if (patch.usageByModel !== void 0) entry.usageByModel = patch.usageByModel;
5537
5680
  if (patch.costAttribution !== void 0) entry.costAttribution = patch.costAttribution;
5681
+ if (patch.usageSemantics !== void 0) entry.usageSemantics = patch.usageSemantics;
5538
5682
  if (patch.transcriptRef !== void 0) entry.transcriptRef = patch.transcriptRef;
5539
5683
  if (patch.checkpointRef !== void 0) entry.checkpointRef = patch.checkpointRef;
5540
5684
  if (patch.artifacts !== void 0) entry.artifacts = toJournalValue(patch.artifacts, "terminal artifacts");
@@ -7759,8 +7903,17 @@ function addUsage(total, turn) {
7759
7903
  * The Usage invariant is verified at the adapter boundary: inputTokens is
7760
7904
  * the FULL prompt including cache reads and writes.
7761
7905
  */
7762
- function assertUsageInvariant(usage, adapterId) {
7763
- if (usage.inputTokens < usage.cacheReadTokens + usage.cacheWriteTokens) throw new Error(`adapter '${adapterId}' violated the Usage invariant: inputTokens (${usage.inputTokens}) < cacheReadTokens + cacheWriteTokens (${usage.cacheReadTokens} + ${usage.cacheWriteTokens})`);
7906
+ /**
7907
+ * The full canonical invariant at the adapter boundary (v1.20.0 review
7908
+ * P1-1): every count finite, integral, and nonnegative, and the cache
7909
+ * subsets inside the input. One violation message covers every adapter,
7910
+ * injected clients and mocks included; the financial invariant never
7911
+ * depends on the good faith of an external transport.
7912
+ */
7913
+ function usageInvariantViolation(usage, adapterId) {
7914
+ const violations = usageViolations(usage);
7915
+ if (violations.length === 0) return;
7916
+ return `adapter '${adapterId}' violated the Usage invariant: ${violations.join("; ")}`;
7764
7917
  }
7765
7918
  async function streamTurn(adapter, req, options) {
7766
7919
  const idle = new AbortController();
@@ -7774,6 +7927,7 @@ async function streamTurn(adapter, req, options) {
7774
7927
  const pendingArgs = /* @__PURE__ */ new Map();
7775
7928
  let usage = ZERO_USAGE$1;
7776
7929
  let reported = ZERO_USAGE$1;
7930
+ let usageViolation;
7777
7931
  let sawFinish = false;
7778
7932
  let finish;
7779
7933
  let providerMetadata;
@@ -7817,22 +7971,46 @@ async function streamTurn(adapter, req, options) {
7817
7971
  break;
7818
7972
  }
7819
7973
  case "usage": {
7974
+ if (sawFinish) {
7975
+ usageViolation ??= "a usage event arrived after the finish event";
7976
+ break;
7977
+ }
7978
+ const cleaned = {};
7979
+ for (const field of [
7980
+ "inputTokens",
7981
+ "outputTokens",
7982
+ "cacheReadTokens",
7983
+ "cacheWriteTokens",
7984
+ "reasoningTokens"
7985
+ ]) {
7986
+ const value = event.usage[field];
7987
+ if (value === void 0) continue;
7988
+ if (Number.isInteger(value) && value >= 0) cleaned[field] = value;
7989
+ else {
7990
+ usageViolation ??= `mid-stream usage event carried invalid ${field} (${String(value)})`;
7991
+ cleaned[field] = sanitizeTokenCount(value);
7992
+ }
7993
+ }
7820
7994
  usage = {
7821
7995
  ...usage,
7822
- ...event.usage
7996
+ ...cleaned
7823
7997
  };
7824
7998
  const delta = {
7825
- inputTokens: event.usage.inputTokens ?? 0,
7826
- outputTokens: event.usage.outputTokens ?? 0,
7827
- cacheReadTokens: event.usage.cacheReadTokens ?? 0,
7828
- cacheWriteTokens: event.usage.cacheWriteTokens ?? 0
7999
+ inputTokens: cleaned.inputTokens ?? 0,
8000
+ outputTokens: cleaned.outputTokens ?? 0,
8001
+ cacheReadTokens: cleaned.cacheReadTokens ?? 0,
8002
+ cacheWriteTokens: cleaned.cacheWriteTokens ?? 0
7829
8003
  };
7830
- if (event.usage.reasoningTokens !== void 0) delta.reasoningTokens = event.usage.reasoningTokens;
8004
+ if (cleaned.reasoningTokens !== void 0) delta.reasoningTokens = cleaned.reasoningTokens;
7831
8005
  reported = addUsage(reported, delta);
7832
8006
  options.onUsage?.(delta);
7833
8007
  break;
7834
8008
  }
7835
8009
  case "finish":
8010
+ if (sawFinish) {
8011
+ usageViolation ??= "a second finish event arrived on one stream";
8012
+ break;
8013
+ }
7836
8014
  sawFinish = true;
7837
8015
  finish = event.finish;
7838
8016
  usage = event.usage;
@@ -7864,6 +8042,7 @@ async function streamTurn(adapter, req, options) {
7864
8042
  aborted
7865
8043
  };
7866
8044
  if (finish !== void 0) outcome.finish = finish;
8045
+ if (usageViolation !== void 0) outcome.usageViolation = usageViolation;
7867
8046
  return outcome;
7868
8047
  }
7869
8048
  const outcome = {
@@ -7873,6 +8052,7 @@ async function streamTurn(adapter, req, options) {
7873
8052
  usageApprox: !sawFinish
7874
8053
  };
7875
8054
  if (finish !== void 0) outcome.finish = finish;
8055
+ if (usageViolation !== void 0) outcome.usageViolation = usageViolation;
7876
8056
  if (providerMetadata !== void 0) outcome.providerMetadata = providerMetadata;
7877
8057
  if (wireError !== void 0) outcome.wireError = wireError;
7878
8058
  return outcome;
@@ -8095,17 +8275,18 @@ async function runAgent(options) {
8095
8275
  messages.length = 0;
8096
8276
  messages.push(...restored.messages);
8097
8277
  turns = restored.turns;
8098
- totalUsage = restored.usage;
8278
+ totalUsage = usageViolations(restored.usage).length === 0 ? restored.usage : sanitizeUsage(restored.usage);
8099
8279
  toolCallsUsed = restored.toolCallsUsed;
8100
8280
  schemaAttempts = restored.schemaAttempts;
8101
8281
  compactionPoints.push(...restored.compaction);
8102
8282
  const restoredSlices = restored.usageByModel ?? [{
8103
8283
  servedBy,
8104
- usage: restored.usage
8284
+ usage: totalUsage
8105
8285
  }];
8106
8286
  for (const slice of restoredSlices) {
8107
- addPhaseUsage(slice.role ?? primaryRole, slice.servedBy, slice.usage);
8108
- options.budget?.onUsage(slice.usage, slice.servedBy);
8287
+ const sliceUsage = usageViolations(slice.usage).length === 0 ? slice.usage : sanitizeUsage(slice.usage);
8288
+ addPhaseUsage(slice.role ?? primaryRole, slice.servedBy, sliceUsage);
8289
+ options.budget?.onUsage(sliceUsage, slice.servedBy);
8109
8290
  }
8110
8291
  }
8111
8292
  const usageSlices = () => [...usageByPhaseModel.values()].map(({ role, servedBy: sliceServedBy, usage }) => ({
@@ -8122,7 +8303,10 @@ async function runAgent(options) {
8122
8303
  const price = options.priceUsd;
8123
8304
  if (price === void 0) return 0;
8124
8305
  let usd = 0;
8125
- for (const slice of usageByPhaseModel.values()) usd += price(slice.servedBy, slice.usage) ?? 0;
8306
+ for (const slice of usageByPhaseModel.values()) {
8307
+ const sliceUsd = price(slice.servedBy, slice.usage) ?? 0;
8308
+ if (Number.isFinite(sliceUsd) && sliceUsd > 0) usd += sliceUsd;
8309
+ }
8126
8310
  return usd;
8127
8311
  };
8128
8312
  const saveBoundary = async (pending) => {
@@ -8358,21 +8542,29 @@ async function runAgent(options) {
8358
8542
  role: primaryRole
8359
8543
  });
8360
8544
  let invariantViolation;
8361
- const recordUsage = (usage, reported, adapterId, ref, role) => {
8362
- try {
8363
- assertUsageInvariant(usage, adapterId);
8364
- } catch (thrown) {
8365
- invariantViolation = thrown instanceof Error ? thrown.message : String(thrown);
8366
- }
8367
- totalUsage = addUsage(totalUsage, usage);
8368
- addPhaseUsage(role, ref, usage);
8545
+ const recordUsage = (usage, reported, adapterId, ref, role, streamViolation) => {
8546
+ if (streamViolation !== void 0) invariantViolation ??= `adapter '${adapterId}' violated the Usage invariant: ${streamViolation}`;
8547
+ const snapshot = snapshotUsage(usage);
8548
+ const violation = usageInvariantViolation(snapshot, adapterId);
8549
+ if (violation !== void 0) invariantViolation ??= violation;
8550
+ const safe = violation === void 0 ? snapshot : sanitizeUsage(snapshot);
8551
+ totalUsage = addUsage(totalUsage, safe);
8552
+ addPhaseUsage(role, ref, safe);
8369
8553
  const remainder = {
8370
- inputTokens: Math.max(0, usage.inputTokens - reported.inputTokens),
8371
- outputTokens: Math.max(0, usage.outputTokens - reported.outputTokens),
8372
- cacheReadTokens: Math.max(0, usage.cacheReadTokens - reported.cacheReadTokens),
8373
- cacheWriteTokens: Math.max(0, usage.cacheWriteTokens - reported.cacheWriteTokens)
8554
+ inputTokens: Math.max(0, safe.inputTokens - reported.inputTokens),
8555
+ outputTokens: Math.max(0, safe.outputTokens - reported.outputTokens),
8556
+ cacheReadTokens: Math.max(0, safe.cacheReadTokens - reported.cacheReadTokens),
8557
+ cacheWriteTokens: Math.max(0, safe.cacheWriteTokens - reported.cacheWriteTokens)
8374
8558
  };
8375
- const reasoningRemainder = Math.max(0, (usage.reasoningTokens ?? 0) - (reported.reasoningTokens ?? 0));
8559
+ for (const field of [
8560
+ "inputTokens",
8561
+ "outputTokens",
8562
+ "cacheReadTokens",
8563
+ "cacheWriteTokens"
8564
+ ]) if (reported[field] > safe[field]) invariantViolation ??= `adapter '${adapterId}' violated the Usage invariant: mid-stream ${field} (${String(reported[field])}) exceeded the finish total (${String(safe[field])})`;
8565
+ const overReportedReads = Math.max(0, reported.cacheReadTokens - safe.cacheReadTokens);
8566
+ if (overReportedReads > 0) remainder.inputTokens = Math.min(Number.MAX_SAFE_INTEGER, remainder.inputTokens + overReportedReads);
8567
+ const reasoningRemainder = Math.max(0, (safe.reasoningTokens ?? 0) - (reported.reasoningTokens ?? 0));
8376
8568
  if (reasoningRemainder > 0) remainder.reasoningTokens = reasoningRemainder;
8377
8569
  if (remainder.inputTokens > 0 || remainder.outputTokens > 0 || remainder.cacheReadTokens > 0 || remainder.cacheWriteTokens > 0) options.budget?.onUsage(remainder, ref);
8378
8570
  };
@@ -8387,7 +8579,7 @@ async function runAgent(options) {
8387
8579
  inner: for (;;) {
8388
8580
  const dispatch = () => streamTurn(target.adapter, site.requestFor(target), site.streamOptionsFor(target));
8389
8581
  const outcome = await (options.providerSlot === void 0 ? dispatch() : options.providerSlot(target.adapter.id, dispatch));
8390
- recordUsage(outcome.usage, outcome.reported, target.adapter.id, target.resolved.ref, site.role);
8582
+ recordUsage(outcome.usage, outcome.reported, target.adapter.id, target.resolved.ref, site.role, outcome.usageViolation);
8391
8583
  tries += 1;
8392
8584
  const retryClass = outcome.aborted === "idle" ? "transport" : outcome.wireError === void 0 ? void 0 : retryClassOf(outcome.wireError);
8393
8585
  if (retryClass === void 0) return {
@@ -9109,6 +9301,15 @@ const ZERO_USAGE = {
9109
9301
  cacheWriteTokens: 0
9110
9302
  };
9111
9303
  /**
9304
+ * A ceiling that is NaN or negative silently disarms every layer (each
9305
+ * comparison against it is false), which is indistinguishable from
9306
+ * uncapped. That must be a loud configuration error, never a silent
9307
+ * fail-open (v1.20.0 review P1-1).
9308
+ */
9309
+ function requireValidCeiling(ceilingUsd, what) {
9310
+ if (!Number.isFinite(ceilingUsd) || ceilingUsd < 0) throw new ConfigError(`${what} must be a finite nonnegative USD amount, got ${String(ceilingUsd)}`);
9311
+ }
9312
+ /**
9112
9313
  * The admission reserve for a spawn: opts.estCost, else profile.estCost,
9113
9314
  * else price(countTokens(input) + one turn's worth of output), else the
9114
9315
  * engine flat default. The output term is caps.maxOutputTokens clamped to
@@ -9151,8 +9352,13 @@ var RunBudget = class {
9151
9352
  exhaustedInternal = false;
9152
9353
  /** Models already warned about; the warning fires once per model per run. */
9153
9354
  unpricedWarned = /* @__PURE__ */ new Set();
9355
+ /** Models whose price function already returned an invalid USD once. */
9356
+ invalidPriceWarned = /* @__PURE__ */ new Set();
9154
9357
  constructor(options) {
9155
- if (options.ceilingUsd !== void 0) this.ceilingUsd = options.ceilingUsd;
9358
+ if (options.ceilingUsd !== void 0) {
9359
+ requireValidCeiling(options.ceilingUsd, "budget ceiling");
9360
+ this.ceilingUsd = options.ceilingUsd;
9361
+ }
9156
9362
  this.lifetimeSpawnCap = options.lifetimeSpawnCap ?? 500;
9157
9363
  if (options.events !== void 0) this.events = options.events;
9158
9364
  if (options.priceUsd !== void 0) this.priceUsd = options.priceUsd;
@@ -9167,8 +9373,9 @@ var RunBudget = class {
9167
9373
  if (options.ceilingUsd !== void 0) root.ceilingUsd = options.ceilingUsd;
9168
9374
  this.accounts.set("run", root);
9169
9375
  if (options.seed !== void 0) {
9376
+ if (!Number.isFinite(options.seed.usd) || options.seed.usd < 0) throw new ConfigError(`budget resume seed is not a finite nonnegative USD amount: ${String(options.seed.usd)}`);
9170
9377
  root.spentUsd = options.seed.usd;
9171
- this.usageInternal = { ...options.seed.usage };
9378
+ this.usageInternal = sanitizeUsage(options.seed.usage);
9172
9379
  this.agentsSpawnedInternal = options.seed.agentsSpawned;
9173
9380
  }
9174
9381
  }
@@ -9208,7 +9415,10 @@ var RunBudget = class {
9208
9415
  parentScope,
9209
9416
  controller: new AbortController()
9210
9417
  };
9211
- if (options.ceilingUsd !== void 0) account.ceilingUsd = options.ceilingUsd;
9418
+ if (options.ceilingUsd !== void 0) {
9419
+ requireValidCeiling(options.ceilingUsd, `ceiling of budget account '${scope}'`);
9420
+ account.ceilingUsd = options.ceilingUsd;
9421
+ }
9212
9422
  if (options.kind !== void 0) account.kind = options.kind;
9213
9423
  this.accounts.set(scope, account);
9214
9424
  }
@@ -9436,15 +9646,16 @@ var RunBudget = class {
9436
9646
  * in-flight agent; providers bill severed streams).
9437
9647
  */
9438
9648
  onUsage(usage, servedBy, accountScope = "run") {
9649
+ const safe = sanitizeUsageDelta(usage);
9439
9650
  this.usageInternal = {
9440
- inputTokens: this.usageInternal.inputTokens + usage.inputTokens,
9441
- outputTokens: this.usageInternal.outputTokens + usage.outputTokens,
9442
- cacheReadTokens: this.usageInternal.cacheReadTokens + usage.cacheReadTokens,
9443
- cacheWriteTokens: this.usageInternal.cacheWriteTokens + usage.cacheWriteTokens
9651
+ inputTokens: this.usageInternal.inputTokens + safe.inputTokens,
9652
+ outputTokens: this.usageInternal.outputTokens + safe.outputTokens,
9653
+ cacheReadTokens: this.usageInternal.cacheReadTokens + safe.cacheReadTokens,
9654
+ cacheWriteTokens: this.usageInternal.cacheWriteTokens + safe.cacheWriteTokens
9444
9655
  };
9445
- const reasoning = (this.usageInternal.reasoningTokens ?? 0) + (usage.reasoningTokens ?? 0);
9656
+ const reasoning = (this.usageInternal.reasoningTokens ?? 0) + (safe.reasoningTokens ?? 0);
9446
9657
  if (reasoning > 0) this.usageInternal.reasoningTokens = reasoning;
9447
- const priced = this.priceUsd?.(servedBy, usage);
9658
+ const priced = this.priceUsd?.(servedBy, safe);
9448
9659
  if (priced === void 0 && this.ceilingUsd !== void 0 && !this.unpricedWarned.has(servedBy)) {
9449
9660
  this.unpricedWarned.add(servedBy);
9450
9661
  this.events?.emit({
@@ -9453,7 +9664,18 @@ var RunBudget = class {
9453
9664
  msg: `no price row for '${servedBy}': its usage does not debit the budget, so the ${this.ceilingUsd} USD run ceiling does NOT bound this model. Add it to createEngine({ pricing }) to cap it; its usage is reported under CostReport.unpriced`
9454
9665
  });
9455
9666
  }
9456
- const usd = priced ?? 0;
9667
+ let usd = priced ?? 0;
9668
+ if (!Number.isFinite(usd) || usd < 0) {
9669
+ if (!this.invalidPriceWarned.has(servedBy)) {
9670
+ this.invalidPriceWarned.add(servedBy);
9671
+ this.events?.emit({
9672
+ type: "log",
9673
+ level: "error",
9674
+ msg: `price function returned ${String(usd)} USD for '${servedBy}'; charging 0 for this slice so the budget stays finite and monotone. Fix the pricing row: this usage is NOT debited and any ceiling under-counts it`
9675
+ });
9676
+ }
9677
+ usd = 0;
9678
+ }
9457
9679
  for (const account of this.chainOf(accountScope)) {
9458
9680
  account.spentUsd += usd;
9459
9681
  if (account.ceilingUsd !== void 0 && account.spentUsd >= account.ceilingUsd && !account.controller.signal.aborted) {
@@ -11016,10 +11238,18 @@ function createCtx(internals, rootWorkflow) {
11016
11238
  result.escalation = report;
11017
11239
  delete result.escalationRequest;
11018
11240
  }
11241
+ const adapterOfRef = (ref) => ref.slice(0, ref.indexOf(":"));
11242
+ const declaredSemantics = [];
11243
+ for (const ref of [result.servedBy, ...(result.usageByModel ?? []).map((slice) => slice.servedBy)]) {
11244
+ const declared = internals.adapters.get(adapterOfRef(ref))?.usageSemantics;
11245
+ if (declared !== void 0 && !declaredSemantics.includes(declared)) declaredSemantics.push(declared);
11246
+ }
11247
+ const servedSemantics = declaredSemantics.length === 0 ? void 0 : declaredSemantics.join("+");
11019
11248
  const terminalPatch = {
11020
11249
  status: result.status === "skipped" ? "error" : result.status,
11021
11250
  usage: result.usage,
11022
11251
  servedBy: result.servedBy,
11252
+ ...servedSemantics === void 0 ? {} : { usageSemantics: servedSemantics },
11023
11253
  ...result.usageByModel === void 0 ? {} : { usageByModel: result.usageByModel },
11024
11254
  costAttribution: {
11025
11255
  ...state.phase === void 0 ? {} : { phase: state.phase },
@@ -11084,7 +11314,7 @@ function createCtx(internals, rootWorkflow) {
11084
11314
  }];
11085
11315
  for (const slice of attributionSlices) {
11086
11316
  const priced = internals.priceUsd(slice.servedBy, slice.usage);
11087
- if (priced === void 0) {
11317
+ if (priced === void 0 || !Number.isFinite(priced) || priced < 0) {
11088
11318
  internals.cost.unpriced.push({
11089
11319
  model: slice.servedBy,
11090
11320
  usage: slice.usage
@@ -12526,6 +12756,7 @@ var EventBus = class {
12526
12756
  listeners = /* @__PURE__ */ new Set();
12527
12757
  seq = 0;
12528
12758
  ended = false;
12759
+ listenerErrorReported = false;
12529
12760
  constructor(options) {
12530
12761
  this.runId = options.runId;
12531
12762
  this.spans = options.spans;
@@ -12544,10 +12775,40 @@ var EventBus = class {
12544
12775
  ...replayed === true ? { replayed: true } : {},
12545
12776
  ...safeBody
12546
12777
  };
12547
- for (const listener of this.listeners) listener(event);
12778
+ for (const listener of this.listeners) try {
12779
+ listener(event);
12780
+ } catch (thrown) {
12781
+ this.reportListenerError(thrown, spanId);
12782
+ }
12548
12783
  for (const subscriber of this.subscribers) subscriber.push(event);
12549
12784
  return event;
12550
12785
  }
12786
+ /**
12787
+ * A throwing on() listener is isolated (its work is best-effort
12788
+ * telemetry), and the failure surfaces ONCE as a warn log on this bus
12789
+ * rather than propagating into the run. The guard is set before the
12790
+ * warn is delivered, so a listener that also throws on the warn cannot
12791
+ * re-arm the report or recurse.
12792
+ */
12793
+ reportListenerError(thrown, spanId) {
12794
+ if (this.listenerErrorReported) return;
12795
+ this.listenerErrorReported = true;
12796
+ const parentSpanId = this.spans.parentOf(spanId);
12797
+ const warn = {
12798
+ runId: this.runId,
12799
+ seq: this.seq++,
12800
+ ts: new Date(this.now()).toISOString(),
12801
+ spanId,
12802
+ ...parentSpanId === void 0 ? {} : { parentSpanId },
12803
+ type: "log",
12804
+ level: "warn",
12805
+ msg: "an event listener threw and was isolated so the run is unaffected: " + (thrown instanceof Error ? thrown.message : String(thrown))
12806
+ };
12807
+ for (const listener of this.listeners) try {
12808
+ listener(warn);
12809
+ } catch {}
12810
+ for (const subscriber of this.subscribers) subscriber.push(warn);
12811
+ }
12551
12812
  on(type, cb) {
12552
12813
  const listener = (event) => {
12553
12814
  if (event.type === type) cb(event);
@@ -13057,6 +13318,10 @@ function createEngine(options) {
13057
13318
  }
13058
13319
  const priorEntries = (await journal.load(runId)).map((entry) => normalizeEntry(entry));
13059
13320
  scanJournalCompatibility(runId, priorEntries, buildDeriverRegistry(options.extraDerivers));
13321
+ if (priorEntries.some((entry) => entry.usageSemantics === void 0 && (entry.servedBy?.startsWith("openai:") === true && (entry.usage?.cacheWriteTokens ?? 0) > 0 || (entry.usageByModel?.some((slice) => slice.servedBy.startsWith("openai:") && slice.usage.cacheWriteTokens > 0) ?? false)))) process.emitWarning(`resume: run '${runId}' contains OpenAI cache-write usage recorded without a usage-semantics stamp. Entries written by rulvar v1.19.0 double-counted cache writes into inputTokens, so their recorded cost and budget debits are OVERSTATED; unstamped entries from v1.20.0 are correct. Resuming keeps the recorded debits. Audit procedure: https://docs.rulvar.com/guide/providers#openai-legacy-cache-journals`, {
13322
+ code: "RULVAR_LEGACY_CACHE_SEMANTICS",
13323
+ type: "RulvarWarning"
13324
+ });
13060
13325
  return run(bound, resumeOptions?.args, void 0, {
13061
13326
  runId,
13062
13327
  priorEntries,
@@ -13417,4 +13682,4 @@ function createSandboxBridge(ctx, options) {
13417
13682
  };
13418
13683
  }
13419
13684
  //#endregion
13420
- 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_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, 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, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FileModelKnowledgeStore, FileTranscriptStore, 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_DEPTH_CEILING, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, PlanInvariantError, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, 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, atCompactionThreshold, 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, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, 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, readTerminationInit, registryKeyRing, remeasureQueue, replayDisposition, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, scanJournalCompatibility, schemaHash, schemaHashOfSpec, selectStructuredOutputTier, shouldCompact, spawnDepthOf, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, validateEditorialCommit, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateSchemaSpec, validateTerminationLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
13685
+ 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_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, 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, EventBus, ExternalRegistry, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FileModelKnowledgeStore, FileTranscriptStore, 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_DEPTH_CEILING, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, ParallelSiteCounter, PlanInvariantError, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, ReplayPlanHashMismatch, Replayer, ResolutionArbiter, ResolutionFold, RulvarError, RunBudget, 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, atCompactionThreshold, 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, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, foldTermination, formatRePrompt, formatScopePath, hashWorkflowBody, hashWorkflowSource, identityJcs, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lexShellCommand, liftRetainedParts, lineageWeightOf, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, mergeUsageLimits, 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, readTerminationInit, registryKeyRing, remeasureQueue, replayDisposition, 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, validateSchemaSpec, validateTerminationLimits, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/core",
3
- "version": "1.20.0",
3
+ "version": "1.22.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",