Skip to content

Commit 323d604

Browse files
committed
Repair crash-file readiness and retain native restart failure evidence
Preserve all current authorized source changes; qualification runs in GitHub Actions.
1 parent 8b475d4 commit 323d604

29 files changed

Lines changed: 6960 additions & 51 deletions

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
KeyLoad is an experimental .NET 10 database that puts JSON documents, event streams, durable work queues, graphs, time series and search behind one API and one authorization model. An atomic command can update a document, append its event and enqueue work in the same transaction domain. The first server topology has three replicated nodes; each node owns its ZoneTree storage and journals.
44

5-
The intended cluster foundation is Orleans, with separate request grains, a distributed grain directory and activation migration. That migration, fully containerized RF3 execution and the official MCP surface are in progress; the published comparison baseline predates them. Follow the [architecture map](docs/Architecture.md) and [qualification tracker](docs/implementation/status.json) for the actual implemented and verified boundaries.
5+
The cluster foundation is Orleans, with separate request grains and a distributed grain directory. Docker/Aspire RF3 operations are exercised through the real .NET and official MCP SDK clients in GitHub Actions. Actual activation migration remains unqualified, and the published comparison baseline predates this replacement. Follow the [architecture map](docs/Architecture.md) and [qualification tracker](docs/implementation/status.json) for the implemented and verified boundaries.
66

77
The original load-testing prototype has been replaced. This repository implements the new [architecture and development plan](docs/design/architecture-v0.3.uk.md), with the [original HTML edition](docs/design/architecture-v0.3.uk.html) preserved alongside it.
88

@@ -237,7 +237,7 @@ Tests use TUnit and Microsoft.Testing.Platform and execute in GitHub Actions. De
237237

238238
The root `.editorconfig` is copied directly from Prostir. Every project enables SDK/static/style analysis with warnings as errors. Edit custom rules under `src/KeyLoad.Analyzers/Features/CodeQuality/` and add real-compilation cases under `tests/KeyLoad.Analyzers.Tests/Features/CodeQuality/`. They attach centrally to consumer projects and report in the IDE and build. Compiler SARIF 2.1 reports live under `artifacts/code-quality/<project>/<configuration>/<framework>/diagnostics.sarif`; CI retains them even when the build fails. See [CodeQuality](docs/Features/CodeQuality.md) for the rule catalog, authoring and applicability, and [current evidence](docs/implementation/code-quality.md) for actual gates.
239239

