@rulvar/core 1.170.0 → 1.172.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 +61 -12
  2. package/dist/index.js +437 -416
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -764,7 +764,13 @@ interface ProviderCallRecord {
764
764
  /** The invocation phase that paid the call. */
765
765
  role: InvocationRole;
766
766
  servedBy: ModelRef;
767
- /** 1-based try number on the serving target; retries increment it. */
767
+ /**
768
+ * 1-based DISPATCHED try number on the serving target; transport
769
+ * retries increment it, a pre-wire quota denial never does (RV1601),
770
+ * so the recorded attempts of one (role, target) series are always
771
+ * dense from 1 and an attempt=2 row proves a prior dispatched try
772
+ * with its own record.
773
+ */
768
774
  attempt: number;
769
775
  /**
770
776
  * 'ok' = a terminal finish; 'error' = a wire failure after dispatch
@@ -4067,6 +4073,19 @@ interface EngineQuotaConfig {
4067
4073
  */
4068
4074
  reserveContinuations?: boolean;
4069
4075
  /**
4076
+ * The denial retry budget (RV1601): how many pre-wire quota denials
4077
+ * one dispatch tolerates per serving target before the denial takes
4078
+ * the exhaustion path (failover when the chain names a rate-limit
4079
+ * trigger, else the typed rate-limit terminal). Denials stopped
4080
+ * consuming `RetryPolicy.attempts` in RV1601: that budget counts
4081
+ * DISPATCHED tries only, so a busy window can no longer exhaust the
4082
+ * transport budget before the wire ever opens (the eighteenth
4083
+ * comparison benchmark measured 21 denials riding the transport
4084
+ * namespaces). Each denied turn still waits the limiter's own
4085
+ * `retryAfterMs` first. Default {@link DEFAULT_MAX_QUOTA_DENIALS}.
4086
+ */
4087
+ maxDenials?: number;
4088
+ /**
4070
4089
  * The drift telemetry opt-in (the v1.71 experiment review, P0.5
4071
4090
  * resized): the SAME rule declaration `preflightEstimate` takes as
4072
4091
  * `quotaRules`, mirrored here so the engine can hold it against what
@@ -4086,6 +4105,14 @@ interface EngineQuotaConfig {
4086
4105
  */
4087
4106
  declaredRules?: readonly QuotaRule[];
4088
4107
  }
4108
+ /**
4109
+ * The default {@link EngineQuotaConfig.maxDenials}: generous next to the
4110
+ * transport default of 3 tries because a denial is a WAIT, not a
4111
+ * failure signal, yet finite because nothing else bounds the pre-wire
4112
+ * loop (the per-agent timeout is checked between turns, not inside a
4113
+ * dispatch).
4114
+ */
4115
+ declare const DEFAULT_MAX_QUOTA_DENIALS = 8;
4089
4116
  /** The resolved engine-side quota runtime threaded into every run. */
4090
4117
  interface EngineQuotaRuntime {
4091
4118
  limiter: QuotaLimiter;
@@ -4093,6 +4120,8 @@ interface EngineQuotaRuntime {
4093
4120
  onLimiterError: "deny" | "allow";
4094
4121
  /** Pre-wire continuation admission (RV1013); see {@link EngineQuotaConfig}. */
4095
4122
  reserveContinuations: boolean;
4123
+ /** The per-target denial retry budget (RV1601); see {@link EngineQuotaConfig}. */
4124
+ maxDenials: number;
4096
4125
  /** The declared rule mirror for drift telemetry; see {@link EngineQuotaConfig}. */
4097
4126
  declaredRules?: readonly QuotaRule[];
4098
4127
  }
@@ -4856,9 +4885,14 @@ interface AgentResult<T> {
4856
4885
  abortClass?: AbortClass;
4857
4886
  /**
4858
4887
  * Transport retries across the span's phase activations, present only
4859
- * when greater than zero. Live telemetry only: the ctx layer surfaces
4860
- * it as `agent:end` retryCount; it is never journaled, so a replayed
4861
- * result omits it (absent means "zero or unknown").
4888
+ * when greater than zero. Counts retries of DISPATCHED attempts only
4889
+ * (RV1601): a pre-wire quota denial never increments it, so this
4890
+ * number can be read against the provider ledger without correction
4891
+ * (the eighteenth comparison benchmark exported 21 denials under this
4892
+ * name over an invoice with zero provider error rows). Live telemetry
4893
+ * only: the ctx layer surfaces it as `agent:end` retryCount; it is
4894
+ * never journaled, so a replayed result omits it (absent means "zero
4895
+ * or unknown").
4862
4896
  */
4863
4897
  transportRetries?: number;
4864
4898
  /**
@@ -5166,12 +5200,14 @@ interface RunAgentOptions<S extends SchemaSpec = JsonSchema> {
5166
5200
  * failover takeovers alike, in every phase). A denial becomes a
5167
5201
  * synthetic rate-limit-class WireError the retry and failover
5168
5202
  * engine treats exactly like a provider 429, except no wire call
5169
- * was paid: retryAfterMs drives the interruptible backoff, attempts
5170
- * stay bounded by RetryPolicy, and exhaustion fails over (the
5171
- * takeover reserves under its own model). Granted reservations are
5172
- * reconciled with the attempt's actual usage after the outcome
5173
- * settles. Live-only by construction: replayed calls never reach
5174
- * this seam, and nothing here is journaled.
5203
+ * was paid: retryAfterMs drives the interruptible backoff, denied
5204
+ * turns stay bounded by their OWN `maxDenials` budget (RV1601;
5205
+ * RetryPolicy.attempts counts dispatched tries only), and
5206
+ * exhaustion of either budget fails over (the takeover reserves
5207
+ * under its own model). Granted reservations are reconciled with
5208
+ * the attempt's actual usage after the outcome settles. Live-only
5209
+ * by construction: replayed calls never reach this seam, and
5210
+ * nothing here is journaled.
5175
5211
  */
5176
5212
  quota?: {
5177
5213
  reserve: (request: QuotaReservationRequest) => Promise<QuotaDecision>;
@@ -5179,7 +5215,8 @@ interface RunAgentOptions<S extends SchemaSpec = JsonSchema> {
5179
5215
  requests?: number;
5180
5216
  }) => Promise<void>; /** Limiter infrastructure failure policy; a denial is unaffected. */
5181
5217
  onLimiterError: "deny" | "allow"; /** Pre-wire continuation admission (RV1013); default post-hoc. */
5182
- reserveContinuations?: boolean; /** Cancels an unused admission; absent = window age-out. */
5218
+ reserveContinuations?: boolean; /** The per-target denial retry budget (RV1601); default 8. */
5219
+ maxDenials?: number; /** Cancels an unused admission; absent = window age-out. */
5183
5220
  release?: (reservationId: string) => Promise<void>;
5184
5221
  };
5185
5222
  /** The resolved toolset; absent = no tools declared. */
@@ -10818,6 +10855,18 @@ interface McpConfig {
10818
10855
  */
10819
10856
  maxTools?: number;
10820
10857
  /**
10858
+ * Cap on tools/list PAGES fetched in one sweep (RV1602): a server
10859
+ * paginating past it refuses typed, fail closed like maxTools (a
10860
+ * truncated import would silently admit a subset of the declared
10861
+ * surface). Bounds the sweep's WIRE CALL count where maxTools bounds
10862
+ * its volume: unique cursors over empty pages grow neither the tool
10863
+ * count nor any timeout (each page answers inside listMs), so only a
10864
+ * page bound stops them. Positive integer; absent = unbounded.
10865
+ * Independent of the unconditional cursor-echo cycle guard, which
10866
+ * needs no configuration.
10867
+ */
10868
+ maxPages?: number;
10869
+ /**
10821
10870
  * Per ADMITTED tool (allow/deny filter first): the UTF-8 byte length
10822
10871
  * of the serialized inputSchema plus outputSchema when present
10823
10872
  * (RV1515). An oversized tool refuses the resolution typed, naming
@@ -12675,4 +12724,4 @@ interface SandboxBridge {
12675
12724
  declare const SANDBOX_AGENT_OPT_KEYS: readonly string[];
12676
12725
  declare function createSandboxBridge(ctx: Ctx<never>, options: SandboxBridgeOptions): SandboxBridge;
12677
12726
  //#endregion
12678
- export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, AcceptanceChildSummary, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentProfileTemplateOptions, AgentResult, AgentResultMeta, AgentStatus, type AppliedPricingRow, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditCategory, AuditRecord, 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, ChildExecutionFacts, ChildIdentityInput, ChildResultPage, CitationTarget, type ClaimClass, ClaimContradictionFinding, type ClaimOp, ClaimPair, ClaimPairOptions, ClaimPairsFold, ClaimPoolReading, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, Contradiction, ContradictionClaim, ContradictionOptions, ContradictionSource, type CoreEvents, CostAttribution, CostAttributionFacts, type CostBasis, CostReport, CreateEngineOptions, type CriticalPath, Ctx, DEFAULT_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, 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, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DataKeyProvider, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DedupedClaims, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DocumentedRates, 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, EngineQuotaConfig, EngineQuotaRuntime, EntryBillingFold, EntryBillingUnit, EntryKind, EntryRef, EntryStatus, EnvelopeEncryption, EnvelopeEncryptionOptions, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, EvidenceContract, type EvidenceRef, type ExecKeyDerivation, type ExecutorRegistry, type ExplorationSummary, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FencedCodeMode, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, type FinalizationWindowBudget, FinishContract, FinishContractCitations, FinishContractGoldenReject, FinishContractManifest, FinishInfo, FinishSelfTestFailure, FinishSelfTestFixtures, FinishSelfTestReport, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, IncrementalSynthesisResult, InvalidResolutionError, InvocationRole, type InvocationTable, InvoiceCardinality, InvoiceExport, InvoicePricingProvenance, InvoiceReconciliation, InvoiceRow, type IsolatedExecContext, type IsolatedExecRequest, type IsolatedExecutorTag, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JOURNAL_ENVELOPE_MARKER, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, type JournalPricingSnapshot, JournalSerializationContext, 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, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, MemoryQuotaLimiter, 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, OrchestrateClaimConsistency, OrchestrateClaimConsistencyMeta, OrchestrateContradictions, OrchestrateContradictionsMeta, OrchestrateOptions, OrchestrateSynthesis, OrchestrateSynthesisSkipReason, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, PersistedTerminalRefusal, PersistedTerminalResult, type PhaseRow, PhaseTarget, type PinnedPricingSegment, PipelineCollected, PipelineOpts, PlanInvariantError, type PostFanInBreakdown, PreflightAdmissionRow, PreflightFinding, PreflightInput, PreflightOrchestratorSpec, PreflightReport, PreflightSpawnReport, PreflightSpawnSpec, PreflightToolCeiling, PriceTable, PricedComponent, PricedComponents, PricedUsage, type Pricing, type PricingTier, ProgressReport, type ProviderAdapter, ProviderCallRecord, QUOTA_WINDOW_MS, QualityFloors, QuotaCounters, type QuotaDecision, type QuotaEstimate, type QuotaLimiter, type QuotaReservationRequest, QuotaRule, QuotaWindowSnapshot, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, RateLimitObservation, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, RepeatedClaim, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, RepositoryResearchToolset, RepositoryResearchToolsetOptions, ResearchAgentProfileOptions, ResearchAgentProfileResult, ResearchEvidenceEntry, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, RunExport, 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, SecretMasker, SectionMatchMode, Semaphore, SerializationHook, Settled, SettlementError, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, type StreamHooks, StructuredOutputTier, SupersededError, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, type TerminalEnvelope, TerminalOutcomeFacts, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, type ToolBudgetSummary, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, type ToolExecutorProvider, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, ToolsetAttestation, 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, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, citationTargetsValidator, citedValueValidator, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reduceAuditTrail, reduceCriticalPath, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolContractHash, toolsetHash, ttlState, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
12727
+ export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, AcceptanceChildSummary, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentProfileTemplateOptions, AgentResult, AgentResultMeta, AgentStatus, type AppliedPricingRow, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditCategory, AuditRecord, 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, ChildExecutionFacts, ChildIdentityInput, ChildResultPage, CitationTarget, type ClaimClass, ClaimContradictionFinding, type ClaimOp, ClaimPair, ClaimPairOptions, ClaimPairsFold, ClaimPoolReading, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, Contradiction, ContradictionClaim, ContradictionOptions, ContradictionSource, type CoreEvents, CostAttribution, CostAttributionFacts, type CostBasis, CostReport, CreateEngineOptions, type CriticalPath, Ctx, DEFAULT_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, DEFAULT_MAX_QUOTA_DENIALS, 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, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DataKeyProvider, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DedupedClaims, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DocumentedRates, 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, EngineQuotaConfig, EngineQuotaRuntime, EntryBillingFold, EntryBillingUnit, EntryKind, EntryRef, EntryStatus, EnvelopeEncryption, EnvelopeEncryptionOptions, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, EvidenceContract, type EvidenceRef, type ExecKeyDerivation, type ExecutorRegistry, type ExplorationSummary, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FencedCodeMode, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, type FinalizationWindowBudget, FinishContract, FinishContractCitations, FinishContractGoldenReject, FinishContractManifest, FinishInfo, FinishSelfTestFailure, FinishSelfTestFixtures, FinishSelfTestReport, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, IncrementalSynthesisResult, InvalidResolutionError, InvocationRole, type InvocationTable, InvoiceCardinality, InvoiceExport, InvoicePricingProvenance, InvoiceReconciliation, InvoiceRow, type IsolatedExecContext, type IsolatedExecRequest, type IsolatedExecutorTag, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JOURNAL_ENVELOPE_MARKER, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, type JournalPricingSnapshot, JournalSerializationContext, 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, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, MemoryQuotaLimiter, 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, OrchestrateClaimConsistency, OrchestrateClaimConsistencyMeta, OrchestrateContradictions, OrchestrateContradictionsMeta, OrchestrateOptions, OrchestrateSynthesis, OrchestrateSynthesisSkipReason, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, PersistedTerminalRefusal, PersistedTerminalResult, type PhaseRow, PhaseTarget, type PinnedPricingSegment, PipelineCollected, PipelineOpts, PlanInvariantError, type PostFanInBreakdown, PreflightAdmissionRow, PreflightFinding, PreflightInput, PreflightOrchestratorSpec, PreflightReport, PreflightSpawnReport, PreflightSpawnSpec, PreflightToolCeiling, PriceTable, PricedComponent, PricedComponents, PricedUsage, type Pricing, type PricingTier, ProgressReport, type ProviderAdapter, ProviderCallRecord, QUOTA_WINDOW_MS, QualityFloors, QuotaCounters, type QuotaDecision, type QuotaEstimate, type QuotaLimiter, type QuotaReservationRequest, QuotaRule, QuotaWindowSnapshot, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, RateLimitObservation, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, RepeatedClaim, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, RepositoryResearchToolset, RepositoryResearchToolsetOptions, ResearchAgentProfileOptions, ResearchAgentProfileResult, ResearchEvidenceEntry, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, RunExport, 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, SecretMasker, SectionMatchMode, Semaphore, SerializationHook, Settled, SettlementError, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, type StreamHooks, StructuredOutputTier, SupersededError, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, type TerminalEnvelope, TerminalOutcomeFacts, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, type ToolBudgetSummary, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, type ToolExecutorProvider, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, ToolsetAttestation, 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, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, citationTargetsValidator, citedValueValidator, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reduceAuditTrail, reduceCriticalPath, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolContractHash, toolsetHash, ttlState, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/dist/index.js CHANGED
@@ -3885,6 +3885,7 @@ function validateBounds(cfg) {
3885
3885
  if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) throw new ConfigError(`mcp: '${key}' must be a positive integer, got ${String(value)}`);
3886
3886
  };
3887
3887
  positiveInt("maxTools");
3888
+ positiveInt("maxPages");
3888
3889
  positiveInt("maxSchemaBytes");
3889
3890
  for (const key of [
3890
3891
  "connectMs",
@@ -4034,12 +4035,16 @@ function mcp(cfg) {
4034
4035
  const listAll = async (client) => {
4035
4036
  const tools = [];
4036
4037
  let cursor;
4038
+ let pages = 0;
4037
4039
  const listOptions = cfg.timeouts?.listMs === void 0 ? void 0 : { timeout: cfg.timeouts.listMs };
4038
4040
  do {
4039
4041
  const page = await client.listTools(cursor === void 0 ? {} : { cursor }, listOptions);
4042
+ pages += 1;
4040
4043
  tools.push(...page.tools);
4041
4044
  if (cfg.maxTools !== void 0 && tools.length > cfg.maxTools) throw new ConfigError(`mcp: tools/list of '${sourceIdOf(cfg)}' returned at least ${tools.length} wire tools, over the declared maxTools ${cfg.maxTools}; raise the cap or trim the server`);
4045
+ if (page.nextCursor !== void 0 && page.nextCursor !== "" && page.nextCursor === cursor) throw new ConfigError(`mcp: tools/list of '${sourceIdOf(cfg)}' returned the cursor it was queried with ('${page.nextCursor}') on page ${pages}: the pagination makes no progress`);
4042
4046
  cursor = page.nextCursor;
4047
+ if (cfg.maxPages !== void 0 && pages >= cfg.maxPages && cursor !== void 0 && cursor !== "") throw new ConfigError(`mcp: tools/list of '${sourceIdOf(cfg)}' still reports another page after ${pages} page(s), over the declared maxPages ${cfg.maxPages}; raise the cap or trim the server`);
4043
4048
  } while (cursor !== void 0 && cursor !== "");
4044
4049
  return tools;
4045
4050
  };
@@ -9009,123 +9014,446 @@ function compareRates(seed, page) {
9009
9014
  return findings;
9010
9015
  }
9011
9016
  //#endregion
9012
- //#region src/model/failover.ts
9013
- /** Normalizes the author-facing ModelChoice.fallbacks list. */
9014
- function normalizeFallbacks(refs) {
9015
- return (refs ?? []).map((model) => ({ model }));
9016
- }
9017
+ //#region src/model/quota.ts
9017
9018
  /**
9018
- * Maps a retry class to its failover trigger once retries exhaust.
9019
- * Overloaded (529) is transport-class for failover purposes; a
9020
- * non-retryable error never fails over.
9019
+ * Quota rules and the in-process reference QuotaLimiter (RV-215).
9020
+ * The rule model is shared by every reference implementation
9021
+ * (memoryQuotaLimiter here, SqliteQuotaLimiter in
9022
+ * @rulvar/store-sqlite): fixed one-minute windows aligned to the
9023
+ * epoch, admission at reservation time, reconciliation to actual
9024
+ * usage inside the same window. The hard guarantee is on
9025
+ * `requestsPerMinute` (every wire attempt is exactly one request);
9026
+ * `tokensPerMinute` admits on the heuristic estimate and settles to
9027
+ * actual usage, so token windows are approximate at admission and
9028
+ * exact at settlement.
9029
+ *
9030
+ * Docs: https://docs.rulvar.com/guide/model-routing
9021
9031
  */
9022
- function failoverTriggerOf(retryClass) {
9023
- if (retryClass === void 0) return;
9024
- return retryClass === "rate-limit" ? "rate-limit" : "transport";
9032
+ /**
9033
+ * Captured at module load, before the InProcessRunner's
9034
+ * nondeterminism guard can patch the global: the limiter's clock is
9035
+ * engine infrastructure on the live-only dispatch path and must never
9036
+ * be blamed on workflow code.
9037
+ */
9038
+ const nativeNow = Date.now;
9039
+ /** The fixed accounting window every PerMinute cap counts over. */
9040
+ const QUOTA_WINDOW_MS = 6e4;
9041
+ /**
9042
+ * Validates a quota rule set as a typed ConfigError before any
9043
+ * limiter can admit under it: a non-array or empty set, a rule
9044
+ * without a cap, a malformed dimension, or a malformed cap all fail
9045
+ * loud at construction. Shared by every reference implementation.
9046
+ */
9047
+ function validateQuotaRules(rules, site = "quota rules") {
9048
+ const raw = rules;
9049
+ if (!Array.isArray(raw)) throw new ConfigError(`${site} must be an array of QuotaRule objects`);
9050
+ if (raw.length === 0) throw new ConfigError(`${site} must contain at least one rule`);
9051
+ raw.forEach((entry, index) => {
9052
+ const at = `${site}[${String(index)}]`;
9053
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) throw new ConfigError(`${at} must be a QuotaRule object`);
9054
+ const rule = entry;
9055
+ for (const dimension of [
9056
+ "provider",
9057
+ "model",
9058
+ "tenant"
9059
+ ]) {
9060
+ const value = rule[dimension];
9061
+ if (value !== void 0 && (typeof value !== "string" || value === "")) throw new ConfigError(`${at}.${dimension} must be a nonempty string when given`);
9062
+ }
9063
+ if (rule.requestsPerMinute === void 0 && rule.tokensPerMinute === void 0) throw new ConfigError(`${at} must set requestsPerMinute or tokensPerMinute (or both)`);
9064
+ for (const cap of ["requestsPerMinute", "tokensPerMinute"]) if (rule[cap] !== void 0) requirePositiveInteger$2(rule[cap], `${at}.${cap}`);
9065
+ });
9025
9066
  }
9026
9067
  /**
9027
- * The next target index past `from` that serves `trigger`, or undefined
9028
- * when the chain is exhausted. Index 0 is the primary; the chain never
9029
- * moves backwards (sticky failover).
9068
+ * The canonical content key of one rule (RV608, promoted from the
9069
+ * store limiters): a fixed-field-order JSON of the rule, identical
9070
+ * across processes and hosts for identical rules. It is the bucket key
9071
+ * of both store references, the input of
9072
+ * `quotaRulesFingerprint`, and the CANONICAL ORDER every reference
9073
+ * limiter folds denials in, so equal rule sets produce byte-identical
9074
+ * refusal objects regardless of array permutation.
9030
9075
  */
9031
- function nextFailover(targets, trigger, from) {
9032
- for (let index = from + 1; index < targets.length; index += 1) {
9033
- const on = targets[index]?.on;
9034
- if (on === void 0 || on.includes(trigger)) return index;
9035
- }
9076
+ function quotaRuleKey(rule) {
9077
+ return JSON.stringify({
9078
+ provider: rule.provider ?? null,
9079
+ model: rule.model ?? null,
9080
+ tenant: rule.tenant ?? null,
9081
+ requestsPerMinute: rule.requestsPerMinute ?? null,
9082
+ tokensPerMinute: rule.tokensPerMinute ?? null
9083
+ });
9036
9084
  }
9037
9085
  /**
9038
- * Classifies a terminal agent outcome for the degenerate fallback:
9039
- * schema-mismatch errors are
9040
- * 'schema-exhausted'; any other error is 'error'; limit terminals (the
9041
- * no-progress abort included) are 'limit'; cancelled, escalated, and
9042
- * skipped never trigger.
9086
+ * Validates a rule set and returns the immutable snapshot every
9087
+ * reference limiter admits under (RV608): a fresh array of fresh
9088
+ * objects carrying ONLY the known rule fields, each frozen, the array
9089
+ * frozen. The caller's array and objects stay untouched and unshared,
9090
+ * so ordinary JavaScript after the constructor (a pushed rule, a
9091
+ * reassigned cap) can no longer change a decision, a bucket key, or a
9092
+ * recorded fingerprint.
9093
+ *
9094
+ * A set containing two rules with the same canonical content key is
9095
+ * refused typed (RV704): the memory reference buckets by rule INDEX
9096
+ * (each copy counts independently, the full cap admits) while the
9097
+ * store references bucket by rule KEY (one shared bucket is debited
9098
+ * once per matching copy, half the cap admits), so the same duplicated
9099
+ * configuration admitted differently per storage. Refusing it at the
9100
+ * shared construction chokepoint is what keeps equal configurations
9101
+ * equal on every storage.
9043
9102
  */
9044
- function fallbackTriggerOf(outcome) {
9045
- if (outcome.status === "error") return outcome.error?.kind === "schema-mismatch" ? "schema-exhausted" : "error";
9046
- if (outcome.status === "limit") return "limit";
9103
+ function snapshotQuotaRules(rules, site = "quota rules") {
9104
+ validateQuotaRules(rules, site);
9105
+ const firstIndexByKey = /* @__PURE__ */ new Map();
9106
+ rules.forEach((rule, index) => {
9107
+ const key = quotaRuleKey(rule);
9108
+ const first = firstIndexByKey.get(key);
9109
+ if (first !== void 0) throw new ConfigError(`${site}[${String(index)}] duplicates ${site}[${String(first)}] (rule key ${key}): identical rules occupy independent buckets in memory but share one key-debited bucket on keyed storage, so one configuration would admit differently per store; delete the duplicate`);
9110
+ firstIndexByKey.set(key, index);
9111
+ });
9112
+ return Object.freeze(rules.map((rule) => Object.freeze({
9113
+ ...rule.provider === void 0 ? {} : { provider: rule.provider },
9114
+ ...rule.model === void 0 ? {} : { model: rule.model },
9115
+ ...rule.tenant === void 0 ? {} : { tenant: rule.tenant },
9116
+ ...rule.requestsPerMinute === void 0 ? {} : { requestsPerMinute: rule.requestsPerMinute },
9117
+ ...rule.tokensPerMinute === void 0 ? {} : { tokensPerMinute: rule.tokensPerMinute }
9118
+ })));
9047
9119
  }
9048
- //#endregion
9049
- //#region src/model/projector.ts
9050
- /** The provider family of an adapter: `provider` when set, else `id`. */
9051
- function providerOf(adapter) {
9052
- return adapter.provider ?? adapter.id;
9120
+ /** True when every dimension the rule pins matches the request. */
9121
+ function quotaRuleMatches(rule, request) {
9122
+ return (rule.provider === void 0 || rule.provider === request.provider) && (rule.model === void 0 || rule.model === request.model) && (rule.tenant === void 0 || rule.tenant === request.tenant);
9123
+ }
9124
+ /** The tokens a reservation is admitted under: input estimate plus the output cap. */
9125
+ function quotaEstimateTokens(request) {
9126
+ return request.estimate.inputTokens + (request.estimate.maxOutputTokens ?? 0);
9127
+ }
9128
+ /** The tokens a settled attempt actually consumed. */
9129
+ function quotaActualTokens(usage) {
9130
+ return usage.inputTokens + usage.outputTokens;
9053
9131
  }
9054
9132
  /**
9055
- * Projects the canonical history into the target provider's view:
9056
- * provider-raw parts of a DIFFERENT provider are omitted; everything
9057
- * else (text, images, tool calls, tool results, compaction content)
9058
- * passes through untouched. Messages whose parts all belong to another
9059
- * provider vanish entirely rather than ride as empty messages.
9133
+ * The request-count settlement delta of one reservation (RV905): the
9134
+ * reservation admitted ONE wire request, and `actual.requests` names
9135
+ * how many the attempt actually made (an adapter absorbing
9136
+ * provider-side continuations dispatches several inside one reserved
9137
+ * call). Non-integer, non-positive, or absent actuals settle as the
9138
+ * single reserved request (delta 0); a settlement only ever ADDS, the
9139
+ * calls already happened. Shared by every reference limiter so the
9140
+ * three implementations cannot disagree about the arithmetic.
9060
9141
  */
9061
- function projectHistory(messages, targetProvider) {
9062
- const projected = [];
9063
- for (const msg of messages) {
9064
- const parts = msg.parts.filter((part) => part.type !== "provider-raw" || part.provider === targetProvider);
9065
- if (parts.length === 0 && msg.parts.length > 0) continue;
9066
- projected.push(parts.length === msg.parts.length ? msg : {
9067
- ...msg,
9068
- parts
9069
- });
9070
- }
9071
- return projected;
9142
+ function quotaActualRequestsDelta(actual) {
9143
+ const requests = actual?.requests;
9144
+ return typeof requests === "number" && Number.isInteger(requests) && requests > 1 ? requests - 1 : 0;
9072
9145
  }
9073
9146
  /**
9074
- * Lifts the adapter-shipped retention payload of one finished turn into
9075
- * provider-raw parts (the retention transport). Reads
9076
- * providerMetadata[<adapter id>].retainedParts and tags each block with
9077
- * the adapter's provider family. Returns [] when the adapter shipped
9078
- * nothing.
9147
+ * One rule's admission verdict against its current-window counters,
9148
+ * the pure decision both reference implementations share. A denial
9149
+ * carries the window remainder as retryAfterMs, except when the
9150
+ * estimate alone can never fit the token cap: that denial says
9151
+ * retryAfterMs 0 (retry immediately), so the caller's bounded
9152
+ * attempts exhaust without waiting and failover gets its chance.
9079
9153
  */
9080
- function liftRetainedParts(providerMetadata, adapter) {
9081
- const namespace = providerMetadata?.[adapter.id];
9082
- if (typeof namespace !== "object" || namespace === null) return [];
9083
- const retained = namespace.retainedParts;
9084
- if (!Array.isArray(retained)) return [];
9085
- const blocks = retained;
9086
- const provider = providerOf(adapter);
9087
- return blocks.map((block) => ({
9088
- type: "provider-raw",
9089
- provider,
9090
- block
9091
- }));
9154
+ function quotaRuleAdmission(rule, counters, estimate, msUntilWindowEnd) {
9155
+ if (rule.requestsPerMinute !== void 0 && counters.requests + estimate.requests > rule.requestsPerMinute) return {
9156
+ admit: false,
9157
+ retryAfterMs: msUntilWindowEnd,
9158
+ reason: `requestsPerMinute ${String(rule.requestsPerMinute)} exhausted`
9159
+ };
9160
+ if (rule.tokensPerMinute !== void 0) {
9161
+ if (estimate.tokens > rule.tokensPerMinute) return {
9162
+ admit: false,
9163
+ retryAfterMs: 0,
9164
+ reason: `the estimate of ${String(estimate.tokens)} tokens can never fit tokensPerMinute ${String(rule.tokensPerMinute)}`
9165
+ };
9166
+ if (counters.tokens + estimate.tokens > rule.tokensPerMinute) return {
9167
+ admit: false,
9168
+ retryAfterMs: msUntilWindowEnd,
9169
+ reason: `tokensPerMinute ${String(rule.tokensPerMinute)} exhausted`
9170
+ };
9171
+ }
9172
+ return { admit: true };
9092
9173
  }
9093
- //#endregion
9094
- //#region src/model/retry.ts
9095
9174
  /**
9096
- * Transport RetryPolicy (M4-T05): retries live UNDER the journal. A
9097
- * retried-then-successful call is exactly one journal entry with one
9098
- * usage total, transport retries never count as lineage attempts
9099
- * (DEF-3), the provider-supplied retryAfterMs replaces the computed
9100
- * delay, and task-class failures never retry by construction (a
9101
- * non-retryable WireError has no retry class).
9102
- *
9103
- * Full contract: https://docs.rulvar.com/guide/model-routing; the
9104
- * Appendix A defaults were committed at the M4 entry gate.
9175
+ * Folds one more failing rule into the decision the caller returns:
9176
+ * the wait is the LONGEST failing horizon (every matching rule must
9177
+ * admit), and the FIRST failing rule names the denial.
9105
9178
  */
9179
+ function mergeQuotaDenial(current, next) {
9180
+ if (current === void 0) return {
9181
+ retryAfterMs: next.retryAfterMs,
9182
+ reason: next.reason
9183
+ };
9184
+ return next.retryAfterMs > current.retryAfterMs ? {
9185
+ retryAfterMs: next.retryAfterMs,
9186
+ reason: current.reason
9187
+ } : current;
9188
+ }
9106
9189
  /**
9107
- * Captured at module load, before the InProcessRunner's nondeterminism
9108
- * guard can patch the global: the engine's own jitter is journal
9109
- * invisible and must never be blamed on workflow code.
9190
+ * The in-process reference QuotaLimiter: fixed epoch-aligned
9191
+ * one-minute windows over the shared rule model. Coordinates every
9192
+ * engine that shares THIS instance inside one process; processes
9193
+ * coordinate through a shared-storage implementation of the same SPI
9194
+ * (SqliteQuotaLimiter in @rulvar/store-sqlite) instead.
9110
9195
  */
9111
- const nativeRandom = Math.random;
9112
- /** Appendix A committed defaults (M4 entry gate, PR #26). */
9113
- const DEFAULT_RETRY_POLICY = {
9114
- attempts: 3,
9115
- backoff: {
9116
- initialMs: 500,
9117
- factor: 2,
9118
- maxMs: 8e3,
9119
- jitter: true
9120
- },
9121
- retryOn: [
9122
- "transport",
9123
- "rate-limit",
9124
- "overloaded"
9125
- ]
9126
- };
9127
- /**
9128
- * Classifies a WireError for the retry engine. Task-class failures are
9196
+ function memoryQuotaLimiter(rules, options = {}) {
9197
+ const frozen = snapshotQuotaRules(rules, "memoryQuotaLimiter rules");
9198
+ const ordered = frozen.map((rule, index) => ({
9199
+ rule,
9200
+ index,
9201
+ key: quotaRuleKey(rule)
9202
+ })).sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
9203
+ const now = options.now ?? (() => nativeNow());
9204
+ const buckets = /* @__PURE__ */ new Map();
9205
+ const reservations = /* @__PURE__ */ new Map();
9206
+ let nextReservation = 0;
9207
+ const windowStartAt = (at) => at - at % QUOTA_WINDOW_MS;
9208
+ const bucketFor = (ruleIndex, windowStart) => {
9209
+ let bucket = buckets.get(ruleIndex);
9210
+ if (bucket === void 0 || bucket.windowStart !== windowStart) {
9211
+ bucket = {
9212
+ windowStart,
9213
+ requests: 0,
9214
+ tokens: 0
9215
+ };
9216
+ buckets.set(ruleIndex, bucket);
9217
+ }
9218
+ return bucket;
9219
+ };
9220
+ const prune = (windowStart) => {
9221
+ for (const [id, reservation] of reservations) if (reservation.windowStart < windowStart) reservations.delete(id);
9222
+ };
9223
+ return {
9224
+ reserve(request) {
9225
+ const at = now();
9226
+ const windowStart = windowStartAt(at);
9227
+ prune(windowStart);
9228
+ const estimateTokens = quotaEstimateTokens(request);
9229
+ const msUntilWindowEnd = windowStart + QUOTA_WINDOW_MS - at;
9230
+ const matched = [];
9231
+ let denial;
9232
+ for (const { rule, index } of ordered) {
9233
+ if (!quotaRuleMatches(rule, request)) continue;
9234
+ matched.push(index);
9235
+ const verdict = quotaRuleAdmission(rule, bucketFor(index, windowStart), {
9236
+ requests: request.estimate.requests,
9237
+ tokens: estimateTokens
9238
+ }, msUntilWindowEnd);
9239
+ if (!verdict.admit) denial = mergeQuotaDenial(denial, verdict);
9240
+ }
9241
+ if (denial !== void 0) return Promise.resolve({
9242
+ granted: false,
9243
+ ...denial
9244
+ });
9245
+ for (const index of matched) {
9246
+ const bucket = bucketFor(index, windowStart);
9247
+ bucket.requests += request.estimate.requests;
9248
+ bucket.tokens += estimateTokens;
9249
+ }
9250
+ nextReservation += 1;
9251
+ const reservationId = `mq-${String(nextReservation)}`;
9252
+ reservations.set(reservationId, {
9253
+ windowStart,
9254
+ estimateTokens,
9255
+ requests: request.estimate.requests,
9256
+ ruleIndexes: matched
9257
+ });
9258
+ return Promise.resolve({
9259
+ granted: true,
9260
+ reservationId
9261
+ });
9262
+ },
9263
+ reconcile(reservationId, usage, actual) {
9264
+ const reservation = reservations.get(reservationId);
9265
+ if (reservation === void 0) return Promise.resolve();
9266
+ reservations.delete(reservationId);
9267
+ const windowStart = windowStartAt(now());
9268
+ if (reservation.windowStart !== windowStart) return Promise.resolve();
9269
+ const delta = quotaActualTokens(usage) - reservation.estimateTokens;
9270
+ const requestsDelta = quotaActualRequestsDelta(actual);
9271
+ for (const index of reservation.ruleIndexes) {
9272
+ const bucket = buckets.get(index);
9273
+ if (bucket !== void 0 && bucket.windowStart === windowStart) {
9274
+ bucket.tokens = Math.max(0, bucket.tokens + delta);
9275
+ bucket.requests += requestsDelta;
9276
+ }
9277
+ }
9278
+ return Promise.resolve();
9279
+ },
9280
+ release(reservationId) {
9281
+ const reservation = reservations.get(reservationId);
9282
+ if (reservation === void 0) return Promise.resolve();
9283
+ reservations.delete(reservationId);
9284
+ const windowStart = windowStartAt(now());
9285
+ if (reservation.windowStart !== windowStart) return Promise.resolve();
9286
+ for (const index of reservation.ruleIndexes) {
9287
+ const bucket = buckets.get(index);
9288
+ if (bucket !== void 0 && bucket.windowStart === windowStart) {
9289
+ bucket.requests = Math.max(0, bucket.requests - reservation.requests);
9290
+ bucket.tokens = Math.max(0, bucket.tokens - reservation.estimateTokens);
9291
+ }
9292
+ }
9293
+ return Promise.resolve();
9294
+ },
9295
+ snapshot() {
9296
+ const windowStart = windowStartAt(now());
9297
+ return frozen.map((rule, index) => {
9298
+ const bucket = buckets.get(index);
9299
+ const current = bucket !== void 0 && bucket.windowStart === windowStart;
9300
+ return {
9301
+ rule,
9302
+ windowStart,
9303
+ requests: current ? bucket.requests : 0,
9304
+ tokens: current ? bucket.tokens : 0
9305
+ };
9306
+ });
9307
+ }
9308
+ };
9309
+ }
9310
+ /**
9311
+ * The default {@link EngineQuotaConfig.maxDenials}: generous next to the
9312
+ * transport default of 3 tries because a denial is a WAIT, not a
9313
+ * failure signal, yet finite because nothing else bounds the pre-wire
9314
+ * loop (the per-agent timeout is checked between turns, not inside a
9315
+ * dispatch).
9316
+ */
9317
+ const DEFAULT_MAX_QUOTA_DENIALS = 8;
9318
+ /**
9319
+ * Validates createEngine's quota config as a typed ConfigError before
9320
+ * any run could dispatch under a malformed limiter (the intake
9321
+ * discipline every engine option follows).
9322
+ */
9323
+ function validateEngineQuotaConfig(config, site = "createEngine quota") {
9324
+ if (config === void 0) return;
9325
+ const raw = config;
9326
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) throw new ConfigError(`${site} must be an object with a limiter`);
9327
+ const candidate = raw;
9328
+ const limiter = candidate.limiter;
9329
+ if (typeof limiter !== "object" || limiter === null || typeof limiter.reserve !== "function" || typeof limiter.reconcile !== "function") throw new ConfigError(`${site}.limiter must implement QuotaLimiter (reserve and reconcile functions)`);
9330
+ if (candidate.tenant !== void 0 && (typeof candidate.tenant !== "string" || candidate.tenant === "")) throw new ConfigError(`${site}.tenant must be a nonempty string when given`);
9331
+ if (candidate.onLimiterError !== void 0 && candidate.onLimiterError !== "deny" && candidate.onLimiterError !== "allow") throw new ConfigError(`${site}.onLimiterError must be 'deny' or 'allow' when given`);
9332
+ const reserveContinuations = candidate.reserveContinuations;
9333
+ if (reserveContinuations !== void 0 && typeof reserveContinuations !== "boolean") throw new ConfigError(`${site}.reserveContinuations must be a boolean when given`);
9334
+ const maxDenials = candidate.maxDenials;
9335
+ if (maxDenials !== void 0 && (typeof maxDenials !== "number" || !Number.isInteger(maxDenials) || maxDenials < 1)) throw new ConfigError(`${site}.maxDenials must be a positive integer when given`);
9336
+ const declared = candidate.declaredRules;
9337
+ if (declared !== void 0) validateQuotaRules(declared, `${site}.declaredRules`);
9338
+ }
9339
+ //#endregion
9340
+ //#region src/model/failover.ts
9341
+ /** Normalizes the author-facing ModelChoice.fallbacks list. */
9342
+ function normalizeFallbacks(refs) {
9343
+ return (refs ?? []).map((model) => ({ model }));
9344
+ }
9345
+ /**
9346
+ * Maps a retry class to its failover trigger once retries exhaust.
9347
+ * Overloaded (529) is transport-class for failover purposes; a
9348
+ * non-retryable error never fails over.
9349
+ */
9350
+ function failoverTriggerOf(retryClass) {
9351
+ if (retryClass === void 0) return;
9352
+ return retryClass === "rate-limit" ? "rate-limit" : "transport";
9353
+ }
9354
+ /**
9355
+ * The next target index past `from` that serves `trigger`, or undefined
9356
+ * when the chain is exhausted. Index 0 is the primary; the chain never
9357
+ * moves backwards (sticky failover).
9358
+ */
9359
+ function nextFailover(targets, trigger, from) {
9360
+ for (let index = from + 1; index < targets.length; index += 1) {
9361
+ const on = targets[index]?.on;
9362
+ if (on === void 0 || on.includes(trigger)) return index;
9363
+ }
9364
+ }
9365
+ /**
9366
+ * Classifies a terminal agent outcome for the degenerate fallback:
9367
+ * schema-mismatch errors are
9368
+ * 'schema-exhausted'; any other error is 'error'; limit terminals (the
9369
+ * no-progress abort included) are 'limit'; cancelled, escalated, and
9370
+ * skipped never trigger.
9371
+ */
9372
+ function fallbackTriggerOf(outcome) {
9373
+ if (outcome.status === "error") return outcome.error?.kind === "schema-mismatch" ? "schema-exhausted" : "error";
9374
+ if (outcome.status === "limit") return "limit";
9375
+ }
9376
+ //#endregion
9377
+ //#region src/model/projector.ts
9378
+ /** The provider family of an adapter: `provider` when set, else `id`. */
9379
+ function providerOf(adapter) {
9380
+ return adapter.provider ?? adapter.id;
9381
+ }
9382
+ /**
9383
+ * Projects the canonical history into the target provider's view:
9384
+ * provider-raw parts of a DIFFERENT provider are omitted; everything
9385
+ * else (text, images, tool calls, tool results, compaction content)
9386
+ * passes through untouched. Messages whose parts all belong to another
9387
+ * provider vanish entirely rather than ride as empty messages.
9388
+ */
9389
+ function projectHistory(messages, targetProvider) {
9390
+ const projected = [];
9391
+ for (const msg of messages) {
9392
+ const parts = msg.parts.filter((part) => part.type !== "provider-raw" || part.provider === targetProvider);
9393
+ if (parts.length === 0 && msg.parts.length > 0) continue;
9394
+ projected.push(parts.length === msg.parts.length ? msg : {
9395
+ ...msg,
9396
+ parts
9397
+ });
9398
+ }
9399
+ return projected;
9400
+ }
9401
+ /**
9402
+ * Lifts the adapter-shipped retention payload of one finished turn into
9403
+ * provider-raw parts (the retention transport). Reads
9404
+ * providerMetadata[<adapter id>].retainedParts and tags each block with
9405
+ * the adapter's provider family. Returns [] when the adapter shipped
9406
+ * nothing.
9407
+ */
9408
+ function liftRetainedParts(providerMetadata, adapter) {
9409
+ const namespace = providerMetadata?.[adapter.id];
9410
+ if (typeof namespace !== "object" || namespace === null) return [];
9411
+ const retained = namespace.retainedParts;
9412
+ if (!Array.isArray(retained)) return [];
9413
+ const blocks = retained;
9414
+ const provider = providerOf(adapter);
9415
+ return blocks.map((block) => ({
9416
+ type: "provider-raw",
9417
+ provider,
9418
+ block
9419
+ }));
9420
+ }
9421
+ //#endregion
9422
+ //#region src/model/retry.ts
9423
+ /**
9424
+ * Transport RetryPolicy (M4-T05): retries live UNDER the journal. A
9425
+ * retried-then-successful call is exactly one journal entry with one
9426
+ * usage total, transport retries never count as lineage attempts
9427
+ * (DEF-3), the provider-supplied retryAfterMs replaces the computed
9428
+ * delay, and task-class failures never retry by construction (a
9429
+ * non-retryable WireError has no retry class).
9430
+ *
9431
+ * Full contract: https://docs.rulvar.com/guide/model-routing; the
9432
+ * Appendix A defaults were committed at the M4 entry gate.
9433
+ */
9434
+ /**
9435
+ * Captured at module load, before the InProcessRunner's nondeterminism
9436
+ * guard can patch the global: the engine's own jitter is journal
9437
+ * invisible and must never be blamed on workflow code.
9438
+ */
9439
+ const nativeRandom = Math.random;
9440
+ /** Appendix A committed defaults (M4 entry gate, PR #26). */
9441
+ const DEFAULT_RETRY_POLICY = {
9442
+ attempts: 3,
9443
+ backoff: {
9444
+ initialMs: 500,
9445
+ factor: 2,
9446
+ maxMs: 8e3,
9447
+ jitter: true
9448
+ },
9449
+ retryOn: [
9450
+ "transport",
9451
+ "rate-limit",
9452
+ "overloaded"
9453
+ ]
9454
+ };
9455
+ /**
9456
+ * Classifies a WireError for the retry engine. Task-class failures are
9129
9457
  * never retryable by construction: adapters mark them retryable: false
9130
9458
  * and this returns undefined. The kind travels in WireError.data.kind;
9131
9459
  * anything retryable without a specific kind is transport.
@@ -11579,6 +11907,8 @@ async function runAgent(options) {
11579
11907
  for (;;) {
11580
11908
  const target = site.chain[site.cursor.index] ?? site.chain[0];
11581
11909
  let tries = 0;
11910
+ let denialTurns = 0;
11911
+ const maxDenials = options.quota?.maxDenials ?? 8;
11582
11912
  inner: for (;;) {
11583
11913
  let reservationId;
11584
11914
  const segmentReservations = [];
@@ -11819,14 +12149,16 @@ async function runAgent(options) {
11819
12149
  reportedLimits: limited.reportedLimits
11820
12150
  });
11821
12151
  }
11822
- tries += 1;
12152
+ if (outcome.quotaDenied === true) denialTurns += 1;
12153
+ else tries += 1;
11823
12154
  const retryClass = outcome.aborted === "idle" ? "transport" : outcome.wireError === void 0 ? void 0 : retryClassOf(outcome.wireError);
11824
12155
  if (retryClass === void 0) return {
11825
12156
  outcome,
11826
12157
  target
11827
12158
  };
11828
12159
  usageApprox = usageApprox || outcome.usageApprox;
11829
- if (retryOn.includes(retryClass) && tries < retryPolicy.attempts) {
12160
+ const retryBudgetLeft = outcome.quotaDenied === true ? denialTurns < maxDenials : tries < retryPolicy.attempts;
12161
+ if (retryOn.includes(retryClass) && retryBudgetLeft) {
11830
12162
  const abortedBefore = abortKind();
11831
12163
  if (abortedBefore !== void 0) return {
11832
12164
  outcome: abortedOutcome(abortedBefore),
@@ -11834,7 +12166,7 @@ async function runAgent(options) {
11834
12166
  };
11835
12167
  const retryAfter = (outcome.wireError?.data)?.retryAfterMs;
11836
12168
  if (outcome.wireError !== void 0) {
11837
- transportRetries += 1;
12169
+ if (outcome.quotaDenied !== true) transportRetries += 1;
11838
12170
  events?.emit({
11839
12171
  type: "agent:error",
11840
12172
  agentType,
@@ -11843,7 +12175,7 @@ async function runAgent(options) {
11843
12175
  willRetry: true
11844
12176
  });
11845
12177
  }
11846
- await backoffWait(retryDelayMs(retryPolicy, tries - 1, typeof retryAfter === "number" ? retryAfter : void 0, retryRandom));
12178
+ await backoffWait(retryDelayMs(retryPolicy, outcome.quotaDenied === true ? denialTurns - 1 : tries - 1, typeof retryAfter === "number" ? retryAfter : void 0, retryRandom));
11847
12179
  const abortedAfter = abortKind();
11848
12180
  if (abortedAfter !== void 0) return {
11849
12181
  outcome: abortedOutcome(abortedAfter),
@@ -14356,319 +14688,6 @@ function ladderRungChoice(ladder, index) {
14356
14688
  };
14357
14689
  }
14358
14690
  //#endregion
14359
- //#region src/model/quota.ts
14360
- /**
14361
- * Quota rules and the in-process reference QuotaLimiter (RV-215).
14362
- * The rule model is shared by every reference implementation
14363
- * (memoryQuotaLimiter here, SqliteQuotaLimiter in
14364
- * @rulvar/store-sqlite): fixed one-minute windows aligned to the
14365
- * epoch, admission at reservation time, reconciliation to actual
14366
- * usage inside the same window. The hard guarantee is on
14367
- * `requestsPerMinute` (every wire attempt is exactly one request);
14368
- * `tokensPerMinute` admits on the heuristic estimate and settles to
14369
- * actual usage, so token windows are approximate at admission and
14370
- * exact at settlement.
14371
- *
14372
- * Docs: https://docs.rulvar.com/guide/model-routing
14373
- */
14374
- /**
14375
- * Captured at module load, before the InProcessRunner's
14376
- * nondeterminism guard can patch the global: the limiter's clock is
14377
- * engine infrastructure on the live-only dispatch path and must never
14378
- * be blamed on workflow code.
14379
- */
14380
- const nativeNow = Date.now;
14381
- /** The fixed accounting window every PerMinute cap counts over. */
14382
- const QUOTA_WINDOW_MS = 6e4;
14383
- /**
14384
- * Validates a quota rule set as a typed ConfigError before any
14385
- * limiter can admit under it: a non-array or empty set, a rule
14386
- * without a cap, a malformed dimension, or a malformed cap all fail
14387
- * loud at construction. Shared by every reference implementation.
14388
- */
14389
- function validateQuotaRules(rules, site = "quota rules") {
14390
- const raw = rules;
14391
- if (!Array.isArray(raw)) throw new ConfigError(`${site} must be an array of QuotaRule objects`);
14392
- if (raw.length === 0) throw new ConfigError(`${site} must contain at least one rule`);
14393
- raw.forEach((entry, index) => {
14394
- const at = `${site}[${String(index)}]`;
14395
- if (typeof entry !== "object" || entry === null || Array.isArray(entry)) throw new ConfigError(`${at} must be a QuotaRule object`);
14396
- const rule = entry;
14397
- for (const dimension of [
14398
- "provider",
14399
- "model",
14400
- "tenant"
14401
- ]) {
14402
- const value = rule[dimension];
14403
- if (value !== void 0 && (typeof value !== "string" || value === "")) throw new ConfigError(`${at}.${dimension} must be a nonempty string when given`);
14404
- }
14405
- if (rule.requestsPerMinute === void 0 && rule.tokensPerMinute === void 0) throw new ConfigError(`${at} must set requestsPerMinute or tokensPerMinute (or both)`);
14406
- for (const cap of ["requestsPerMinute", "tokensPerMinute"]) if (rule[cap] !== void 0) requirePositiveInteger$2(rule[cap], `${at}.${cap}`);
14407
- });
14408
- }
14409
- /**
14410
- * The canonical content key of one rule (RV608, promoted from the
14411
- * store limiters): a fixed-field-order JSON of the rule, identical
14412
- * across processes and hosts for identical rules. It is the bucket key
14413
- * of both store references, the input of
14414
- * `quotaRulesFingerprint`, and the CANONICAL ORDER every reference
14415
- * limiter folds denials in, so equal rule sets produce byte-identical
14416
- * refusal objects regardless of array permutation.
14417
- */
14418
- function quotaRuleKey(rule) {
14419
- return JSON.stringify({
14420
- provider: rule.provider ?? null,
14421
- model: rule.model ?? null,
14422
- tenant: rule.tenant ?? null,
14423
- requestsPerMinute: rule.requestsPerMinute ?? null,
14424
- tokensPerMinute: rule.tokensPerMinute ?? null
14425
- });
14426
- }
14427
- /**
14428
- * Validates a rule set and returns the immutable snapshot every
14429
- * reference limiter admits under (RV608): a fresh array of fresh
14430
- * objects carrying ONLY the known rule fields, each frozen, the array
14431
- * frozen. The caller's array and objects stay untouched and unshared,
14432
- * so ordinary JavaScript after the constructor (a pushed rule, a
14433
- * reassigned cap) can no longer change a decision, a bucket key, or a
14434
- * recorded fingerprint.
14435
- *
14436
- * A set containing two rules with the same canonical content key is
14437
- * refused typed (RV704): the memory reference buckets by rule INDEX
14438
- * (each copy counts independently, the full cap admits) while the
14439
- * store references bucket by rule KEY (one shared bucket is debited
14440
- * once per matching copy, half the cap admits), so the same duplicated
14441
- * configuration admitted differently per storage. Refusing it at the
14442
- * shared construction chokepoint is what keeps equal configurations
14443
- * equal on every storage.
14444
- */
14445
- function snapshotQuotaRules(rules, site = "quota rules") {
14446
- validateQuotaRules(rules, site);
14447
- const firstIndexByKey = /* @__PURE__ */ new Map();
14448
- rules.forEach((rule, index) => {
14449
- const key = quotaRuleKey(rule);
14450
- const first = firstIndexByKey.get(key);
14451
- if (first !== void 0) throw new ConfigError(`${site}[${String(index)}] duplicates ${site}[${String(first)}] (rule key ${key}): identical rules occupy independent buckets in memory but share one key-debited bucket on keyed storage, so one configuration would admit differently per store; delete the duplicate`);
14452
- firstIndexByKey.set(key, index);
14453
- });
14454
- return Object.freeze(rules.map((rule) => Object.freeze({
14455
- ...rule.provider === void 0 ? {} : { provider: rule.provider },
14456
- ...rule.model === void 0 ? {} : { model: rule.model },
14457
- ...rule.tenant === void 0 ? {} : { tenant: rule.tenant },
14458
- ...rule.requestsPerMinute === void 0 ? {} : { requestsPerMinute: rule.requestsPerMinute },
14459
- ...rule.tokensPerMinute === void 0 ? {} : { tokensPerMinute: rule.tokensPerMinute }
14460
- })));
14461
- }
14462
- /** True when every dimension the rule pins matches the request. */
14463
- function quotaRuleMatches(rule, request) {
14464
- return (rule.provider === void 0 || rule.provider === request.provider) && (rule.model === void 0 || rule.model === request.model) && (rule.tenant === void 0 || rule.tenant === request.tenant);
14465
- }
14466
- /** The tokens a reservation is admitted under: input estimate plus the output cap. */
14467
- function quotaEstimateTokens(request) {
14468
- return request.estimate.inputTokens + (request.estimate.maxOutputTokens ?? 0);
14469
- }
14470
- /** The tokens a settled attempt actually consumed. */
14471
- function quotaActualTokens(usage) {
14472
- return usage.inputTokens + usage.outputTokens;
14473
- }
14474
- /**
14475
- * The request-count settlement delta of one reservation (RV905): the
14476
- * reservation admitted ONE wire request, and `actual.requests` names
14477
- * how many the attempt actually made (an adapter absorbing
14478
- * provider-side continuations dispatches several inside one reserved
14479
- * call). Non-integer, non-positive, or absent actuals settle as the
14480
- * single reserved request (delta 0); a settlement only ever ADDS, the
14481
- * calls already happened. Shared by every reference limiter so the
14482
- * three implementations cannot disagree about the arithmetic.
14483
- */
14484
- function quotaActualRequestsDelta(actual) {
14485
- const requests = actual?.requests;
14486
- return typeof requests === "number" && Number.isInteger(requests) && requests > 1 ? requests - 1 : 0;
14487
- }
14488
- /**
14489
- * One rule's admission verdict against its current-window counters,
14490
- * the pure decision both reference implementations share. A denial
14491
- * carries the window remainder as retryAfterMs, except when the
14492
- * estimate alone can never fit the token cap: that denial says
14493
- * retryAfterMs 0 (retry immediately), so the caller's bounded
14494
- * attempts exhaust without waiting and failover gets its chance.
14495
- */
14496
- function quotaRuleAdmission(rule, counters, estimate, msUntilWindowEnd) {
14497
- if (rule.requestsPerMinute !== void 0 && counters.requests + estimate.requests > rule.requestsPerMinute) return {
14498
- admit: false,
14499
- retryAfterMs: msUntilWindowEnd,
14500
- reason: `requestsPerMinute ${String(rule.requestsPerMinute)} exhausted`
14501
- };
14502
- if (rule.tokensPerMinute !== void 0) {
14503
- if (estimate.tokens > rule.tokensPerMinute) return {
14504
- admit: false,
14505
- retryAfterMs: 0,
14506
- reason: `the estimate of ${String(estimate.tokens)} tokens can never fit tokensPerMinute ${String(rule.tokensPerMinute)}`
14507
- };
14508
- if (counters.tokens + estimate.tokens > rule.tokensPerMinute) return {
14509
- admit: false,
14510
- retryAfterMs: msUntilWindowEnd,
14511
- reason: `tokensPerMinute ${String(rule.tokensPerMinute)} exhausted`
14512
- };
14513
- }
14514
- return { admit: true };
14515
- }
14516
- /**
14517
- * Folds one more failing rule into the decision the caller returns:
14518
- * the wait is the LONGEST failing horizon (every matching rule must
14519
- * admit), and the FIRST failing rule names the denial.
14520
- */
14521
- function mergeQuotaDenial(current, next) {
14522
- if (current === void 0) return {
14523
- retryAfterMs: next.retryAfterMs,
14524
- reason: next.reason
14525
- };
14526
- return next.retryAfterMs > current.retryAfterMs ? {
14527
- retryAfterMs: next.retryAfterMs,
14528
- reason: current.reason
14529
- } : current;
14530
- }
14531
- /**
14532
- * The in-process reference QuotaLimiter: fixed epoch-aligned
14533
- * one-minute windows over the shared rule model. Coordinates every
14534
- * engine that shares THIS instance inside one process; processes
14535
- * coordinate through a shared-storage implementation of the same SPI
14536
- * (SqliteQuotaLimiter in @rulvar/store-sqlite) instead.
14537
- */
14538
- function memoryQuotaLimiter(rules, options = {}) {
14539
- const frozen = snapshotQuotaRules(rules, "memoryQuotaLimiter rules");
14540
- const ordered = frozen.map((rule, index) => ({
14541
- rule,
14542
- index,
14543
- key: quotaRuleKey(rule)
14544
- })).sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
14545
- const now = options.now ?? (() => nativeNow());
14546
- const buckets = /* @__PURE__ */ new Map();
14547
- const reservations = /* @__PURE__ */ new Map();
14548
- let nextReservation = 0;
14549
- const windowStartAt = (at) => at - at % QUOTA_WINDOW_MS;
14550
- const bucketFor = (ruleIndex, windowStart) => {
14551
- let bucket = buckets.get(ruleIndex);
14552
- if (bucket === void 0 || bucket.windowStart !== windowStart) {
14553
- bucket = {
14554
- windowStart,
14555
- requests: 0,
14556
- tokens: 0
14557
- };
14558
- buckets.set(ruleIndex, bucket);
14559
- }
14560
- return bucket;
14561
- };
14562
- const prune = (windowStart) => {
14563
- for (const [id, reservation] of reservations) if (reservation.windowStart < windowStart) reservations.delete(id);
14564
- };
14565
- return {
14566
- reserve(request) {
14567
- const at = now();
14568
- const windowStart = windowStartAt(at);
14569
- prune(windowStart);
14570
- const estimateTokens = quotaEstimateTokens(request);
14571
- const msUntilWindowEnd = windowStart + QUOTA_WINDOW_MS - at;
14572
- const matched = [];
14573
- let denial;
14574
- for (const { rule, index } of ordered) {
14575
- if (!quotaRuleMatches(rule, request)) continue;
14576
- matched.push(index);
14577
- const verdict = quotaRuleAdmission(rule, bucketFor(index, windowStart), {
14578
- requests: request.estimate.requests,
14579
- tokens: estimateTokens
14580
- }, msUntilWindowEnd);
14581
- if (!verdict.admit) denial = mergeQuotaDenial(denial, verdict);
14582
- }
14583
- if (denial !== void 0) return Promise.resolve({
14584
- granted: false,
14585
- ...denial
14586
- });
14587
- for (const index of matched) {
14588
- const bucket = bucketFor(index, windowStart);
14589
- bucket.requests += request.estimate.requests;
14590
- bucket.tokens += estimateTokens;
14591
- }
14592
- nextReservation += 1;
14593
- const reservationId = `mq-${String(nextReservation)}`;
14594
- reservations.set(reservationId, {
14595
- windowStart,
14596
- estimateTokens,
14597
- requests: request.estimate.requests,
14598
- ruleIndexes: matched
14599
- });
14600
- return Promise.resolve({
14601
- granted: true,
14602
- reservationId
14603
- });
14604
- },
14605
- reconcile(reservationId, usage, actual) {
14606
- const reservation = reservations.get(reservationId);
14607
- if (reservation === void 0) return Promise.resolve();
14608
- reservations.delete(reservationId);
14609
- const windowStart = windowStartAt(now());
14610
- if (reservation.windowStart !== windowStart) return Promise.resolve();
14611
- const delta = quotaActualTokens(usage) - reservation.estimateTokens;
14612
- const requestsDelta = quotaActualRequestsDelta(actual);
14613
- for (const index of reservation.ruleIndexes) {
14614
- const bucket = buckets.get(index);
14615
- if (bucket !== void 0 && bucket.windowStart === windowStart) {
14616
- bucket.tokens = Math.max(0, bucket.tokens + delta);
14617
- bucket.requests += requestsDelta;
14618
- }
14619
- }
14620
- return Promise.resolve();
14621
- },
14622
- release(reservationId) {
14623
- const reservation = reservations.get(reservationId);
14624
- if (reservation === void 0) return Promise.resolve();
14625
- reservations.delete(reservationId);
14626
- const windowStart = windowStartAt(now());
14627
- if (reservation.windowStart !== windowStart) return Promise.resolve();
14628
- for (const index of reservation.ruleIndexes) {
14629
- const bucket = buckets.get(index);
14630
- if (bucket !== void 0 && bucket.windowStart === windowStart) {
14631
- bucket.requests = Math.max(0, bucket.requests - reservation.requests);
14632
- bucket.tokens = Math.max(0, bucket.tokens - reservation.estimateTokens);
14633
- }
14634
- }
14635
- return Promise.resolve();
14636
- },
14637
- snapshot() {
14638
- const windowStart = windowStartAt(now());
14639
- return frozen.map((rule, index) => {
14640
- const bucket = buckets.get(index);
14641
- const current = bucket !== void 0 && bucket.windowStart === windowStart;
14642
- return {
14643
- rule,
14644
- windowStart,
14645
- requests: current ? bucket.requests : 0,
14646
- tokens: current ? bucket.tokens : 0
14647
- };
14648
- });
14649
- }
14650
- };
14651
- }
14652
- /**
14653
- * Validates createEngine's quota config as a typed ConfigError before
14654
- * any run could dispatch under a malformed limiter (the intake
14655
- * discipline every engine option follows).
14656
- */
14657
- function validateEngineQuotaConfig(config, site = "createEngine quota") {
14658
- if (config === void 0) return;
14659
- const raw = config;
14660
- if (typeof raw !== "object" || raw === null || Array.isArray(raw)) throw new ConfigError(`${site} must be an object with a limiter`);
14661
- const candidate = raw;
14662
- const limiter = candidate.limiter;
14663
- if (typeof limiter !== "object" || limiter === null || typeof limiter.reserve !== "function" || typeof limiter.reconcile !== "function") throw new ConfigError(`${site}.limiter must implement QuotaLimiter (reserve and reconcile functions)`);
14664
- if (candidate.tenant !== void 0 && (typeof candidate.tenant !== "string" || candidate.tenant === "")) throw new ConfigError(`${site}.tenant must be a nonempty string when given`);
14665
- if (candidate.onLimiterError !== void 0 && candidate.onLimiterError !== "deny" && candidate.onLimiterError !== "allow") throw new ConfigError(`${site}.onLimiterError must be 'deny' or 'allow' when given`);
14666
- const reserveContinuations = candidate.reserveContinuations;
14667
- if (reserveContinuations !== void 0 && typeof reserveContinuations !== "boolean") throw new ConfigError(`${site}.reserveContinuations must be a boolean when given`);
14668
- const declared = candidate.declaredRules;
14669
- if (declared !== void 0) validateQuotaRules(declared, `${site}.declaredRules`);
14670
- }
14671
- //#endregion
14672
14691
  //#region src/runtime/usage-limits.ts
14673
14692
  /**
14674
14693
  * UsageLimits (M1-T06): normative limit vocabulary and the per-spawn merge.
@@ -16614,7 +16633,8 @@ function createCtx(internals, rootWorkflow) {
16614
16633
  }),
16615
16634
  reconcile: (reservationId, usage, actual) => quota.limiter.reconcile(reservationId, usage, actual),
16616
16635
  onLimiterError: quota.onLimiterError,
16617
- reserveContinuations: quota.reserveContinuations
16636
+ reserveContinuations: quota.reserveContinuations,
16637
+ maxDenials: quota.maxDenials
16618
16638
  };
16619
16639
  const limiterRelease = quota.limiter.release?.bind(quota.limiter);
16620
16640
  if (limiterRelease !== void 0) runAgentOptions.quota.release = limiterRelease;
@@ -24105,6 +24125,7 @@ function createEngine(options) {
24105
24125
  ...options.quota.tenant === void 0 ? {} : { tenant: options.quota.tenant },
24106
24126
  onLimiterError: options.quota.onLimiterError ?? "deny",
24107
24127
  reserveContinuations: options.quota.reserveContinuations ?? false,
24128
+ maxDenials: options.quota.maxDenials ?? 8,
24108
24129
  ...options.quota.declaredRules === void 0 ? {} : { declaredRules: options.quota.declaredRules }
24109
24130
  };
24110
24131
  const knowledgeStore = options.stores?.modelKnowledge;
@@ -25130,4 +25151,4 @@ function createSandboxBridge(ctx, options) {
25130
25151
  };
25131
25152
  }
25132
25153
  //#endregion
25133
- 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_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, 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, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, 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_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GitWorktreeProvider, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JOURNAL_ENVELOPE_MARKER, 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, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, PlanInvariantError, QUOTA_WINDOW_MS, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, 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, SettlementError, SpanRegistry, SupersededError, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, citationTargetsValidator, citedValueValidator, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reduceAuditTrail, reduceCriticalPath, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolContractHash, toolsetHash, ttlState, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
25154
+ 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_ANCHOR_PATTERN, DEFAULT_ARTIFACT_PATTERN, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_CLAIM_JUDGE_MAX_TURNS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_GRADE_PHRASES, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_CLAIM_PAIRS, DEFAULT_MAX_CONTRADICTIONS, DEFAULT_MAX_DEPTH, DEFAULT_MAX_EXCERPT_CHARS, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PAIR_EXCERPT_CHARS, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_POOL_PER_PAIR, DEFAULT_MAX_QUOTA_DENIALS, 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, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, 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_SECTIONAL_SCHEMA, FINISH_TOOL_NAME, FailRunError, FileModelKnowledgeStore, FileTranscriptStore, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, GitWorktreeProvider, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IN_FLIGHT_EXPOSURE_REFUSAL_PREFIX, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, InvalidResolutionError, JOURNAL_ENVELOPE_MARKER, 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, MAX_RUN_ID_LENGTH, MAX_TIMER_DELAY_MS, ModelRetry, NoProgressDetector, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OrchestratorCapConfigError, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, PlanInvariantError, QUOTA_WINDOW_MS, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, 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, SettlementError, SpanRegistry, SupersededError, TOOL_NAME_PATTERN, TerminationAccount, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, accountSpendFromJournal, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, assertSafeRunId, atCompactionThreshold, attestToolset, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, citationTargetsValidator, citedValueValidator, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compareRates, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, enforceToolsetAttestation, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidenceGradeValidator, evidencePreservedValidator, executeWorkflow, executionFactsOf, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, findContradictions, finishContract, foldLedger, foldTermination, formatCharacterValidator, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, pairDraftClaims, parallelScope, parseModelRef, parseScopePath, persistedTerminalEnvelope, phiInitialOf, pipelineScope, planNodeScope, preflightEstimate, priceComponentsOf, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualRequestsDelta, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reduceAuditTrail, reduceCriticalPath, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, spliceSections, stripFencedBlocks, sumUsage, summarizeInstruction, summarizeOutput, terminalEnvelopeOf, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolContractHash, toolsetHash, ttlState, usageViolations, validateDetachedResolution, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateToolsetAttestation, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/core",
3
- "version": "1.170.0",
3
+ "version": "1.172.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",