Repository navigation
Conversation
`promote` no longer re-reads a manifest staged by the same `PartWriteTxn`, so the "body-absent precommit is rejected" contract now applies only to manifests not staged there. Also document that `staged_manifest_proofs` entries must never be erased, because `precommitAdd` uses them as the A3 barrier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extract `blobDependenciesOf` so `stageManifest` and the non-staged path of `promote` use the same filter. Cleanup of staged manifests now logs at debug level when the exact-incarnation remove returns `Gone` or `Mismatch`, or throws, instead of silently swallowing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a test that promotes its own staged manifest with Inline and Blob entries: it fails with `no dependency proof` while one blob is missing, then commits without a manifest read. Add a test that `abandon` keeps the live precommit body and removes another staged manifest without `HEAD`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The record only says what a confirmed put-if-absent returned in `stageManifest`. It does not prove that the body still exists at `promote` time, so "proof" overstated it. Rename the member to `staged_manifests` and say "record" in the docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The blob dependencies of a `StagedManifest` keep the order the caller passed the entries, which can differ from the path-sorted encoded body. `promote` does not detect a staged body removed outside the protocol; the read path and `fsck` report it later. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add `FixRecheckAfterFloor` (cut C, floor on every key, owner view, catalog re-read C' for rowless candidates), `ViewByCutLife` (owner view replays the life C named), `PromoteSkipsOwnBodyReread` and the candidate `RecheckLifeChange`. - `fix_recheck_norebirth`, `fix_recheck_noreread_norebirth`: green. - `sab_recheck`: `INV_NO_DANGLE`. - `fix_recheck`: `INV_NO_DANGLE` when the namespace is removed and reborn between C and the floor read; `fix_recheck_life` closes it (green). - `fenced_late_bound_recheck` green, `fenced_late_unbounded_recheck` red: the late-request residual is unchanged. Related: Altinity#2528 Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Reproduce a namespace changing incarnation after the sweep catalog cut. The old owner view is empty while the successor life commits the same manifest, so the stale candidate must be retained.
A namespace can change incarnation after the sweep catalog cut while the successor life commits the candidate manifest. Recheck every candidate row by full value and retain it when the catalog life changed.
PR #2528 Audit Review
VerdictNo High-severity defect. The central safety argument holds, and the orphan-sweep change that makes it hold is the right companion fix. Two Medium findings about what the pool leaks and what it no longer detects, and four Low findings. What the change does
The PR replaces it with a proof the writer already holds. A successful Two things fall out of the same record:
Model
The central argument, and why it holdsTrusting an in-memory proof needs exactly one thing: nothing in the protocol may delete a staged The PR earns this by moving the floor gate in A live build cannot be covered by the floor. The second half of the sweep change covers the window the first half opens. The floor read now
I checked the other deletion paths — FindingsRecovery and rollbackMedium: pre-precommit manifest debris becomes permanently unreclaimable when the server root has no
Partial and gray failureMedium: an out-of-protocol body deletion now produces a committed ref to a missing manifest instead
Backpressure and resource limitsLow: rowless namespaces now consume the per-page namespace work budget.
Low: per-transaction memory now scales with staged entries.
Observability and diagnosabilityLow: the GC side pays back part of the writer-side saving, and the PR does not measure it.
Low: blob dependency checks run in caller order, not path-sorted order.
Checked and clean
Test gapEvery new test is unit-level and single-threaded. The invariant the PR actually rests on — a sweep A regression test in this repository's CAS suite would be the natural home: run an insert-heavy |
|
The CAS-36 sweep race happened in CI. It left a dangling ref after a successful Evidence
Sequence
Impact beyond the lost part
Why a923533 covers it
Not caused by #2614
CAS-36 spec §2.2 says this race fails closed at the final commit step. That is wrong: the sweep plans before the row exists and deletes after the commit. I will fix §2.2 and cite this run. |
1'000 parts were inserted:
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Reduced CAS object storage requests by reusing the proof recorded when a manifest is staged. Promotion no longer reads the manifest back, and cleanup deletes abandoned staged manifests using the recorded incarnation without a preliminary HEAD request.
Fixed a race between CAS manifest staging and orphan cleanup that could delete a committed manifest and leave a dangling reference.
Documentation entry for user-facing changes
...
CI/CD Options
Exclude tests:
Regression jobs to run: