Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/auto-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Auto Tag on Merge
on:
push:
branches: [main]
workflow_dispatch:

jobs:
tag:
Expand Down Expand Up @@ -39,7 +40,9 @@ jobs:
if: steps.check_tag.outputs.exists == 'false'
run: |
pip install build twine
python scripts/verify_release_v6.py
python -m build
python scripts/generate_sbom_v1.py --dist-dir dist
python scripts/verify_release_v1.py --dist-dir dist

- name: Create and push tag
if: steps.check_tag.outputs.exists == 'false'
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,11 @@ jobs:
- run: pip install build twine "readme-renderer[md]"
- run: python -m build
- run: twine check --strict dist/*
- run: python scripts/generate_sbom_v1.py --dist-dir dist
- name: Check package metadata
run: python scripts/check_package_metadata.py
run: python scripts/check_package_metadata.py --dist-dir dist
- name: Verify release readiness
run: python scripts/verify_release_v1.py --dist-dir dist

- uses: actions/upload-artifact@v4
with:
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
permissions:
contents: read
id-token: write
attestations: write

jobs:
pypi-publish:
Expand All @@ -30,13 +31,22 @@ jobs:
- name: Build binary wheel and source tarball
run: python -m build

- name: Generate CycloneDX SBOM
run: python scripts/generate_sbom_v1.py --dist-dir dist

- name: Check package distribution
run: |
twine check --strict dist/*
python scripts/check_package_metadata.py --dist-dir dist
python scripts/verify_release_v6.py --dist-dir dist
python scripts/verify_release_v1.py --dist-dir dist

- name: Generate build provenance attestation
uses: actions/attest-build-provenance@v1
with:
subject-path: "dist/*"

- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true
attestations: true
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes are recorded here using [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [1.0.0] - 2026-11-06

### Added

- **Public API Freeze & Contract Lock:** Frozen public API contract with `API_CONTRACT_VERSION = "1.0"`, automated signature locking against `tests/fixtures/api_contract_v1_0.json`, and package graduation from `Beta` to `Development Status :: 5 - Production/Stable` with `Typing :: Typed`.
- **Promotion of Qualified Surfaces:** Graduated all `0.5.0` candidate symbols in `PUBLIC_API_STABILITY` from `"stable-candidate"` to `"stable"`, including `SharedRedisCacheBackend` and `SharedCoordinationBackend` following `0.6.0` qualification.
- **Runtime Warnings for Pass-Through & Experimental Surfaces:** Added `LongCachePassThroughWarning` (emitted on instantiation/use of `CachedLLM`, `CachedChain`, `CachedQueryEngine`, `CachedState`, `StreamingCacheAdapter`, and `cache.cached_stream`) and `LongCacheExperimentalWarning` (emitted on `AsyncRedisCacheBackend`).
- **Format-2 Persistence Upgrade Guarantee:** Added `tests/test_v1_persistence_compat.py` verifying zero data loss, zero re-indexing, and bit-identical partition digests (`v2:<sha256>`) for upgrading pre-populated SQLite and Redis caches.
- **Release Provenance & SBOM:** Added deterministic CycloneDX 1.5 JSON SBOM generation (`scripts/generate_sbom_v1.py`), `dist/SHA256SUMS.txt` manifests, and release verification via `scripts/verify_release_v1.py`.
- **Support & Migration Documentation:** Published `docs/semver-contract.md` (defining the 1.x stability contract) and `docs/migration-v1.0.md` (0.6.0 to 1.0.0 upgrade guide).

## [0.6.0] - 2026-11-05

### Added
Expand Down
36 changes: 15 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,15 @@ cache = LongCache(config, context=context)

- ✅ **SQLite Backend:** No external service, WAL mode, versioned manifests, transactional initialization; default backend
- ✅ **Redis Backend:** Versioned durable response storage with TTL; one LongCache process per generation in default mode
- 🧪 **Shared Redis Mode (opt-in):** Journal-synchronized local indexes, guarded replay, and distributed singleflight across processes; under qualification
- ✅ **Async Redis Backend:** Experimental standalone storage interface; unsupported through `LongCache`
- ✅ **Shared Redis Mode (opt-in):** Journal-synchronized local indexes, guarded replay, and distributed singleflight across processes
- 🧪 **Async Redis Backend:** Experimental standalone storage interface (emits `LongCacheExperimentalWarning`); unsupported through `LongCache`
- ✅ **In-Memory Backend:** Zero I/O, ideal for unit tests and CI/CD pipelines
- ✅ **LangChain Integration:** `CachedLLM` and `CachedChain` compatibility pass-through wrappers
- ✅ **LangGraph Integration:** `CachedState` compatibility interface; graph state is not cached
- ✅ **LlamaIndex Integration:** `CachedQueryEngine` preserves the engine interface without caching opaque state
- ✅ **LangChain Integration:** `CachedLLM` and `CachedChain` compatibility pass-through wrappers (emit `LongCachePassThroughWarning` by default)
- ✅ **LangGraph Integration:** `CachedState` compatibility pass-through interface; graph state is not cached
- ✅ **LlamaIndex Integration:** `CachedQueryEngine` compatibility pass-through wrapper; preserves the engine interface without caching opaque state
- ✅ **OpenAI Integration:** Supported single-turn text requests with explicit context; sync/async dict and SDK replay
- ✅ **FastAPI Middleware:** Bounded supported chat-completion JSON with trusted scope resolution and diagnostic headers
- ✅ **CLI:** `longcache stats`, `clear`, `inspect`, `export` — manage the cache without writing code
- ✅ **CLI:** `longcache stats`, `clear`, `inspect`, `export`, `info` — manage the cache without writing code

---

Expand Down Expand Up @@ -345,13 +345,13 @@ with LongCache(config, context=context) as cache:
| **Index** | Local FAISS; not synchronized with other processes | Local FAISS synchronized via Redis journal; journal gaps trigger a rebuild |
| **Coalescing** | Within one process | Across processes via fenced leases (15 s lifetime, 5 s renewal by default) |
| **Requires** | Redis | Dedicated non-evicting Redis; identical cache ID, generation, embedder, and policy settings |
| **Status** | Supported | Development; release qualification open |
| **Status** | Supported (`stable`) | Supported (`stable`) |

Shared-mode limits: one Redis authority only. Redis Cluster, Sentinel, failover, and replica reads are out of scope. After a Redis restart or restore, stop all workers, choose a new generation, and run a canary. Callbacks must be safe to repeat, because after a lease expires a new owner may run the origin again. Manual lookup → generate → store calls are not coalesced. Full contract: [shared Redis deployment](docs/deployment.md).

### Async Redis backend status

`AsyncRedisCacheBackend` can be used and tested as a standalone storage backend (`experimental` tier in `PUBLIC_API_STABILITY`). It is not supported through `LongCache`; selecting `backend="async_redis"` fails immediately. End-to-end async Redis integration is planned for a later release.
`AsyncRedisCacheBackend` can be used and tested as a standalone storage backend (`experimental` tier in `PUBLIC_API_STABILITY`, emitting `LongCacheExperimentalWarning` on instantiation unless `warn_experimental=False`). It is not supported through `LongCache`; selecting `backend="async_redis"` fails immediately. End-to-end async Redis integration is planned for a later release.

### In-Memory (Testing & CI)

Expand All @@ -369,7 +369,7 @@ cache = LongCache(CacheConfig(backend="memory"))

## Integrations

Generic LangChain, LangGraph, and LlamaIndex adapters below preserve their interfaces as `pass-through` compatibility wrappers (`cache_bypass_reason = "unsupported_request_shape"`). Use the explicit-context manual/decorator path or `CachedOpenAI` / `LongCacheMiddleware` for caching proven application workflows. All streaming helpers also pass through. See the [Support Matrix](docs/support-matrix.md).
Generic LangChain, LangGraph, and LlamaIndex adapters below preserve their interfaces as `pass-through` compatibility wrappers (`cache_bypass_reason = "unsupported_request_shape"`, `is_passthrough = True`) and emit `LongCachePassThroughWarning` by default (pass `warn_passthrough=False` to silence). Use the explicit-context manual/decorator path or `CachedOpenAI` / `LongCacheMiddleware` for caching proven application workflows. All streaming helpers (`@cache.cached_stream`, `StreamingCacheAdapter`) also pass through. See the [Support Matrix](docs/support-matrix.md) and [1.x SemVer Contract](docs/semver-contract.md).

### LangChain

Expand Down Expand Up @@ -883,13 +883,10 @@ longcache/
│ ├── test_langchain.py
│ ├── test_middleware.py
│ ├── test_cli.py
│ ├── test_shared_redis_v4.py # two-process shared Redis acceptance
│ ├── test_v06_slice_a.py # paged vector loading and compaction bounds
│ ├── test_qualification_stress_v6.py # multi-process Redis crash/churn stress suite
│ └── test_examples_and_migrations_v6.py # 0.x migration and example validation
│ ├── test_api_freeze_v1.py # frozen public API signature & contract lock
│ └── test_v1_persistence_compat.py # Format-2 persistence compatibility suite
├── evaluation/
│ ├── run.py, rag.py, deployment.py
│ ├── qualification_v6.py # v0.6 qualification benchmark runner
│ ├── cost_model.py # audited LLM net cost and latency model
│ ├── reports/
│ └── configs/
Expand Down Expand Up @@ -975,18 +972,15 @@ LONGCACHE_TEST_REDIS_URL=redis://localhost:16379/0 LONGCACHE_TEST_MODEL=1 \
Shared Redis tests are skipped unless `LONGCACHE_TEST_REDIS_URL` points at a disposable Redis 7.2 service. They own only test-prefixed keys and never flush the database:

```bash
LONGCACHE_TEST_REDIS_URL=redis://localhost:16379/0 uv run --no-sync pytest tests/test_shared_redis_v4.py -q -rs
LONGCACHE_TEST_REDIS_URL=redis://localhost:16379/0 uv run --no-sync python examples/multi_instance_rag.py
```

### Examples and Release Qualification Verification
### Release Provenance & SBOM Verification

```bash
# Verify all 7 examples and README quickstart workflow
LONGCACHE_TEST_REDIS_URL=redis://localhost:16379/0 uv run --no-sync python scripts/wheel_examples_v6.py

# Verify distribution build, hashes, changelog, and qualification benchmark evidence
uv run --no-sync python scripts/verify_release_v6.py --dist-dir dist --check-evidence
# Generate deterministic CycloneDX 1.5 SBOM and verify release artifacts, hashes, and benchmark evidence
uv run --no-sync python scripts/generate_sbom_v1.py --dist-dir dist
uv run --no-sync python scripts/verify_release_v1.py --dist-dir dist --check-evidence
```

---
Expand Down
Binary file removed assets/logo.png
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
| `shared_max_tag_chars` | `256` |
| `distributed_lease_seconds`, `distributed_renew_interval_seconds` | `15.0`, `5.0` |

Legacy `model`, `system_prompt`, `temperature`, and `track_miss` parameters were removed in v0.5.0; supply execution identity explicitly via `RequestContext`. See [Upgrading to v0.5](migration-v0.5.md) and the [Support Matrix](support-matrix.md) for public API stability classifications (`PUBLIC_API_STABILITY`).
Legacy `model`, `system_prompt`, `temperature`, and `track_miss` parameters were removed in v0.5.0; supply execution identity explicitly via `RequestContext`. In v1.0.0 (`API_CONTRACT_VERSION = "1.0"`), all qualified public interfaces are promoted to `"stable"` in `PUBLIC_API_STABILITY`, while compatibility pass-through shims emit `LongCachePassThroughWarning` and standalone experimental backends emit `LongCacheExperimentalWarning` (both subclasses of `LongCacheWarning(UserWarning)`). See [Upgrading to v1.0](migration-v1.0.md), the [1.x SemVer Contract](semver-contract.md), and the [Support Matrix](support-matrix.md) for full stability classifications.

## Policy and embedding interfaces

Expand Down
Binary file removed docs/assets/logo.png
Binary file not shown.
11 changes: 11 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

All notable changes are recorded here using [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [1.0.0] - 2026-11-06

### Added

- **Public API Freeze & Contract Lock:** Frozen public API contract with `API_CONTRACT_VERSION = "1.0"`, automated signature locking against `tests/fixtures/api_contract_v1_0.json`, and package graduation from `Beta` to `Development Status :: 5 - Production/Stable` with `Typing :: Typed`.
- **Promotion of Qualified Surfaces:** Graduated all `0.5.0` candidate symbols in `PUBLIC_API_STABILITY` from `"stable-candidate"` to `"stable"`, including `SharedRedisCacheBackend` and `SharedCoordinationBackend` following `0.6.0` qualification.
- **Runtime Warnings for Pass-Through & Experimental Surfaces:** Added `LongCachePassThroughWarning` (emitted on instantiation/use of `CachedLLM`, `CachedChain`, `CachedQueryEngine`, `CachedState`, `StreamingCacheAdapter`, and `cache.cached_stream`) and `LongCacheExperimentalWarning` (emitted on `AsyncRedisCacheBackend`).
- **Format-2 Persistence Upgrade Guarantee:** Added `tests/test_v1_persistence_compat.py` verifying zero data loss, zero re-indexing, and bit-identical partition digests (`v2:<sha256>`) for upgrading pre-populated SQLite and Redis caches.
- **Release Provenance & SBOM:** Added deterministic CycloneDX 1.5 JSON SBOM generation (`scripts/generate_sbom_v1.py`), `dist/SHA256SUMS.txt` manifests, and release verification via `scripts/verify_release_v1.py`.
- **Support & Migration Documentation:** Published `docs/semver-contract.md` (defining the 1.x stability contract) and `docs/migration-v1.0.md` (0.6.0 to 1.0.0 upgrade guide).

## [0.6.0] - 2026-11-05

### Added
Expand Down
4 changes: 2 additions & 2 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Shared Redis deployment (v0.6 qualification)
# Shared Redis deployment (`stable` in v1.0.0)

The v0.6 qualification milestone validates shared Redis mode for processes connected to one writable Redis authority. It has passed multi-process churn, fail-closed Redis crash/data-loss recovery, and bounded memory index rebuilds. The default remains `single_process`.
Qualified in v0.6.0 and promoted to `stable` in v1.0.0, shared Redis mode connects multiple processes to one writable Redis authority. It has passed multi-process churn, fail-closed Redis crash/data-loss recovery, and bounded memory index rebuilds. The default remains `single_process`.

```python
from longcache import CacheConfig, LongCache, RequestContext, RequestScope
Expand Down
6 changes: 3 additions & 3 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Installation

LongCache v0.6 requires Python 3.11 or newer; Python 3.11 and 3.12 are the tested interpreters. v0.1.1 remains the Python 3.10-compatible line.
LongCache v1.0 requires Python 3.11 or newer; Python 3.11 and 3.12 are the supported and tested interpreters. v0.1.1 remains the legacy Python 3.10-compatible line.

v0.6.0 is the current qualification and hardening milestone. The package-index commands install the available published release; they do not select this development checkout. To install this branch from the repository root:
v1.0.0 is the Stable Foundation release (`Development Status :: 5 - Production/Stable`). To install from a local repository checkout:

```bash
uv sync --locked --extra all --extra dev --extra docs
Expand All @@ -15,6 +15,6 @@ uv pip install longcache
uv pip install 'longcache[openai,server,redis]'
```

The local model downloads weights on first use. Pin `embedder_revision` for a deployment, then cache the weights for offline operation. Custom embedders still use the current core package dependencies. See [upgrading to v0.5](../migration-v0.5.md) and the [support matrix](../support-matrix.md) before upgrading. Compatible format-2 stores from v0.2–v0.4 require no reset. For v0.1.1 stores, follow the separate [legacy migration](../migration-v0.2.md); those stores require a fresh path/generation.
The local model downloads weights on first use. Pin `embedder_revision` for a deployment, then cache the weights for offline operation. Custom embedders still use the current core package dependencies. See [upgrading to v1.0](../migration-v1.0.md), [1.x SemVer contract](../semver-contract.md), and the [support matrix](../support-matrix.md) before upgrading. Compatible Format-2 stores from v0.2–v0.6 require no reset. For v0.1.1 stores, follow the separate [legacy migration](../migration-v0.2.md); those stores require a fresh path/generation.

For the tested CPU runtime, install `torch==2.14.0+cpu` from `https://download.pytorch.org/whl/cpu` before installing the wheel. Installer index settings in the project's lockfile do not become wheel dependency metadata.
Loading
Loading