240-
The latest completed runtime checkpoint [fa80c701475d8faf65bb43b49b6e1c7afb33979a](https://github.com/managedcode/KeyLoad/commit/fa80c701475d8faf65bb43b49b6e1c7afb33979a) passed exact GitHub solution build, formatter, governance and118/118 analyzer cases on all three OSes in [run37021991878](https://github.com/managedcode/KeyLoad/actions/runs/37021991878). Unit results are787/788 on each OS, with three distinct remaining failures. Process recovery is115/115 on Linux/macOS and104/115 on Windows. RF3 caller tests are9/26; three separate file-receipt tests also pass. Comparison is2/4. The previous four unit failures now pass across all OSes. New preserving fixture/MCP framing repairs require renewed CI; [the runtime ledger](docs/implementation/runtime-qualification-20261002.md) records exact failures and evidence. Coverage and server-resource qualification remain open.
240+
The [runtime ledger](docs/implementation/runtime-qualification-20261002.md) preserves exact GitHub source SHAs, native suite counts, failures and artifact hashes; [AdminDashboard](docs/Features/AdminDashboard.md) records its separately verified RF3 and browser evidence. Preserving recovery refinements cover optional checkpoint metadata absence and all expected source/target ownership under the original deadline. They and the new bounded failed-restart diagnostics require their own delivered-source CI. Recovery, comparison completion and intermittent startup gates remain open. Coverage and server-resource qualification remain open.
241241

242242
The comparison library/sole CLI host split under [ADR-043](docs/ADR/ADR-043-comparison-library-host.md), immutable harness under [ADR-044](docs/ADR/ADR-044-benchmark-immutable-contracts.md), owned PostgreSQL schema repair under [ADR-045](docs/ADR/ADR-045-postgres-schema-ownership.md), private storage owners under [ADR-046](docs/ADR/ADR-046-storage-private-owners.md) and genuine BenchmarkDotNet library under [ADR-047](docs/ADR/ADR-047-embedded-benchmark-host.md) are source joins awaiting full runtime qualification. The read-only product contract migration preserves JSON/base64 and fingerprints under [ADR-041](docs/ADR/ADR-041-read-only-public-collections.md). Exact-SHA run [37015193756](https://github.com/managedcode/KeyLoad/actions/runs/37015193756) passed all88 analyzer cases and the enabled solution builds; subsequent repairs require renewed verification. Compatible coverage collection, container export and its numeric baseline remain pending. Historical source stages are retained in the [code-quality record](docs/implementation/code-quality.md); the [runtime ledger](docs/implementation/runtime-qualification-20261002.md) records the latest completed candidate run.
243243

‎docs/Features/ClusterReplication.md‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,51 @@ Slice map: `src/KeyLoad.Replication/Features/ClusterReplication/` owns protocol/
2424

2525
Traceability: AC-REP-001/003/004 map to `ClusterTests` and the new replica recovery tests; AC-REP-002 maps to real CrashHost interruption scenarios; AC-REP-005 maps to authorization/failover client cases. TASK-REP-LOG, TASK-REP-TRANSPORT, TASK-REP-INTEGRATE and TASK-REP-VERIFY are defined in [execution plan](../implementation/orleans-foundation.plan.md). Qualification is GitHub Actions only. Historical CI 36926803549 qualifies the old implementation, not this replacement. Power-loss and endurance remain pending.
2626

27+
TASK-RUNTIME-REPLICA-READINESS-W4 maps REQ-REP-004 / AC-REP-004 and
28+
REQ/AC-STORAGE-012. Exact main b533c80 / CI37032546228 fails the Windows
29+
SnapshotInstalled reopen on target/database/tree/0.meta.wal; the prior two-store
30+
barrier probes only owner.lock and commands.wal. Root replaces each store's
31+
probe with the shared StorageRecovery exclusive-file probe, including metadata
32+
when present, inside the existing single five-second/25ms loop. Cancellation
33+
stops before another probe. No file creation, recovery retry, timeout increase,
34+
weakened snapshot/tail/receipt predicate or attribution of the unknown holder
35+
is permitted. A disjoint test worker owns new ClusterReplication real-file
36+
barrier cases: hold canonical or replica metadata exclusively, verify pending
37+
then release and success; cancel a held wait and pre-cancel an unlocked wait;
38+
assert a permanent holder still fails under the unchanged bound. Use actual
39+
closed CrashHost target stores and observe/dispose pending tasks and holders
40+
before deleting their root. Existing native SnapshotInstalled process-kill and
41+
ordered-tail tests are the primary regression. ADR-035/036/041 ownership and
42+
lifetime contracts suffice; public/data/dependency boundaries are unchanged.
43+
Root reviews both helper/caller scopes together, development-builds/formats,
44+
and qualifies the full three-OS recovery suite in GitHub at the delivered SHA.
45+
46+
The same W4 criterion includes exact1bee2609 / CI37036628601's source-store
47+
reopen failures. For the six typed snapshot/transfer crash boundaries, the child
48+
also opened `source/database` and `source/replica`. Enumerate these exact owned
49+
stores alongside the target stores inside the same single five-second/25ms loop.
50+
Use the crash boundary's explicit source-ownership contract, never filesystem
51+
existence to decide whether required ownership/journal files are optional. Other
52+
boundaries retain their target-only path and must not create source storage.
53+
Root owns the CrashHost store-path/source-boundary helpers, preserving the
54+
existing scenario predicate, and ReplicaProcessTrial/ReplicaProcessFiles join.
55+
The disjoint readiness test worker extends only its real-store fixture and cases:
56+
each source canonical/replica owner, journal and metadata holder keeps the actual
57+
combined wait pending until released. Existing source snapshot import and private
58+
transfer crash cases remain the primary regression and retain all assertions.
59+
60+
The two permanent-holder elapsed checks retain their five-second lower and
61+
six-second upper observation bounds. Run only those individual wall-clock
62+
measurement cases with TUnit's keyless method-level `NotInParallel`, which the
63+
pinned1.72.10 package documents as exclusive execution. Exact Windows evidence
64+
shows the failed check overlapped74 distinct cases with16 active at peak; timer
65+
or continuation delay is a supported inference, without a threadpool trace.
66+
No class/assembly serialization, retry or timeout increase is allowed. Other
67+
holder-release/cancellation tests and every real process crash remain parallel.
68+
This is intrinsic readiness timing qualification, not a loaded-system latency
69+
claim. Source review, native case discovery and full exact-SHA CI must verify
70+
that the same bounds and all original crash cases remain.
71+
2772
## Actors, entry points and failure boundaries
2873

2974
Actors are authenticated SDK/MCP callers, the node-local replica host, fixed voters, the membership provider and the recovery operator. Current source is composed by [ServerApplication](../../src/KeyLoad.Server/Features/ClientApi/ServerApplication.cs): it starts the node-local [PartitionHost](../../src/KeyLoad.Server/Features/StorageRecovery/PartitionHost.cs) and Orleans silo, whose [replica service](../../src/KeyLoad.Orleans/Features/ClusterReplication/PartitionReplicaGrainService.cs) routes peer operations. Aspire declares three Docker nodes with separate data mounts. This source is not yet qualified as a delivered RF3 deployment: current tests do not force request-activation migration and then verify storage ownership and a durable caller-visible outcome. Public HTTP/.NET transport belongs to ClientApi; required official MCP parity is pending. Frontend is N/A because replica consensus has no independent UI. Shared contracts stay in Abstractions and the exact ClusterReplication/StorageRecovery slice owners above.

‎docs/Features/StorageRecovery.md‎

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,37 @@
33
REQ-STORAGE-012 / AC-STORAGE-012 (TASK-RUNTIME-WINDOWS-RECOVERY-W3) preserves
44
the existing killed-child filesystem readiness bound. After actual process exit,
55
exclusive readiness covers owner.lock, commands.wal and the actual ZoneTree
6-
tree/0.meta.wal which failed to reopen in Windows CI37021991878. The prior receipt
6+
tree/0.meta.wal when present, which failed to reopen in Windows CI37021991878. The prior receipt
77
does not identify the sharing holder; this is a test-fixture observation gap,
88
not proof of a storage/dependency defect. Keep the five-second bound and25ms poll,
99
all50 seeded trials, original trial deadlines, WAL/snapshot/atomic assertions and
1010
permanent sharing failure. Cancellation stops before another probe; no retry of
1111
the recovery operation, default timeout increase or filesystem bypass is allowed.
1212

13+
TASK-RUNTIME-RECOVERY-W4 refines this same criterion using exact main
14+
b533c80 / CI37032546228. During checkpoint installation the disposed live tree
15+
is moved aside before InstallPrepared and JournalSwapped callbacks; the child
16+
can therefore exit with no tree directory. Only FileNotFoundException and
17+
DirectoryNotFoundException while opening the optional metadata WAL mean that
18+
this file has no holder. owner.lock and commands.wal remain required exclusive
19+
probes; sharing violations and all other I/O errors retain the original bound.
20+
No readiness probe creates files or directories. Real missing-directory and
21+
missing-metadata-file regressions assert successful readiness without recreating
22+
either path, then restore the actual store files and prove subsequent reopen
23+
and commit. Missing required ownership/journal files must still fail, and the
24+
existing held-file/cancel/pre-cancel/permanent-lock tests remain intact.
25+
26+
The common synchronous probe is internal test infrastructure shared with
27+
ClusterReplication's existing store barrier. That caller retains one
28+
five-second deadline across target stores and, only at typed snapshot/transfer
29+
boundaries, both source stores, with its25ms poll; it does not perform consecutive
30+
independently bounded waits. Root owns that caller join;
31+
the StorageRecovery worker owns only the existing helper, real-file tests and
32+
fixture. All checkpoint process-kill, seeded trials and replica snapshot/tail
33+
assertions remain unchanged. Tests-first source hashes, numeric/lifetime review,
34+
enabled development build/format and full exact-SHA GitHub recovery all OSes
35+
are the join; rollback reverts only the preserving helper/caller/test refinement.
36+
1337
New real-file tests first hold the metadata WAL exclusively after an actual
1438
ZoneTree store closes: the shared barrier must remain pending, complete only
1539
after releasing that holder, reject cancellation and fail under the same bounded
@@ -52,7 +76,7 @@ new scoped-read contract; ADR-032 records existing layout migration debt.
5276
| REQ-STORAGE-008: cohesive private provider owners meet numeric gates without changing storage/caller contracts | AC-SQ-001..008 in storage-quality.acceptance.md | ADR-046 TASK-MP-010AF-R/T/C/L/B; source join and real lifetime test source exist; enabled provider development build clean, complete exact-SHA runtime qualification pending |
5377
| REQ-STORAGE-009: validation and apply share one private mutation projection per staged generation | AC-PSW-001..004, AC-MP-006/012 | ADR-035 TASK-MP-016P-W/L; first-authored PreparedTransactionTests plus existing FrameBudget/recovery/RF3 proof; source and qualification pending |
5478
| REQ-STORAGE-011: startup identity metadata is finite and failed read releases physical ownership | AC-BSM-001/003/005 | [ADR-048](../ADR/ADR-048-bounded-storage-metadata.md), Metadata* real-file constructor/restore/reopen checks under BackupRestore; complete source and GitHub execution pending |
55-
| REQ-STORAGE-012: killed-child readiness includes the real metadata WAL and preserves cancellation and the original failure bound | AC-STORAGE-012 | `tests/KeyLoad.RecoveryTests/Features/StorageRecovery/KilledProcessFileReadinessTests.cs`: actual closed-store pending/release, cancellation, pre-cancellation and permanent-lock cases; `RecoveryTests.cs` retains every process-kill scenario; TASK-RUNTIME-WINDOWS-RECOVERY-W3, full three-OS GitHub recovery qualification pending |
79+
| REQ-STORAGE-012: killed-child readiness includes the real metadata WAL when present, permits only precise sanctioned metadata absence, and preserves cancellation and the original failure bound | AC-STORAGE-012 | `tests/KeyLoad.RecoveryTests/Features/StorageRecovery/KilledProcessFileReadinessTests.cs`: actual closed-store pending/release, cancellation, pre-cancellation, permanent-lock, missing optional directory/file without creation and missing required file cases; `RecoveryTests.cs` retains every process-kill scenario; TASK-RUNTIME-WINDOWS-RECOVERY-W3 and TASK-RUNTIME-RECOVERY-W4, full three-OS GitHub recovery qualification pending |
5680

5781
Ownership: common public storage contracts stay in Abstractions/Storage;
5882
provider helpers in Storage.ZoneTree/Features/StorageRecovery, tests mirror that

‎docs/Features/TestInfrastructure.md‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,59 @@ and exact-SHA GitHub first-failure/report/recovery artifacts supplement those
109109
assertions. Environmental watch/runner failures
110110
must not be replaced by mocks or counted as green qualification.
111111

112+
TASK-RUNTIME-RESTART-RECEIPT-W4 refines REQ/AC-TEST-007 after exact main
113+
b533c80 / CI37032546228. The failed native restart attempt is currently missing
114+
its container generation: the first receipt shows the killed old node and later
115+
receipts show a successful restoration. Capture the public Aspire current
116+
ResourceId, closed state/health, exit code and creation/start/stop timestamps
117+
before Start, after its successful command and immediately after an existing
118+
restart failure. These are sampled snapshots, not a native snapshot version or
119+
proof of the transition which caused the failure. Native Version and readiness
120+
internals are unavailable and must not be reflected or inferred.
121+
122+
The failure receipt includes the existing verified pre-kill Docker ID/start time,
123+
closed failure stage/type, Start success and one immediate read-only Docker
124+
inspection of ID/status/exit/OOM/start/finish/error-present. No Docker error text,
125+
environment, properties, endpoints, credentials, arbitrary method/type text or
126+
payload is included. Only validated native identifiers and timestamps are
127+
retained; unknown states/types become a fixed unavailable/other marker. At most
128+
32 earliest restart receipts plus one latest view are retained, with80-line/8KiB
129+
UTF-8 bounds and filenames containing only the local sequence. The diagnostic
130+
has its own three-second native-inspection deadline after the original failure.
131+
Every path after process creation owns termination, reaping and observation of
132+
both redirected readers, including setup, wait and reader faults. Mandatory
133+
cleanup can extend wall time if operating-system termination is delayed; no
134+
hard end-to-end three-second return or detached process/reader claim is allowed.
135+
Termination checks an exit race and retries a failed live-child tree kill once;
136+
a final live-child kill error is retained through mandatory task joining. If
137+
the operating system permanently refuses termination, finite cleanup cannot be
138+
guaranteed. This environmental branch needs native CI evidence or source review,
139+
never a synthetic process failure or a passing lifecycle claim.
140+
It releases/awaits its actual CLI process and redirected readers on cancellation,
141+
then rethrows the original restart exception even if diagnostic inspection or
142+
file writing fails. Existing synchronous whole-file persistence keeps its
143+
80-line/8KiB limit; no hard three-second filesystem-latency claim or detached
144+
writer task is allowed.
145+
No Start, health, runtime identity, zero-exit, cancellation, timeout, retry count,
146+
quorum, atomicity, data or cleanup assertion changes.
147+
148+
Root owns ContainerRuntimeControl and the closed receipt-kind join in
149+
ClusterFailureReceipts; one disjoint worker owns only new ClusterReplication
150+
failure-capture/projection/CLI-lifetime helpers and real temporary-file tests.
151+
Tests first prove only selected native public snapshot fields survive with
152+
canary properties/env/URL/state/identifier/type rejected, whole valid bounded
153+
files preserve the first failed generation across later receipts, and32-file
154+
retention remains exact. Native-shaped Docker records cover valid identities,
155+
safe error-presence projection and malformed ID/state/exit/OOM/timestamp fields;
156+
actual stream readers prove output is drained after its retained prefix is full.
157+
Do not fake native services, Docker or process failures.
158+
The original RF3 leader-loss/minority scenario remains the real lifecycle test;
159+
an environmental failure branch additionally requires exact-SHA GitHub artifact
160+
review and source lifetime/predicate comparison. If the next run succeeds, do
161+
not claim its unexecuted failure path qualified. ADR-035/036/039 existing
162+
privacy/lifetime contracts suffice; no product/public/dependency boundary changes.
163+
Rollback reverts only this additive diagnostic join and its helpers/tests.
164+
112165
## Platform, dependency та release qualification
113166

114167
B3 keeps the exact task lifetime above while satisfying enabled CA1031: a private

0 commit comments

Comments
 (0)