Skip to content

fix(metaserver): remove owner TTL from lifecycle sweep - #2

Closed
GentleCold wants to merge 16 commits into
masterfrom
fix/metaserver-sweep-manual-ttl
Closed

GentleCold wants to merge 16 commits into
masterfrom
fix/metaserver-sweep-manual-ttl

Conversation

@GentleCold

Copy link
Copy Markdown
Owner

Summary

  • Stop periodic lifecycle sweep from deleting owners based on registration age.
  • Add POST /admin/cleanup-expired-blocks for explicit one-hour owner cleanup.
  • Maintain node-to-block reverse indexes and redundancy counters incrementally so stale-node sweeps avoid scanning the full block map.
  • Preserve the 600-second default sweep interval and existing node liveness semantics.

Validation

  • Remote RTX 4090 (192.168.172.117): cargo test -p pegaflow-metaserver (42 passed).
  • Remote RTX 4090: cargo clippy -p pegaflow-metaserver --all-targets -- -D warnings passed.
  • Remote RTX 4090: release MetaServer process smoke test passed; /health returned ok, POST /admin/cleanup-expired-blocks returned valid JSON, and metrics were exposed.

A complete 2P2D GPU workload was not started because the host already had a long-running vLLM workload occupying the GPUs; no existing process was stopped.

xiaguan and others added 16 commits August 12, 2026 16:21
## Summary

- classify `FullAttentionSpec` subclasses as full-attention cache groups
- allow specialized full-attention specs used by the latest Kimi K3 vLLM
release to initialize with aligned Mamba groups
- cover subclass and MLA inheritance behavior in cache-group layout
tests
- bump the workspace and Python package version to `0.23.10` for release

## Testing

- `cd python && uv run --extra test pytest` (256 passed, 13 deselected)
- `cd python && uv run --isolated --no-project --with pytest --with
numpy --with 'requests>=2.26.0' pytest` (256 passed, 13 deselected)
- pre-commit hooks, including `cargo test --release`, Ruff, and
Commitizen checks
- `cargo metadata --locked --no-deps --format-version 1`
- Cargo workspace, Python package, and Commitizen versions verified at
`0.23.10`

## Release

After merge, create and push tag `v0.23.10` to trigger the release
workflow.

## Performance Work

Not a performance change; no benchmark was required.
## Summary

- keep polling an in-flight prefetch with its original query identity
when local prefix hits change
- let TP shard validation check the stale result against the query that
created it
- release stale per-shard leases before issuing the updated query

## Root cause

The scheduler already snapshots `computed_blocks` and query hashes when
`query_prefetch` returns Loading. After TP shard support was added, each
shard validated a later Ready result against the current, shorter query
before the scheduler could compare it with the saved snapshot. A valid
stale result therefore raised `hits > queried blocks` instead of being
discarded.

## Tests

