Skip to content

Commit 6ad4741

Browse files
committed
Use generated Orleans serialization for atomic ZoneTree WAL
1 parent ed41c0a commit 6ad4741

35 files changed

Lines changed: 1085 additions & 44 deletions

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
strategy:
3636
fail-fast: false
3737
matrix:
38-
os: [ubuntu-latest, macos-latest, windows-latest]
38+
os: [ubuntu-latest]
3939
runs-on: ${{ matrix.os }}
4040
timeout-minutes: 30
4141
steps:

‎AGENTS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ManagedCode packages are our projects. Fix dependency defects in their owning si
2525
- Optimize each operation only against its correctness and fault contracts, using representative multi-node GitHub qualification to measure latency, throughput, allocations, memory, contention and backlog where applicable. Architecture choices or local builds alone do not prove maximum scalability or performance.
2626
- Use ZoneTree's native storage APIs correctly and Orleans for bounded parallel execution of independent operation work. Preserve node-local storage ownership, the ordered atomic commit/apply gate, scoped read cuts, cancellation and backpressure; qualify the resulting performance in real multi-node GitHub runs (owner direction 2026-10-02).
2727
- All KeyLoad-owned database models MUST use ZoneTree as their canonical storage engine, including documents, relational rows, graphs, vectors/search, time series, blobs, queues and events. Use and qualify ZoneTree's native WAL in the storage durability path; retain the distinct replication and atomic-commit recovery journals until an explicit storage-format ADR and fault qualification prove any migration safe. This requirement applies to KeyLoad models, while comparison engines retain their real native storage (owner direction 2026-10-02).
28+
- Use the native generated Orleans binary serializer for KeyLoad atomic WAL mutation payloads over ZoneTree. Preserve raw-byte native ZoneTree serialization, synchronous durability barriers, checksums, ordered atomic recovery and RF3 authority; accept format changes only through an explicit upgrade contract and qualify speed and fault claims with actual GitHub evidence (owner direction 2026-10-03).
2829
- Orleans distribution and Orleans-coordinated caches are mandatory product workstreams. Define bounded memory, admission, eviction, concurrency and backpressure, with cache identity and validation tied to authorized scoped read cuts and policy epochs. Specify invalidation after writes and authorization changes, and recovery after grain migration, failover and restart before implementation; cached state MUST NOT replace persisted authorization, committed ZoneTree state or RF3 durability guarantees (owner direction 2026-10-02).
2930
- The owner confirmed on 2026-10-02 that memory means the KeyLoad RAM layer and Orleans caches. Deliver a bounded node-local RAM acceleration layer over committed ZoneTree data and its native WAL, coordinated through Orleans; RAM contents are disposable across restart or activation movement and MUST NOT become the authority for acknowledged writes, authorization or RF3 recovery.
3031
- Model logical shards and cache coordination as Orleans grains behind the separate grain-per-request boundary. Shard-grain identity MUST remain distinct from physical replica placement; activation movement routes to node-local ZoneTree/WAL owners rather than moving open storage handles (owner clarification 2026-10-02).

‎Directory.Packages.props‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
<PackageVersion Include="ModelContextProtocol.Core" Version="2.2.0" />
1919
<PackageVersion Include="Microsoft.Orleans.Server" Version="10.3.1" />
2020
<PackageVersion Include="Microsoft.Orleans.Sdk" Version="10.3.1" />
21+
<PackageVersion Include="Microsoft.Orleans.Serialization" Version="10.3.1" />
22+
<PackageVersion Include="Microsoft.Orleans.CodeGenerator" Version="10.3.1" />
2123
<!-- Orleans' existing Roslyn dependency; analyzer tests select SDK compiler assets. -->
2224
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.0.0" />
2325
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ System projection APIs require cluster administration. A consumer defines its in
199199

200200
The canonical backup includes the checksummed redo journal, database identity and a SHA-256 manifest. Domain data, schemas, credentials, outcomes and inbox receipts are journaled together. The journal can begin with a verified checkpoint followed by newer transaction frames. ZoneTree files can be rebuilt from that canonical history. Restore validates every manifest file, creates a new incarnation, resets consensus routing metadata and leaves queue dispatch paused.
201201

