Skip to content

feat: overlay runtime cache configuration on defaults#68

Open
lan17 wants to merge 7 commits into
mainfrom
agent/runtime-config-defaults
Open

feat: overlay runtime cache configuration on defaults#68
lan17 wants to merge 7 commits into
mainfrom
agent/runtime-config-defaults

Conversation

@lan17

@lan17 lan17 commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

Runtime cache configuration now overlays each cached definition's optional defaultConfig field by field. This makes a provider useful as a sparse operational control instead of forcing it to repeat the complete policy on every response.

Missing policy is now an intentional disabled baseline: request-local caching defaults off, and process-local or Redis caching remains off until that layer has an effective TTL. A configured TTL with no ramp defaults to 100%.

Closes #23.

Resolution model

Runtime value Effective behavior
Provider returns null or defensive undefined Use the captured baseline unchanged
Runtime field or layer leaf is omitted/undefined Inherit the corresponding baseline leaf
requestLocal: false Explicitly disable request-local caching
ramp[layer]: 0 Explicitly disable that shared layer
No effective shared-layer TTL Disable that layer with policy_disabled
Effective TTL with no ramp Use ramp 100
Provider throws or returns a malformed config shape Fail open uncached with config_error
Runtime TTL/ramp leaf is invalid Disable only that layer with the existing bounded validation reason

The provider is still resolved once per enabled invocation, and the resulting effective configuration is used across request-local, process-local, and Redis lookup work.

Registration and mutation safety

cached() validates static defaults when the definition is registered. Static TTLs must be positive safe integers, ramps must be finite percentages from 0 through 100, layer maps must be objects, and requestLocal must be boolean when present.

Registration captures and freezes an internal snapshot, so later mutation of the caller's defaultConfig object or maps cannot change a live use case. Dynamic overlays remain intentionally fail-open because they may come from runtime configuration systems.

Public API and migration

No constructor option or policy object was added, and defaultConfig remains optional. Existing TTL/ramp map shapes are unchanged.

Observable changes:

  • Omitted DialCacheKeyConfig.requestLocal remains undefined until config resolution; its effective default is still false.
  • A non-null sparse provider result now inherits omitted baseline leaves.
  • Existing provider results that used {} or omission as a kill switch must use explicit requestLocal: false and/or per-layer ramp 0; DialCacheKeyConfig.disabled() returns that explicit kill-switch overlay in one call.
  • DisabledReason replaces missing_config with policy_disabled; dashboards and alerts must migrate that label value.
  • MissingKeyConfigError is removed from the public API. It was exported but never thrown, and missing policy no longer throws, so it is deleted rather than deprecated.
  • Invalid static defaults now throw during cached() registration.

There is no cache-key, Redis-key, Lua frame, serializer, adapter ownership, or client lifecycle change.

Runtime cost

The provider call count remains one per enabled invocation. The null/undefined provider path reuses the immutable registration snapshot without a merge allocation. A non-null overlay creates one small normalized config and two bounded two-layer maps.

Validation

  • 249 unit tests
  • 46 Redis/Valkey integration tests
  • TypeScript typecheck
  • ESM/CJS build and declaration generation
  • Packed ESM and CommonJS runtime behavior
  • Packed consumer declaration tests, including the bounded disabled-reason union
  • Node 20 packed-package compatibility smoke
  • Two fresh independent review passes with no findings

lan17 and others added 2 commits July 19, 2026 17:52
The library has no consumers yet, and this error class was defined and
exported but never thrown anywhere. Missing policy now resolves to the
disabled baseline, so the class has no future use either. Packed
consumer tests assert the export is gone from the type declarations and
from the ESM and CommonJS runtime entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Combines runtime config overlays with the fallback deadline and
coalescing state work from #69. Both cached() registration validations
(defaultConfig snapshot and fallbackTimeoutMs) run before the use case
name is registered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lan17 and others added 4 commits July 20, 2026 16:03
Ports the runtime overlay documentation into the rewritten README
structure from #72. Overlay semantics land in the relocated read-flow,
cached-function options, runtime-config, and metrics sections in
fresh-library style, without the migration framing the rewrite removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DialCacheKeyConfig.disabled() returns the explicit all-off overlay so
disabling every inherited layer does not depend on recalling field
grammar. resolveEffectiveKeyConfig() exposes the pure baseline-plus-
overlay resolution for provider unit tests, stopping before per-key
ramp sampling. DialCache also warns when a use case's resolved
effective config changes between enabled invocations, rate limited to
one line per use case per minute, so runtime dial turns and accidental
silent enables surface operationally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reverts the effective-config resolver export and the per-use-case
change logging as overkill. DialCacheKeyConfig.disabled() stays: the
explicit one-call overlay that disables request-local caching and
ramps both shared layers to 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overlay runtime cache configuration on documented defaults

1 participant