- `cd python && uv run --extra test pytest -q` (257 passed, 13
deselected)
- `cd python && uv run --extra test pytest -q tests/test_tp_shards.py
tests/test_combine_hashes.py` (66 passed)
- commit hooks, including `cargo test --release`, ruff, format, typos,
and Commitizen
…ntion and recurrent layers (novitalabs#433)

## What this changes

End-to-end PegaFlow support for vLLM v1 hybrid KV cache models (full
attention layers mixed with Mamba/KDA/GDN recurrent layers), landed on
top of the group-aware plumbing introduced in recent connector work and
proved out on GB300 (SM100) with Kimi-K3.

Before this, every engine-side keying decision assumed a single cache
group: group 0's content hashes addressed all segments, so recurrent
groups were never saved, and a warm restore for a hybrid model could
only answer attention hash queries. This patch teaches the whole stack
about
cache groups:

### Engine (`feat(core)`)

- `pegaflow-common::block::group_hash` encodes a block content hash with
  its vLLM cache-group id. Group 0 stays byte-identical to the raw hash,
  so all existing single-group deployments produce exactly the same
  block keys as before.
- `RegisterContextRequest` now carries `layer_group_ids`; the instance
  registry seals a per-group layer set and slot topology and refuses to
  serve instances whose workers disagree about group layout.
- Read cache, write path, layup and offload all carry explicit group
  ids; slot derivation dedupes per group instead of per layer.
- `QueryRequest.group_id` selects semantics: group 0 keeps the existing
  prefix query, other groups answer sparse-checkpoint membership
  queries. Membership results do not feed remote RDMA fetch in this
  release (see Limitations).
- gRPC service routes save fan-out and per-(slot, hash) reports so the
  connector can place recurrent checkpoints where its membership leases
  require.

### Connector (`feat(connector)`)

- Every group's block hashes are derived from the same prefix hash chain
  (group id + checkpoint-offset/private-salt emptiness mixed in) so a
  restore is only counted as a hit when every group's data can come back
  together. Group 0 provides prompt-layout blocks; recurrent groups
  provide sparse checkpoints at per-model-config positions, including
  the final HMA blocks (`fix(connector): save final HMA cache blocks`).
- `_reconcile_hybrid` combines per-group answers into the longest fully
  restorable prefix; a partial reconcile is dropped entirely rather than
  restored with stale recurrent context.
- Save/load intents keep per-group slot positions and write recurrent
  groups under their own hash namespaces inside the same request flow.
- TP shard topology now accepts an explicit
  `pegaflow.tp_shard_endpoints` list so rank-to-server mapping no longer
  depends on every server being reachable at the same host:port pattern;
  without it the previous deterministic default layout is preserved.

## Verification

- New coverage: `pegaflow-core/tests/hybrid_groups.rs`,
  instance-slot sealing tests for multi-group topologies, and
  `python/tests/test_hybrid_reconcile.py` for the reconcile/drop/final-
  block contracts. All existing engine, connector and fault-tolerance
  gates pass unmodified (`prek run` green: fmt, clippy, release-profile
  tests, ruff, typos).
- Cluster validation on GB300 (SM100, aarch64): Kimi-K3 (MLA + KDA),
  6 `xingming-k3-debug` LWS groups of TP8x2 with per-tray
  `pegaflow-server` shards (`550gb` hugepage pools each). Under Kimi
  production prefill traffic, port 8001 shows 24/24-25/25 layout
  block hits after a cold pass (TTFT 4.9s -> 1.7s for a ~39K-token
  prompt), and pooled saves/loads run at multi-TB/hour overnight with
  `pegaflow_cache_block_hits`-driven throughput scaling as expected.

## Limitations

- The vLLM connector's reconcile keeps using the local membership form:
  its sparse queries stay resident-cache-only, so hybrid models still
  recompute after local eviction of recurrent checkpoints. Engine-side
  the limitation is closed: `wait_for_full_prefix` on a group > 0 query
  selects an all-or-nothing set fetch that routes misses through the
  same SSD prefetch and MetaServer + RDMA machinery as prefix queries
  (the want-set either completes or reports short, which callers treat
  as a miss) — the form a prefill/decode handoff consumer needs. Wiring
  the connector's warm-restore path onto it is follow-up work.

## Test plan

- `cargo test --workspace --no-default-features --features cuda-13,rdma`
- `cd python && uv run --extra test pytest`
- `python/tests/test_vllm_e2e_correctness.py -m e2e` (hybrid model,
  GB300 cluster): cold -> warm verify loop with `hit_blocks` matching
  the full layout block count.

---------

Co-authored-by: xiaguan <rsh56dwgsw@privaterelay.appleid.com>
## Summary

- reclaim only cache entries exclusively owned by the resident cache
- keep leased, queried, loading, and weakly referenced blocks indexed
during memory pressure
- preserve reclaimable-before-retained ordering with a bounded LRU scan
- strengthen the GPU eviction integration test to prove an unleased
batch is reclaimed while a leased batch remains queryable and loadable

## Testing

- `cargo test --no-default-features --features cuda-13,rdma -p
pegaflow-core storage::read_cache::tests -- --nocapture`
- `cargo test --no-default-features --features cuda-13,rdma -p
pegaflow-core --test eviction -- --nocapture`
- `cargo clippy --workspace --all-targets --no-default-features
--features cuda-13,rdma -- -D warnings`
- `prek run` (includes release-mode Rust test suite)

Signed-off-by: xiaguan <751080330@qq.com>
## Summary

- bump the Rust workspace packages to `0.23.12`
- bump the Python package and Commitizen version to `0.23.12`
- refresh the workspace package versions in `Cargo.lock`

## Validation

- `cargo metadata --locked --no-deps --format-version 1`
- `prek run` (includes Clippy and release-mode Rust tests)

Signed-off-by: xiaguan <751080330@qq.com>
## Summary

- Treat only additional strong `Arc<SealedBlock>` owners as
pressure-eviction pins.
- Allow SSD write-queue `Weak<SealedBlock>` references to yield to
memory pressure, preserving the existing fire-and-forget SSD contract.
- Add regression coverage for weak-only eviction and strong-reference
retention.

## Validation

Ran on RTX 4090 / Linux with CUDA 13 and RDMA enabled:

- `cargo fmt --all -- --check`
- `cargo test --no-default-features --features cuda-13,rdma -p
pegaflow-core storage::read_cache::tests -- --nocapture` (22 passed)
- `cargo clippy --workspace --all-targets --no-default-features
--features cuda-13,rdma -- -D warnings`
- `cargo test --no-default-features --features cuda-13,rdma -p
pegaflow-core --test eviction -- --nocapture --test-threads=1` (3
passed)

The existing `ssd_cache` integration suite was also attempted on the
4090 host, but its fixed 32 KiB test pool is split across the host's
NUMA-local pools and exhausts before the first save; all 11 failures are
`pinned pool exhausted`, before SSD assertions run.
## Summary

- Increase the default local HLL size from `bucket_bits=14` (16,384
registers) to `16` (65,536 registers), reducing the theoretical standard
error from about 0.8% to about 0.4%.
- Record only the final miss suffix in HLL cardinality while keeping all
queried blocks in `pegaflow_hll_total_requests`.
- Add `pegaflow_hll_estimated_hit_rate`, calculated and clamped in the
tracker, while retaining the existing cardinality and total metrics and
labels.
- Use stable `(namespace, block hash)` identities so local measurements
do not collide across namespaces.
- Update the metrics documentation and default windows to `15m,1h,1d`.

## Compatibility

This is not an `/metrics` protocol breaking change: the HTTP endpoint,
existing metric names, types, and labels remain available. The new gauge
is additive. The existing PromQL remains valid, but the HLL cardinality
semantics are now explicitly miss-only and the default precision is
higher.

MetaServer HLL aggregation, heartbeat, protobuf, and MetaServer metrics
are intentionally excluded and will be handled by a follow-up PR.

## Validation

- `cargo fmt --all -- --check`
- `cargo test -p pegaflow-common` (34 passed)
- `git diff --check`

Server compilation could not complete on the macOS development host
because the workspace's Linux-only `io-uring`/CUDA dependencies require
Linux headers/toolchains; Linux CI remains the authoritative server
build check.
## Summary

- Fix `ConnectorContext.virtual_block_size` to match vLLM's scheduler
block-hash granularity.
- Keep DCP in the virtual block size, but do not multiply by PCP.
- Update unit coverage for PCP-only and DCP+PCP configurations.

Fixes novitalabs#428.

## Why

vLLM scheduler block hashes use `block_size * dcp`; prefill context
parallelism changes rank ownership, not token granularity. Pegaflow
currently multiplies by `pcp_world_size` as well, making the expected
block size 8x too large with PCP8 and causing the first prefix-cache hit
to fail. PCP deployments currently work around this with a startup `sed`
patch; this makes the behavior native to Pegaflow.

## Duplicate-work check

- Checked issue novitalabs#428 and open PRs for `428`, `PCP`, `context parallel`,
and `virtual_block_size`.
- No open PR covering this fix was found.

## Tests

- `UV_CACHE_DIR=/tmp/pegaflow-uv-cache uv run --isolated --no-project
python -c '...'` (syntax compilation passed)
- `git diff --check` (passed)
- Full pytest could not run because the environment cannot resolve
`pypi.org` to install test dependencies.

AI assistance was used to prepare this change; human review is required
before merge.
## Summary

- replace the single-owner prefix result with an ordered `FetchSegment`
plan that covers the longest contiguous remote prefix
- exclude the requester from owner candidates and greedily choose the
owner that reaches the farthest from each offset, with a stable
node-name tie break
- validate and fetch segments serially in core; stop immediately on the
first short read or RDMA failure, keep the already fetched contiguous
prefix, and do not retry another owner or query MetaServer again
- preserve the single-owner fast path as one segment and add per-segment
block counts to the fetch summary log
- reserve the old protobuf response field so mixed-version deployments
degrade to a cache miss instead of misinterpreting the payload

## Why

In multi-turn workloads, an older prefix segment may survive only on one
remote P node while a newer segment is stored on another. The previous
API selected only one owner, so the requester could fetch the first
segment but had to recompute the rest even though the full prefix
existed across nodes.

## Validation

Executed on `192.168.172.117` with CUDA 13 and RDMA:

- `cargo fmt --all -- --check`
- `cargo test -p pegaflow-metaserver`: 38 passed
- `cargo test -p pegaflow-core rdma_fetch --no-default-features
--features cuda-13,rdma`: 8 passed
- `cargo test -p pegaflow-core metaserver_client --no-default-features
--features cuda-13,rdma`: 9 passed
- `cargo test -p pegaflow-proto`: passed
- `cargo clippy -p pegaflow-core -p pegaflow-metaserver --all-targets
--no-default-features --features cuda-13,rdma -- -D warnings`
- `cargo build --release --no-default-features --features cuda-13,rdma`

The full core run passed 157/157 non-GPU unit tests and the integration
suites reached `ssd_cache`; those 11 tests failed during harness setup
with `pinned pool exhausted`. The same single test fails identically in
the baseline workspace on this host, so it is an environment condition
rather than a feature regression.

## 6P2D E2E evidence

Real fragmented multi-turn A/B, Qwen3-4B, 6P2D, 128-token blocks, 8
active conversations, no HTTP retry:

| Metric | Baseline | Feature |
| --- | ---: | ---: |
| Target RDMA blocks | 20/42 | 42/42 (20+22) |
| Target hit ratio | 47.6% | 100.0% |
| Mean target TTFT | 2776.2 ms | 2123.6 ms |
| Whole-workload hit ratio | 48.6% | 53.6% |

All four paired target requests returned HTTP 200 with identical prompt
hashes. The feature recovered 88 additional RDMA blocks, avoided
recomputing 88 blocks, and reduced mean target TTFT by 652.6 ms (23.5%).

A separate fixed-transcript 96 conversations x 12 turns run also used
identical prompts and exercised many multi-segment plans. Its aggregate
hit ratio was effectively flat (74.9645% vs 74.9586%) because
target-path requests were diluted by 1152 total requests; median TTFT
improved from 5019.7 ms to 4713.1 ms, while tail latency remained noisy.
The fragmented paired A/B above isolates the mechanism without synthetic
cache operations or retries.

Private benchmark harness and artifacts remain under `.local/` and are
intentionally not part of this PR.
## Summary

- Replace one whole-batch SSD prefetch slab per NUMA node with bounded
256 MiB staging chunks.
- Preserve per-slot NUMA placement, slot ordering, oversized-slot
handling, and the existing all-or-nothing batch allocation contract.
- Add a representative multi-group regression shape that verifies the
allocation bound.

## Production evidence before this change

Observed on one GB300 4-GPU node running a hybrid multi-group workload:

| Metric | Observed value |
| --- | ---: |
| SSD-prefetched data | 83 blocks / 8.52 GB |
| Largest contiguous staging request | 3.5 GiB per NUMA node |
| Cache blocks evicted | 4,608 |
| Logical cache bytes evicted | 415.6 GiB |
| Allocator bytes reclaimed | 462.8 GB |
| Pinned-pool usage | 484.5 GB -> 30.2 GB |

The allocator reclaims until its largest free extent can satisfy the
request. A multi-GiB whole-batch slab therefore turns fragmentation into
a large eviction burst. This is the SSD equivalent of the RDMA staging
issue addressed by novitalabs#387.

## Allocation-shape A/B

The deterministic multi-group regression uses 56 blocks with eight 16
MiB slots split evenly across two NUMA nodes:

| Allocation shape | Baseline | This PR |
| --- | ---: | ---: |
| Bytes staged per NUMA | 3.5 GiB | 3.5 GiB |
| Maximum contiguous allocation | 3.5 GiB | 256 MiB |
| Allocations per NUMA | 1 | 14 |
| Slots preserved | 224 | 224 |

This establishes the allocation bound. Runtime eviction and hit-ratio
impact still need to be re-measured after deployment.

## Validation

- `cargo fmt --all -- --check`
- `cargo clippy -p pegaflow-core --all-targets --no-default-features
--features cuda-13,rdma -- -D warnings`
- `cargo test -p pegaflow-core --no-default-features --features
cuda-13,rdma -- --test-threads=1` (154 passed, 1 existing GPU-only test
ignored)
- `prek run`

---------

Signed-off-by: xiaguan <751080330@qq.com>
…ovitalabs#441)

## Summary
- Hybrid (HMA) requests now skip mid-flight saves and emit a single
recurrent checkpoint from `request_finished`.
- That checkpoint is resolved through vLLM's committed prefix cache
instead of the live align-mode block table, which otherwise stores a
mid-block running state or a speculative draft block under the wrong
hash.
- Regression tests build the recurrent table with vLLM's align-mode
formulas and encode provenance in block ids so a wrong save is visible.

This is not duplicating an existing PR: the 5090 exploration session
never landed a commit or PR.

## Test plan
- [x] `cd python && uv run --extra test pytest` — 278 passed, 13
deselected
- [x] `tests/test_hma_checkpoint_index.py` — 9 cases (mid-block /
aligned / speculative, plus skip-when-stored and new-boundary-only)
- [x] Local Qwen3.5-4B GPU invariant script
(`logs/k3-hma/verify_hma_invariants.py`): vbs=528, mid-block keys last
committed boundary, short skip, warm hit no re-save with matching greedy
text, prefix-extend files only the new boundary, independent miss,
two-block checkpoint at 1056
- [x] `pytest -m e2e tests/test_vllm_e2e_correctness.py --model
/data/models/Qwen3.5-4B --max-model-len 4096` — 5 passed (9m30s);
same-process HMA load used PegaFlow; no data-path RPC / KV load failures

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary

- bump the Rust workspace packages to `0.24.0`
- bump the Python package and Commitizen version to `0.24.0`
- refresh the workspace package versions in `Cargo.lock`

## Validation

- `cargo metadata --locked --no-deps --format-version 1`
- `prek run` (includes Clippy and release-mode Rust tests)

Signed-off-by: xiaguan <751080330@qq.com>
novitalabs#448)

## Problem

On hybrid models (Kimi-K3 / Kimi-Linear: KDA recurrent state + MLA
attention) the PegaFlow connector's hit rate on agent workloads is far
below the Mooncake store connector's, and it is not a capacity issue.
The connector stored **one** recurrent checkpoint per request, at
`request_finished`, taken from whatever boundary block vLLM still had
cached. Agent traffic shares a system prompt across sessions and
branches mid-history, so the shared prefix almost never ends at that
single checkpoint. `reconcile_hybrid_hit` then finds the attention pages
but no usable recurrent state and logs

```
[PegaKVConnector] req=... HMA attention prefix of N blocks has no common recurrent checkpoint; recomputing instead
```

i.e. a 0-block hit on exactly the traffic Mooncake serves from the
second session on. (novitalabs#444 does not address this; it only restores local
hits.)

## Fix

Store recurrent states the way vLLM offers them (same hand-off the
Mooncake connector consumes since vllm-project/vllm#51358):

- **Per-boundary saves.** Consume
`SchedulerOutput.kv_connector_block_state.boundary_state_offloads` every
step. Each `(group, block, boundary_tokens)` entry becomes a boundary
save job filed under the request hash ending at that boundary: chunk
ends, internal prefill checkpoints, every block crossed while decoding.
The block is pinned in the GPU block pool (`pool.touch`) until every
worker reports the job via the new `PegaWorkerMetadata`
(`KVConnectorWorkerMetadata.aggregate` across TP), so the save is
decoupled from the request's block lifetime; `has_pending_push_work`
keeps the engine stepping while jobs are in flight. HMA now requires a
vLLM with this hand-off and fails loudly without it.
- **Attention pages save mid-flight** at the normal per-block cadence
with recurrent rows nulled; recurrent blocks are never saved
positionally from the connector's table mirror. Request saves run
asynchronously again (the synchronous D2H in `wait_for_save` is gone).
- **Junction hint.** When the external attention prefix runs past the
last usable checkpoint, set `Request.shared_prefix_boundary` so vLLM
stops the prefill chunk there and commits (and hands off) the state at
the end of the shared prefix. The first sharer recomputes once; every
later sharer resumes.

The first commit is a prerequisite for running on current vLLM main at
all: vLLM now allocates one KV buffer and hands each layer a strided
`[B, H, N, C]` view at a nonzero storage offset, which registration
rejected (zero-offset assertion; MLA split ratio read from the head
axis).

## Verification

Kimi-Linear-48B-A3B-Instruct, single GB300, vLLM main (2026-09-01
nightly, 1920-token blocks, mamba `align`), `pegaflow-server` 40 GiB
pool, greedy decoding. Prompts share a ~10.5k-token system prefix `S` (5
full blocks); E/F share only the first ~4.3k tokens of `S` (2 full
blocks) and then diverge for ~3k unique tokens, so their common prefix
ends where no earlier checkpoint exists.

| request | master | this PR |
|---|---|---|
| A cold | 0 / 5 blocks | 0 / 5 |
| A' exact repeat | 5 | 5 |
| B, C sharers of full `S` | 5 | 5 |
| D next turn of A | 5 | 5 |
| E first sharer of the 2-block prefix | 0 (`no common recurrent
checkpoint`) | 0 (`no common recurrent checkpoint`, junction committed)
|
| **F second sharer of the 2-block prefix** | **0** (`no common
recurrent checkpoint`) | **2 / 2 blocks** |

Greedy output of A' equals A in both runs; no load/save failures;
`pegaflow_cache_block_hits_total` matches the per-request hit counts.

Unit gate: `uv run --isolated --no-project --with pytest --with numpy
--with 'requests>=2.26.0' pytest` → 288 passed. New
`tests/test_hma_boundary_offloads.py` covers pinned saves and release
across workers, worker-meta aggregation, unusable/duplicate hand-offs,
attention-only mid-request saves, and the junction hint.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_016pSeF3SWkaeomAW4GQ7M6z

---------

Signed-off-by: JinYan Su <751080330@qq.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
… table (novitalabs#449)

## Summary

Production K3 (TP8, MTP, PegaFlow master with novitalabs#448) hit this on every
attention layer once KV pressure started preempting requests:

```
RuntimeError: save block/hash count mismatch for language_model.model.layers.3.self_attn: blocks=1 hashes=10
```

- **Root cause** (`scheduler.py::_consume_full_block_saves`): the save
window was bounded by `base_block_idx + len(table)`, but the mirrored
table already contains the externally loaded prefix, so the external
offset was counted twice. It stayed masked while the scheduled-token
accumulator only covered the current life. After a preemption vLLM
resets `num_computed_tokens` and rebuilds the table from the resume
chunk, while the accumulator and the first life's offset stay: the
window runs past the rebuilt table, Python slicing silently shortens the
block IDs, and the prompt hashes (known up front) are not shortened. In
save-only mode the same stale watermark could save a partially
recomputed block under a valid hash.
- **Fix**: bound the window by the table itself; on resume restart the
per-request bookkeeping from the refreshed external hit
(`_rebase_resumed_request`), keeping already-stored progress.
- **Blast radius fix** (`worker.py`): the raise killed the save thread,
so nothing drained the queue afterwards, every later request stayed held
for a save that never completed, and the engine leaked KV cache until
restart (2 running / 18 waiting / 2 tok/s in the incident). The save
worker now survives a failing batch, a malformed intent drops only its
own request's save, and completion is always reported so blocks get
released.
- **Second bug, found while reproducing under preemption on
Kimi-Linear** (`scheduler.py::_load_block_ids_by_group`): the load's
destination vector was sized by the *usable* hit, but the engine walks
it in lock step with the query lease. When the hybrid reconcile fell
back to an earlier checkpoint (an exact-repeat prompt whose final token
must be recomputed), the load carried one target fewer than the lease
and the engine rejected it with `query lease block count 5 does not
match destination block count 4`, which the worker escalated to "Service
unavailable" and the engine died. The probe now keeps the leased block
count and the load pads unwanted leased blocks with `None` targets
(already skipped by the engine).
- Bumps the version to 0.24.2.

## Test plan

- [x] `tests/test_save_intent_preempt_resume.py`: the production shape
(19-block prompt, 9 loaded, preempted after a sub-block chunk, resumed)
plus save-only partial-block and rebase cases. All 5 fail on master,
pass here.
- [x] `tests/test_connector_save_lifecycle.py`: malformed intent is
skipped and the request still completes; save worker survives a failing
batch.
- [x]
`tests/test_hma_boundary_offloads.py::test_load_targets_cover_every_leased_block_when_the_hit_shrinks`:
fails on master, passes here.
- [x] `cd python && uv run --isolated --no-project --with pytest --with
numpy --with 'requests>=2.26.0' pytest` on the connector suites (109
passed), ruff check/format clean.
- [x] Single-GPU Kimi-Linear e2e (tray08, 512 GiB pool, 400-block GPU KV
budget to force preemption, 2048-token chunks): master died on the
lease/destination mismatch under a warm-prefix + 96 long-decode fillers
+ long-tail scenario; this branch completes 3 rounds (294 requests, 3908
preemptions, 0 save mismatches, 0 load failures). Multi-turn vllm-bench
load (128 conv, 3 turns, 2000+ preemptions) is clean on both. The exact
save-mismatch sequence from production was not reproduced e2e on this
model (its resume hits cover everything stored, so the rebuilt table is
never shorter than the hashes); the unit test pins that shape.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01SXoijrttVSfhrQF6EAq5CC

---------

Signed-off-by: JinYan Su <751080330@qq.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@GentleCold GentleCold closed this Sep 9, 2026
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.

3 participants