202+
The current atomic-WAL source uses generated Orleans binary mutation payloads, explicit Put/Delete kinds and identity format3; native ZoneTree raw bytes, disk-flush ordering and checkpoint2 remain. Upgrading JSON journals requires stopping all RF3 writers, Compact with the previous binary, and a verified compacted backup before upgrading every node. A remaining full legacy journal header is refused. [ADR-057](docs/ADR/ADR-057-orleans-atomic-wal.md) defines this offline transition; final GitHub fault qualification and measured acceleration are pending.
203+
202204
```sh
203205
# Stop the node before using the offline CLI.
204206
dotnet run --project src/KeyLoad.Cli -- compact data/cluster/node1/database
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ADR-057: Native Orleans binary atomic WAL
2+
3+
Status: Accepted implementation contract2026-10-03 under owner serializer direction; source implemented; exact-SHA qualification pending. Owner: KeyLoad integration lead. Related REQ-STORAGE-015..019, AC-WAL-001..005, TASK-WAL-001..005. Extends the storage format matrix of ADR-011 only for this private journal transition; no broader migration approval.
4+
5+
## Decision
6+
7+
commands.wal mutation payload uses private generated Orleans DTOs with permanent field IDs and type aliases and a cached typed serializer. Fields0/1 carry key/nullable value; mandatory field2 is Put1 or Delete2, with default0 invalid. This prevents absent version-tolerant fields from implying deletion. Validate exact kind/value pairing before apply. A direct Microsoft.Orleans.Serialization reference uses the already pinned10.3.1 version. Native ZoneTree Memory<byte> ByteArraySerializer and Sync WAL remain. No duplicate custom serializer, permissive JSON fallback or application-owned serialization loop. Serialized output is bounded by the existing configured MaxFrameBytes; exact binary length is checked before writing.
8+
9+
Journal header layout stays52bytes with SHA256, payload length and sequence; journal magic advances from1 to2. Store identity advances to3 so the old binary's identity validator refuses writes. Checkpoint format2, raw record keys/values, replication log, authority/incarnation and ACK ordering stay. Decode and validate complete payload/records before any frame apply; errors are sanitized Corruption. Current binary torn-tail, poisoned unknown-outcome and durable-flush behavior stays. Every full legacy52-byte frame header is refused even if its payload is torn; only shorter-than-header tail bytes retain truncation for the offline transition.
10+
11+
```mermaid
12+
flowchart LR
13+
Stage[Ordered owned mutations] --> Orleans[Generated binary codec and bounded output]
14+
Orleans --> Journal[Versioned checksummed commands WAL]
15+
Journal --> Flush[Flush to disk before apply]
16+
Flush --> Tree[Native ZoneTree bytes and Sync WAL]
17+
Journal --> Verify[Verify checksum sequence complete decode and keys]
18+
Verify --> Replay[Replay whole valid frame]
19+
```
20+
21+
## Upgrade and rollback matrix
22+
23+
|Source|Target|Contract|
24+
|---|---|---|
25+
|New empty directory|Identity3 plus frame2|Create current binary store|
26+
|Identity1/2 empty journal or complete verified checkpoint2 only|Identity3 plus frame2|Offline stop all RF3 writers, verify backup, recover existing checkpoint, atomically publish identity3 before accepting writes|
27+
|Identity1/2 with any full JSON frame1 header, including a torn payload|None|FormatUnsupported with old-binary Compact guidance, authoritative journal unchanged; no runtime compatibility reader|
28+
|Identity3 with checkpoint2 plus frame2|Same|Normal recovery/Compact/InstallSnapshot/native backup/restore; never lower identity to2|
29+
|Unknown magic/identity or malformed complete binary|None|Fail closed; no reinterpretation/reset|
30+
|Identity3 after first frame2 write|Old executable|Unsupported; use compatible binary or restore complete verified pre-upgrade backup with explicit operational data-loss decision|
31+
32+
Before rollout use the old binary to Compact every stopped node's journal, verify backups and checkpoints, then deploy identical new binaries to all RF3 members before serving traffic. There is no mixed-version rolling write contract. No direct production/database access is requested or authorized. Upgrade tests use owned local fixtures executed in GitHub.
33+
34+
## Implementation and join contract
35+
36+
1. Lead freezes requirements/acceptance and keeps shared docs/dependencies/existing-file edits.
37+
2. Codec worker owns new StorageRecovery DTO/codec/bounded-writer files; regression worker owns StorageRecovery unit tests. Writes are disjoint, lead integrates aliases/package reference.
38+
3. Lead switches PreparePayload/recovery, replaces JSON stage estimates with binary-safe accounting, preserves cache/reset/rejected-stage invariants, sets new journal magic and identity guard, promotes only recovered legacy checkpoint/empty state, and preserves identity3 in CheckpointGeneration.
39+
4. Lead verifies restore returns current identity, old executables fail before writes, and no corrupt frame is partially accepted. Existing SDK/MCP contracts remain.
40+
5. Qualify build/analyzers/format/governance and real TUnit unit/process/RF3 exact-SHA GitHub gates. Keep ADR Accepted until all required source/tests/docs/evidence exists. Measured speed, power-loss and endurance remain separate unproven gates.
41+
42+
Canonical slice: src/KeyLoad.Storage.ZoneTree/Features/StorageRecovery and tests/KeyLoad.UnitTests/Features/StorageRecovery; existing real RecoveryTests and RF3 integration suites are mandatory. Frontend/client API:N/A, private durable payload only. No authored public model change. The working task graph and test mapping are in the root WAL plan/acceptance.

‎docs/ADR/README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,5 @@ and GitHub TUnit/Dry qualification; implementation and exact-SHA proof are pendi
9898
- configured voter membership for the console's node view.
9999

100100
REQ/AC-AD-008..010 and REQ/AC-BC-029 apply. Exact-SHA qualification is pending.
101+
102+
[ADR-057](ADR-057-orleans-atomic-wal.md) accepts private Orleans binary atomic WAL payloads with format3 fencing and offline checkpoint-only upgrades; source and exact-SHA qualification pending.

‎docs/Architecture.md‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ flowchart LR
4343

4444
Read the root and nearest project-local AGENTS.md before changing this solution. The product specification is [architecture v0.3](design/architecture-v0.3.uk.md). This document is a navigation map, not a replacement specification or a readiness claim.
4545

46-
The [documentation index](README.md) is the complete entry point for 22 canonical Feature specifications. Each owning Feature defines stable REQ/AC, callers, boundaries, flows, existing or planned tests and a Mermaid diagram. The [ADR catalog](ADR/README.md) contains all 55 decisions with status and implementation contracts. The [coverage catalog](implementation/documentation-coverage.json) maps all 104 KL tasks; [status.json](implementation/status.json) remains the single implementation-status authority.
46+
The [documentation index](README.md) is the complete entry point for 22 canonical Feature specifications. Each owning Feature defines stable REQ/AC, callers, boundaries, flows, existing or planned tests and a Mermaid diagram. The [ADR catalog](ADR/README.md) contains all 56 decisions with status and implementation contracts. The [coverage catalog](implementation/documentation-coverage.json) maps all 104 KL tasks; [status.json](implementation/status.json) remains the single implementation-status authority.
4747

4848
Current mandatory policy requires an Orleans RF3 database, node-local PartitionHost storage ownership, separate request grains, distributed grain directory and activation migration, TUnit tests, Docker/Aspire RF3 execution and real .NET SDK plus official MCP SDK callers. Atomic partitions remain separate from physical replica placement. Credentials and trusted authorization are persisted server-side.
4949

@@ -404,3 +404,16 @@ flowchart LR
404404
Timescale --> Oracle
405405
MCTS --> Oracle
406406
```
407+
408+
## Atomic WAL binary serialization
409+
410+
[ADR-057](ADR/ADR-057-orleans-atomic-wal.md) scopes native generated Orleans serialization to StorageRecovery commands.wal payloads. Private stable mutation DTOs and a cached typed serializer join the existing ordered atomic journal; native ZoneTree bytes/Sync WAL, replication journal, checkpoint2 and Orleans routing stay under their existing owners. Identity3 fences old writers; only offline verified checkpoint-only/empty legacy stores may promote. Source/GitHub qualification pending.
411+
412+
```mermaid
413+
classDiagram
414+
ZoneTreeTransaction --> ZoneTreeJournalCodec : prepares binary payload
415+
ZoneTreeJournalPublication --> ZoneTreeJournalCodec : validated payload
416+
ZoneTreeJournalRecovery --> ZoneTreeJournalCodec : complete checked decode
417+
ZoneTreeJournalCodec --> ZoneTreeJournalMutation : stable generated fields
418+
ZoneTreeStoreInitializer --> ZoneTreeIdentityFile : format3 writer fence
419+
```

‎docs/Features/StorageRecovery.md‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,26 @@ and1000success receipts perOS. Existing ADR-035 lifetime/test contracts suffice;
236236
ADR:N/A for additional architecture because this is test-harness ordering only,
237237
with no product/wire/persistence/topology change. Rollback reintroduces the
238238
post-cleanup receipt cancellation risk without altering production data.
239+
240+
## Orleans binary atomic WAL
241+
242+
[ADR-057](../ADR/ADR-057-orleans-atomic-wal.md) accepts owner-directed REQ-STORAGE-015..019 and AC-WAL-001..005. New commands.wal mutation payloads use generated Orleans binary serialization, versioned magic2 and identity3. Native ZoneTree raw-byte Sync WAL, checkpoint2 and replication journals retain their own contracts. Offline upgrade requires old-binary Compact and a verified backup on every stopped RF3 node; a remaining JSON frame refuses with FormatUnsupported instead of a fallback reader. Exact-source source/runtime qualification remains pending.
243+
244+
|Requirement|Acceptance/test trace|
245+
|---|---|
246+
|REQ-STORAGE-015 binary mutation codec|AC-WAL-001 real-store binary/empty/delete roundtrip and reopen|
247+
|REQ-STORAGE-016 exact bounded payload|AC-WAL-002 FrameBudgetTests plus PreparedTransactionTests cache/replacement/reset/rejected-stage|
248+
|REQ-STORAGE-017 safe replay|AC-WAL-003 checksum/full-consumption/shape/order/legacy rejection and existing real commit crash cuts|
249+
|REQ-STORAGE-018 version fence and offline upgrade|AC-WAL-004 legacy checkpoint/empty/refusal, Compact/InstallSnapshot/restore identity preservation|
250+
|REQ-STORAGE-019 authentic qualification|AC-WAL-005 full Release/formatter/governance and exact-SHA GitHub unit/process-recovery/RF3 SDK+MCP; speed and power-loss unclaimed|
251+
252+
```mermaid
253+
flowchart LR
254+
Transaction[Owned ordered transaction] --> Codec[Orleans generated binary payload]
255+
Codec --> Commit[Checksum and disk flush]
256+
Commit --> Native[Native ZoneTree Sync WAL]
257+
Reopen[Journal recovery] --> Validate[Version checksum complete decode and ordered keys]
258+
Validate --> Apply[Apply verified mutations]
259+
```
260+
261+
See root zonetree-orleans-wal.acceptance.md and .plan.md for precise pass/fail conditions, disjoint agent scopes, rollout/rollback and verification. No new UI/API/model format; no local tests; all runtime evidence comes from GitHub.

