Session- and auth-bound task context cache
Key in-process task-context caches by session epoch, live auth generation, and content revision; isolate shared-process sessions, survive mid-session auth replace, and keep prompt data separate from network authority.
Session- and auth-bound task context cache
Key in-process task-context caches by session epoch, live auth generation, and content revision; isolate shared-process sessions, survive mid-session auth replace, and keep prompt data separate from network authority.
When to use
Use when an agent plugin caches task context before a system-message transform, multiple root or child sessions share one process, and authorization may be revoked or replaced while that process and root session stay alive.
Practical steps
- Composite key with reserved root sentinels. Key every immutable entry by authLineageId, sessionId, sessionEpoch, authGeneration, contentRevision, childBindingId, and parentLineageGeneration. Use fixed reserved sentinels for root childBindingId and parentLineageGeneration that real ID allocation must never produce. Resolve authGeneration only from the live authorization handle at every write, read, and inject—never from closure state captured across await.
- Session epoch in request scope. Carry sessionId and sessionEpoch in request scope such as AsyncLocalStorage. On epoch bump, tombstone all entries for the prior epoch. At every operation verify scope sessionEpoch equals live session epoch; mismatch fails closed to empty inject. Workers must re-enter scope from a trusted task envelope at entry; scope loss without restoration fails closed.
- Separate auth generation from content revision. Bump contentRevision for content-only updates; bump authGeneration only on revoke or replace. Bind each model turn to explicit contentRevision in a turn lease on the turn handle—never inject implicit latest across internal awaits.
- Exact lookup, fail closed. After any await, re-resolve the full composite key from live handles immediately before lookup. Missing key, generation mismatch, or stale parentLineageGeneration on child entries yields empty inject. Never fall back to parent, sibling, latest, or prior generation.
- Auth replace under lock hierarchy. Define AuthLineageLock before SessionCacheLock; always acquire in that order. Under lineage lock: tombstone entries matching revoked authLineageId and authGeneration including child lineage; if authLineageId rotates, tombstone all entries for the old authLineageId; cancel queued work tagged with old generation; bump every bound handle so new credentials and authGeneration are observable together; signal in-flight workers to abort or re-check at commit. On swap failure after tombstone, fail closed on network and inject.
- Child fork as point-in-time snapshot. Copy-on-create a sanitized snapshot under a critical section blocking parent writers and child readers. Publish one immutable ChildForkRecord containing childBindingId, parentAuthGeneration, and snapshot via atomic swap—readers never load fields independently. Child prompt context is fork-time snapshot, not live parent inheritance. Re-validate live parent authGeneration on every child read and inject.
- Write-side TOCTOU mirror. Under SessionCacheLock then lineage lock: resolve live composite key, verify generation, serialize a deep-cloned deep-frozen immutable entry. At commit, require authGeneration and contentRevision to match values observed at write start and contentRevision at or above the binding high-water mark; abort if live generation changed during serialization.
- Inject pin lock plus commit checkpoint. One lock unit covers resolve live handle, build full key, lookup, verify generations, pin, deep-copy into message buffer, release pin—repeat entire unit after any await. Immediately before system-message commit, re-read live authGeneration and tombstone state; discard copy on mismatch. Tombstoned entries reject new pins; cap pinned bytes, concurrent pins, and pin duration per session.
- Prompt data versus network authority. Cached context is prompt data only—never embed credentials or scopes. Mint short-lived capabilities from a live-handle snapshot. Tag dispatches with authLineageId and authGeneration; reject mismatch at enqueue and again at execution before socket write, RPC, or filesystem side effect.
- Memory bounds. Cap bytes per entry, per session, and process-wide. Delete-on-bump as primary eviction; LRU plus TTL for orphans. Account pinned snapshots, pin refcounts, fork duplication, and queued work in budgets.
Limits
- Does not scrub prompt text already committed to an in-flight model turn before auth replace.
- Cannot recall bytes already on the wire under a prior generation.
- Model may plan from semantically stale prompt while network gate uses fresh credentials.
- Child fork intentionally does not track parent content edits after fork.
- Does not define distributed revocation protocol, capability format, or crash-recovery store.
- Support is reasoned analysis and independent adversarial subagent review in the source conversation, not executed tests.
Failure prevented
Prevents cross-session and cross-generation context injection including sessionId reuse without epoch; stale context surviving auth replace or lineage rotation; child torn reads and fork partial-publication races; inject and write TOCTOU across await, threads, or concurrent replace; shallow-copy mutation leaks; sentinel key collisions; stale prompt authorizing network activity via enqueue-only gates; lock-order deadlock skipping invalidation; worker scope loss causing silent empty or wrong-session inject; and unbounded memory from orphaned generations, idle sessions, or pin leaks.
Supporting basis
Multi-turn reasoned design and second-pass independent adversarial subagent review in the cited source conversation. No repository inspection and no executed tests were performed.