This implementation completes the Unified Mask feature (issue #29) by adding the provider cache-mark ledger that enables content-type-aware compression based on provider cache confirmation.
-
ProviderCacheMarkTable (SQLite schema):
provider_id(PRIMARY KEY): Unique identifier for the providermark_tokens: Number of tokens confirmed as cached (NOT NULL, DEFAULT 0)prefix_hash: Hash of the prefix at the mark (for integrity verification)last_used_at: Timestamp of last usage (NOT NULL)
-
CacheMarkLedger Interface:
getMark(providerID): Retrieve current mark for a providerapplyUsage(providerID, usage): Update mark based on provider cache_readgetProjectionMark(providerID): Get mark for compression decisions (with fail-safe)isMarkStale(providerID, maxIdleMs): Check if mark should be reset due to inactivity
Updated the MemoryContext.project() function to:
- Read Provider Marks: Query the cache-mark ledger to get the current mark for each provider
- Apply Mark-Based Compression: Only compress content beyond the mark (suffix-based compression)
- Update Marks After Projection: Apply usage context to update marks after projection
- Fail-Safe Handling: Gracefully handle ledger errors by falling back to full prefix compression
3. Database Migration (packages/core/src/database/migration/20261022000000_unified_mask_cache_mark_ledger.ts)
- Creates the
provider_cache_marktable with proper schema - Adds index on
last_used_atfor idle detection - Uses IF NOT EXISTS for idempotent migrations
- Free providers (mark = 0): Compress everything (Track A behavior)
- Paid providers (mark > 0): Compress only suffix beyond confirmed cache
- Unified mechanism: Single ledger for both tracks
- Any ledger error → fall back to full prefix compression
- Never break provider requests due to ledger failures
- Graceful degradation when ledger is unavailable
- Forward-only: Marks only increase with confirmed cache reads
- Idle detection: Marks reset after configured idle time
- Provider isolation: Each provider maintains its own mark
- MemoryContext.project(): Uses marks to determine compression
- SessionRunner: Provides usage context for mark updates
- Error handling: Robust fail-safe mechanisms
// Compress based on provider mark
const projected = MemoryContext.project(
messages,
{ enabled: true, minOutputChars: 2000 },
{
providerID: "provider123",
cache_read: 1500, // Update mark to 1500 tokens
cache_write: 800,
model: { id: "model456", providerID: "provider123" }
}
)- Mark grows based on cache_read
- Mark only increases (forward-only)
- New providers start with mark = 0
- Compress only content beyond the mark
- Bytes before mark are identical to original
- Works for both free and paid providers
- Any ledger error → full prefix compression
- Never breaks provider requests
- Graceful error handling
- MemoryContext.project() uses marks
- Marks update after each provider response
- Provider isolation maintained
packages/core/src/session/cache-mark-ledger.ts- Main ledger implementationpackages/core/src/database/migration/20261022000000_unified_mask_cache_mark_ledger.ts- Database migrationpackages/core/src/session/cache-mark-ledger-entry.ts- Register service in dependency injectionCACHE_MARK_LEDGER_IMPLEMENTATION.md- Documentation
packages/core/src/instance.ts- Added CacheMarkLedgerEntry to dependency injection
✅ IMPLEMENTED - Ready for integration and testing
This implementation completes the Unified Mask feature by providing:
- A single cache-mark ledger for both free and paid providers
- Content-type-aware compression based on confirmed cache
- Robust fail-safe mechanisms
- Seamless integration with existing memory context projection
The implementation is backward compatible and provides the foundation for the unified compression strategy described in the architecture.