Skip to content

Commit a07634d

Browse files
docs(release): 📝 v0.7.1 changelog, README updates, and test matrix (#110)
## Summary Documentation sweep to prep for v0.7.1 patch release. Updates changelog, fixes a stale README gotcha, bumps version references, and adds test traceability for the parent-ID caching fix (#109). ## Highlights - **CHANGELOG.md**: Add v0.7.1 entry (Fixed + Added sections), update all comparison links from `justapithecus` → `pithecene-io` org - **README.md**: Fix stale "Metadata must be non-nil" gotcha — nil metadata has been safe since v0.7.0 coalescing; bump status version to v0.7.1 - **CONTRACT_TEST_MATRIX.md**: Add three parent-ID caching test rows (Write, StreamWrite, StreamWriteRecords) for contract traceability ## Test plan - [ ] CHANGELOG entry follows Keep a Changelog format - [ ] Comparison links resolve to pithecene-io/lode - [ ] README gotcha matches v0.7.0 nil coalescing behavior - [ ] Test matrix rows reference existing test names 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7db236e commit a07634d

3 files changed

Lines changed: 33 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
---
1313

14+
## [0.7.1] - 2026-02-09
15+
16+
### Fixed
17+
18+
- **O(n²) write degradation on remote stores**: `Write()`, `StreamWrite()`, and `StreamWriteRecords()` called `Latest()` on every invocation, scanning all manifests via `store.List` + N×`store.Get`. On remote stores (S3, R2), this caused sequential writes to degrade quadratically. A 40-write burst that should complete in <1s took ~40 minutes. Parent snapshot ID is now cached after each successful write; only the first write (cold start) falls back to `Latest()`. ([#109](https://github.com/pithecene-io/lode/pull/109), closes [#108](https://github.com/pithecene-io/lode/issues/108))
19+
20+
### Added
21+
22+
- **Sequential write benchmarks**: `BenchmarkDataset_SequentialWrites` (wall-clock with simulated latency) and `BenchmarkDataset_SequentialWrites_StoreCallCount` (correctness assertion) guard against parent-resolution regressions
23+
24+
### Upgrade Notes
25+
26+
- No API changes; transparent internal optimization
27+
- All write paths (`Write`, `StreamWrite`, `StreamWriteRecords`) benefit automatically
28+
- Safe to upgrade from v0.7.0
29+
30+
---
31+
1432
## [0.7.0] - 2026-02-07
1533

1634
### Added
@@ -312,12 +330,13 @@ Post-v0.3.0 improvements planned:
312330

313331
---
314332

315-
[Unreleased]: https://github.com/justapithecus/lode/compare/v0.7.0...HEAD
316-
[0.7.0]: https://github.com/justapithecus/lode/compare/v0.6.0...v0.7.0
317-
[0.6.0]: https://github.com/justapithecus/lode/compare/v0.5.0...v0.6.0
318-
[0.5.0]: https://github.com/justapithecus/lode/compare/v0.4.1...v0.5.0
319-
[0.4.1]: https://github.com/justapithecus/lode/compare/v0.4.0...v0.4.1
320-
[0.4.0]: https://github.com/justapithecus/lode/compare/v0.3.0...v0.4.0
321-
[0.3.0]: https://github.com/justapithecus/lode/compare/v0.2.0...v0.3.0
322-
[0.2.0]: https://github.com/justapithecus/lode/compare/v0.1.0...v0.2.0
323-
[0.1.0]: https://github.com/justapithecus/lode/releases/tag/v0.1.0
333+
[Unreleased]: https://github.com/pithecene-io/lode/compare/v0.7.1...HEAD
334+
[0.7.1]: https://github.com/pithecene-io/lode/compare/v0.7.0...v0.7.1
335+
[0.7.0]: https://github.com/pithecene-io/lode/compare/v0.6.0...v0.7.0
336+
[0.6.0]: https://github.com/pithecene-io/lode/compare/v0.5.0...v0.6.0
337+
[0.5.0]: https://github.com/pithecene-io/lode/compare/v0.4.1...v0.5.0
338+
[0.4.1]: https://github.com/pithecene-io/lode/compare/v0.4.0...v0.4.1
339+
[0.4.0]: https://github.com/pithecene-io/lode/compare/v0.3.0...v0.4.0
340+
[0.3.0]: https://github.com/pithecene-io/lode/compare/v0.2.0...v0.3.0
341+
[0.2.0]: https://github.com/pithecene-io/lode/compare/v0.1.0...v0.2.0
342+
[0.1.0]: https://github.com/pithecene-io/lode/releases/tag/v0.1.0

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ For full contract details: [`docs/contracts/`](docs/contracts/)
200200

201201
Common pitfalls when using Lode:
202202

203-
- **Metadata must be non-nil**Pass `lode.Metadata{}` for empty metadata, not `nil`.
203+
- **Metadata defaults to empty**`nil` metadata is coalesced to `Metadata{}`; pass `nil` or `Metadata{}` for empty metadata.
204204
- **Raw mode expects `[]byte`** — Without a codec, `Write` expects exactly one `[]byte` element.
205205
- **Single-writer only** — Concurrent writers to the same dataset or volume may corrupt history.
206206
- **Cleanup is best-effort** — Failed streams may leave partial objects in storage.
@@ -309,7 +309,7 @@ Each example is self-contained and runnable. See the example source for detailed
309309

310310
## Status
311311

312-
Lode is at **v0.7.0** and under active development.
312+
Lode is at **v0.7.1** and under active development.
313313
APIs are stabilizing; some changes are possible before v1.0.
314314

315315
If you are evaluating Lode, focus on:

docs/contracts/CONTRACT_TEST_MATRIX.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Gaps are tracked with codes indicating category and priority:
8383
| Creates snapshot | Multiple write tests |
8484
| nil metadata coalesced | `TestDataset_Write_NilMetadata_CoalescesToEmpty` |
8585
| Parent snapshot linked | `TestDataset_StreamWrite_ParentSnapshotLinked` |
86+
| Parent ID cached (O(1) after first write) | `TestDataset_Write_CachesParentSnapshotID` |
8687
| Raw blob RowCount=1 | `TestDataset_StreamWrite_Success` |
8788

8889
**StreamWrite**: All covered ✅
@@ -95,6 +96,7 @@ Gaps are tracked with codes indicating category and priority:
9596
| Abort → no manifest | `TestDataset_StreamWrite_Abort_NoManifest` |
9697
| Close without Commit → abort | `TestDataset_StreamWrite_CloseWithoutCommit_BehavesAsAbort` |
9798
| Codec configured → error | `TestDataset_StreamWrite_WithCodec_ReturnsError` |
99+
| Parent ID cached across StreamWrite→Commit | `TestDataset_StreamWrite_CachesParentSnapshotID` |
98100
| Checksum computed | `TestDataset_StreamWrite_WithChecksum_RecordsChecksum` |
99101
| Manifest Put error → no manifest + cleanup | `TestStreamWrite_ManifestPutError_NoManifest_CleanupAttempted` |
100102
| Abort → cleanup attempted | `TestStreamWrite_Abort_NoManifest_CleanupAttempted` |
@@ -113,6 +115,7 @@ Gaps are tracked with codes indicating category and priority:
113115
| Iterator error → no manifest | `TestDataset_StreamWriteRecords_IteratorError` |
114116
| RowCount = records consumed | `TestDataset_StreamWriteRecords_Success` |
115117
| Iterator error → cleanup attempted | `TestStreamWriteRecords_IteratorError_NoManifest_CleanupAttempted` |
118+
| Parent ID cached across StreamWriteRecords | `TestDataset_StreamWriteRecords_CachesParentSnapshotID` |
116119
| Manifest Put error → no manifest + cleanup | `TestStreamWriteRecords_ManifestPutError_NoManifest` |
117120

118121
**Timestamp Computation**: All covered ✅

0 commit comments

Comments
 (0)