You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+14-2Lines changed: 14 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,10 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
8
-
## [Unreleased]
8
+
## [13.0.0] — 2026-03-03
9
+
10
+
### Added
11
+
12
+
-**Observer API stabilized (B3)** — `subscribe()` and `watch()` promoted to `@stability stable` with `@since 13.0.0` annotations. Fixed `onError` callback type from `(error: Error)` to `(error: unknown)` to match runtime catch semantics. `watch()` pattern param now correctly typed as `string | string[]` in `_wiredMethods.d.ts`.
13
+
-**`graph.patchMany()` batch patch API (B11)** — applies multiple patch callbacks sequentially. Each callback sees state from prior commits. Returns array of commit SHAs. Inherits reentrancy guard from `graph.patch()`.
14
+
-**Causality bisect (B2)** — `BisectService` performs binary search over a writer's patch chain to find the first bad patch. CLI: `git warp bisect --good <sha> --bad <sha> --test <cmd> --writer <id>`. O(log N) materializations. Exit codes: 0=found, 1=usage, 2=range error, 3=internal.
9
15
10
16
### Changed
11
17
18
+
-**BREAKING: `getNodeProps()` returns `Record<string, unknown>` instead of `Map<string, unknown>` (B100)** — aligns with `getEdgeProps()` which already returns a plain object. Callers must replace `.get('key')` with `.key` or `['key']`, `.has('key')` with `'key' in props`, and `.size` with `Object.keys(props).length`. `ObserverView.getNodeProps()` follows the same change.
12
19
-**GraphPersistencePort narrowing (B145)** — domain services now declare focused port intersections (`CommitPort & BlobPort`, etc.) in JSDoc instead of the 23-method composite `GraphPersistencePort`. Removed `ConfigPort` from the composite (23 → 21 methods); adapters still implement `configGet`/`configSet` on their prototypes. Zero behavioral change.
13
20
-**Codec trailer validation extraction (B134, B138)** — created `TrailerValidation.js` with `requireTrailer()`, `parsePositiveIntTrailer()`, `validateKindDiscriminator()`. All 4 message codec decoders now use shared helpers exclusively. Patch and Checkpoint decoders now also perform semantic field validation (graph name, writer ID, OID, SHA-256) matching the Audit decoder pattern. Internal refactor for valid inputs, with stricter rejection of malformed messages.
14
21
-**HTTP adapter shared utilities (B135)** — created `httpAdapterUtils.js` with `MAX_BODY_BYTES`, `readStreamBody()`, `noopLogger`. Eliminates duplication across Node/Bun/Deno HTTP adapters. Internal refactor, no behavioral change.
@@ -25,6 +32,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
32
-**Fake timer lifecycle (B131)** — moved `vi.useFakeTimers()` from `beforeAll` to `beforeEach` and `vi.useRealTimers()` into `afterEach` in `WarpGraph.watch.test.js`.
26
33
-**Test determinism (B132)** — seeded `Math.random()` in benchmarks with Mulberry32 RNG (`0xDEADBEEF`), added `seed: 42` to all fast-check property tests, replaced random delays in stress test with deterministic values.
27
34
-**Global mutation documentation (B133)** — documented intentional `globalThis.Buffer` mutation in `noBufferGlobal.test.js` and `crypto.randomUUID()` usage in `SyncAuthService.test.js`.
35
+
-**Code review fixes (B148):**
36
+
-**CLI hardening** — added `--writer` validation to bisect, SHA format regex on `--good`/`--bad`, rethrow ENOENT/EACCES from test command runner instead of swallowing.
37
+
-**BisectService cleanup** — removed dead code, added invariant comment, replaced `BisectResult` interface with discriminated union type, fixed exit code constant.
38
+
-**Prototype-pollution hardening** — `Object.create(null)` for property bags in `getNodeProps`, `getEdgeProps`, `getEdges`, `buildPropsSnapshot`; fixed indexed-path null masking in `getNodeProps`.
39
+
-**Docs housekeeping** — reconciled ROADMAP inventory counts (24→29 done), fixed M11 sequencing, removed done items from priority tiers, fixed stale test vector counts (6→9), corrected Deno test name, moved B100 to `### Changed`.
28
40
29
41
## [12.4.1] — 2026-02-28
30
42
@@ -1528,7 +1540,7 @@ Implements [Paper III](https://doi.org/10.5281/zenodo.17963669) (Computational H
1528
1540
1529
1541
#### Query API (V7 Task 7)
1530
1542
-**`graph.hasNode(nodeId)`** - Check if node exists in materialized state
1531
-
-**`graph.getNodeProps(nodeId)`** - Get all properties for a node as Map
1543
+
-**`graph.getNodeProps(nodeId)`** - Get all properties for a node (returns `Record<string, unknown>` since v13.0.0)
1532
1544
-**`graph.neighbors(nodeId, dir?, label?)`** - Get neighbors with direction/label filtering
1533
1545
-**`graph.getNodes()`** - Get all visible node IDs
1534
1546
-**`graph.getEdges()`** - Get all visible edges as `{from, to, label}` array
-**JSDoc total coverage** — eliminated all unsafe `{Object}`, `{Function}`, `{*}` type patterns across 135 files (190+ sites), replacing them with precise inline typed shapes.
14
-
-**Zero tsc errors** — fixed tsconfig split-config includes and type divergences; 0 errors across all three tsconfig targets.
15
-
-**JSR dry-run fix** — worked around a deno_ast 0.52.0 panic caused by overlapping text-change entries for duplicate import specifiers.
16
-
-**`check-dts-surface.js` regex fix** — default-export parsing now correctly captures identifiers instead of keywords for `export default class/function` patterns.
13
+
-**BREAKING: `getNodeProps()` returns `Record<string, unknown>`** — aligns with `getEdgeProps()`. Replace `.get('key')` with `.key`, `.has('key')` with `'key' in props`, `.size` with `Object.keys(props).length`.
14
+
-**BREAKING: Removed `PerformanceClockAdapter` and `GlobalClockAdapter`** — use `ClockAdapter` directly.
15
+
-**`graph.patchMany()`** — batch multiple patches sequentially; each callback sees prior state.
16
+
-**`git warp bisect`** — binary search over writer patch history to find the first bad commit. O(log N) materializations.
17
+
-**Observer API stable** — `subscribe()` and `watch()` promoted to stable with `@since 13.0.0`.
18
+
-**`BisectService`** — domain service exported for programmatic use.
17
19
18
20
See the [full changelog](CHANGELOG.md) for details.
19
21
@@ -183,7 +185,7 @@ Query methods auto-materialize by default. Just open a graph and start querying:
-**Status:**`DONE` (spec existed; implementation completed in M11)
29
29
30
30
**Items:**
31
31
32
-
-**B2 (spec only)** (CAUSALITY BISECT) — design the bisect CLI contract + data model. Commit spec with test vectors. Full implementation deferred to M11 — but the spec lands here so bisect is available as a debugging tool during M10 trust hardening.
32
+
-**B2 (spec only)**✅ (CAUSALITY BISECT) — Spec committed at `docs/specs/BISECT_V1.md`. Full implementation shipped in M11/v13.0.0.
33
33
34
34
**M10 Gate:** Signed ingress enforced end-to-end; trust E2E receipts green; B63 GC isolation verified under concurrent writes; B64 sync payload validation green; B65 divergence logging verified; B2 spec committed with test vectors.
**Objective:** Ship bisect, public observer API, and batch patch ergonomics.
172
-
**Triage date:** 2026-02-17
173
-
174
-
### M11.T1 — Causality Bisect (Implementation)
175
-
176
-
-**Status:**`PENDING`
177
-
178
-
**Items:**
179
-
180
-
-**B2 (implementation)** (CAUSALITY BISECT) — full implementation building on M10 spec. Binary search for first bad tick/invariant failure. `git bisect` for WARP.
181
-
182
-
### M11.T2 — Observer API
183
-
184
-
-**Status:**`PENDING`
185
-
186
-
**Items:**
187
-
188
-
-**B3** (OBSERVER API) — public event contract. Internal soak period over (shipped in PULSE, used internally since). Stabilize the public surface.
189
-
190
-
### M11.T3 — Batch Patch API
191
-
192
-
-**Status:**`PENDING`
193
-
194
-
**Items:**
195
-
196
-
-**B11** (`graph.patchMany(fns)` BATCH API) — sequence multiple patch callbacks atomically, each seeing the ref left by the previous. Natural complement to `graph.patch()`.
| B36 |**FLUENT STATE BUILDER FOR TESTS** — `StateBuilder` helper replacing manual `WarpStateV5` literals |
@@ -229,7 +201,7 @@ Items picked up opportunistically without blocking milestones. No milestone assi
229
201
| B79 |**WARPGRAPH CONSTRUCTOR LIFECYCLE DOCS** — document cache invalidation strategy for 25 instance variables: which operations dirty which caches, which flush them. From B-AUDIT-16 (TSK TSK). **File:**`src/domain/WarpGraph.js:69-198`|
230
202
| B80 |**CHECKPOINTSERVICE CONTENT BLOB UNBOUNDED MEMORY** — iterates all properties into single `Set` before tree serialization. Stream content OIDs in batches. From B-AUDIT-10 (JANK). **File:**`src/domain/services/CheckpointService.js:224-226`|
231
203
| B81 |**`attachContent` ORPHAN BLOB GUARD** — `attachContent()` unconditionally writes blob before `setProperty()`. Validate before push to prevent orphan blobs. From B-CODE-2. **File:**`src/domain/services/PatchBuilderV2.js`|
232
-
| B146 |**UNIFY `CorePersistence` / `FullPersistence` TYPEDEFS** — `CorePersistence` (`WarpPersistence.js`) and `FullPersistence`(`WarpGraph.js`) are identical `CommitPort & BlobPort & TreePort & RefPort` intersections. Consolidate into one canonical typedef and update all import sites. From B145 PR review. |
| B147 |**RFC FIELD COUNT DRIFT DETECTOR** — script that counts WarpGraph instance fields (grep `this._` in constructor) and warns if design RFC field counts diverge. Prevents stale numbers in `warpgraph-decomposition.md`. From B145 PR review. |
234
206
235
207
### CI & Tooling Pack
@@ -299,7 +271,7 @@ Items parked with explicit conditions for promotion.
299
271
| B20 |**TRUST RECORD ROUND-TRIP SNAPSHOT TEST**| Promote if trust record schema changes |
300
272
| B21 |**TRUST SCHEMA DISCRIMINATED UNION**| Promote if superRefine causes a bug or blocks a feature |
301
273
| B27 |**`TrustKeyStore` PRE-VALIDATED KEY CACHE**| Promote when `verifySignature` appears in any p95 flame graph above 5% of call time |
302
-
| B100 |**MAP vs RECORD ASYMMETRY** — `getNodeProps()` returns Map, `getEdgeProps()` returns Record. Breaking change either way. From B-FEAT-3.| Promote with next major version RFC |
274
+
|~~B100~~|✅ ~~**MAP vs RECORD ASYMMETRY**~~ — `getNodeProps()`now returns `Record<string, unknown>`. Done in v13.0.0.|~~Promote with next major version RFC~~|
303
275
| B101 |**MERMAID `~~~` INVISIBLE-LINK FRAGILITY** — undocumented Mermaid feature for positioning. From B-DIAG-3. | Promote if Mermaid renderer update breaks `~~~` positioning |
304
276
305
277
---
@@ -312,21 +284,21 @@ B5, B6, B13, B17, B18, B25, B45 — rejected 2026-02-17 with cause recorded in `
@@ -455,11 +427,11 @@ Pick opportunistically between milestones. Recommended order within tiers:
455
427
## Final Command
456
428
457
429
Every milestone has a hard gate. No milestone blurs into the next.
458
-
Execution: M10 SENTINEL → **M12 SCALPEL** → **M13 SCALPEL II** → **M14 HYGIENE** → M11 COMPASS II. Standalone items fill the gaps.
430
+
Execution: M10 SENTINEL → **M12 SCALPEL** → **M13 SCALPEL II** → **M11 COMPASS II** → **M14 HYGIENE**. M11 is complete and archived. Standalone items fill the gaps.
459
431
460
432
M12 is complete (including T8/T9). M13 internal canonicalization (ADR 1) is complete — canonical `NodePropSet`/`EdgePropSet` semantics, wire gate split, reserved-byte validation, version namespace separation. The persisted wire-format half of B116 is deferred by ADR 2 and governed by ADR 3 readiness gates.
461
433
462
-
M14 HYGIENE is the current priority — test hardening, DRY extraction, and SOLID quick-wins from the HEX_AUDIT. M11 follows after M14.
434
+
M14 HYGIENE is the current priority — test hardening, DRY extraction, and SOLID quick-wins from the HEX_AUDIT. M11 is complete and archived in COMPLETED.md.
463
435
464
436
Rejected items live in `GRAVEYARD.md`. Resurrections require an RFC.
465
437
`BACKLOG.md` retired — all intake goes directly into this file (policy in `CLAUDE.md`).
0 commit comments