‎docs/implementation/status.json‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
"KL-003": {
2121
"title": "ZoneTree durability audit і crash harness",
2222
"status": "in_progress",
23+
"atomicWalSerialization": {
24+
"status": "source_implemented_qualification_pending",
25+
"decision": "docs/ADR/ADR-057-orleans-atomic-wal.md",
26+
"source": "generated_Orleans10.3.1_binary_mutations_explicit_kind_full_consumption_frame2_identity3_native_ZoneTree_unchanged",
27+
"upgrade": "offline_old_binary_compact_verified_backup_homogeneous_RF3_no_JSON_fallback",
28+
"verification": "restore_governance_pass_no_final_WAL_compiler_analyzer_diagnostics_dirty_tree_build_blocked_by_111_concurrent_comparison_diagnostics_exact_committed_GitHub_full_build_format_unit_process_recovery_RF3_pending",
29+
"performance": "encoded_size_regression_authored_no_acceleration_power_loss_or_endurance_claim"
30+
},
2331
"evidence": [
2432
"src/KeyLoad.Storage.ZoneTree/ZoneTreeStore.cs",
2533
"tests/KeyLoad.RecoveryTests/RecoveryTests.cs",

‎scripts/Features/BenchmarkComparisons/image-contracts.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export const dockerArgument = Object.freeze({
7777
context: 'context',
7878
show: 'show',
7979
contextInspect: 'inspect',
80+
format: '--format',
8081
contextEndpointTemplate: '{{(index .Endpoints "docker").Host}}',
8182
version: '--version',
8283
info: 'info',

0 commit comments

Comments
 (0)