Skip to content

Commit ad59464

Browse files
committed
Preserve tombstones and stream reports; repair real SDK qualification
Preserve empty-versus-missing storage bytes, strict MCP framing and negotiated SDK transport. Stream immutable report arrays without copying samples. Correct real admission/authority/catalog/quota fixtures and retain bounded startup/test evidence. Full enabled development build and static checks precede this checkpoint; complete exact-SHA GitHub runtime qualification remains pending. Shared main HEAD/index and independent website work are preserved.
1 parent 6949fa0 commit ad59464

60 files changed

Lines changed: 2918 additions & 211 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jobs:
2727
with:
2828
name: analyzer-rule-evidence
2929
path: |
30+
TestResults/**
3031
tests/KeyLoad.Analyzers.Tests/**/TestResults/**
3132
artifacts/code-quality/**
3233
if-no-files-found: error
@@ -87,6 +88,7 @@ jobs:
8788
with:
8889
name: docker-rf3-qualification
8990
path: |
91+
TestResults/**
9092
tests/KeyLoad.IntegrationTests/**/TestResults/**
9193
artifacts/qualification/**
9294
if-no-files-found: error
@@ -141,6 +143,15 @@ jobs:
141143
name: comparison-suite
142144
path: artifacts/comparisons/**
143145
if-no-files-found: warn
146+
- name: Retain comparison test result reports
147+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
148+
if: always()
149+
with:
150+
name: comparison-test-results
151+
path: |
152+
TestResults/**
153+
tests/KeyLoad.ComparisonTests/**/TestResults/**
154+
if-no-files-found: warn
144155
- name: Retain comparison compiler diagnostic reports
145156
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
146157
if: always()

‎README.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,17 +233,17 @@ Tests use TUnit and Microsoft.Testing.Platform and execute in GitHub Actions. De
233233

234234
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.
235235

236-
Commit [`3559225a5f918160e46e32c9a812c3f71790e382`](https://github.com/managedcode/KeyLoad/commit/3559225a5f918160e46e32c9a812c3f71790e382) is on `main`. Its full 25-project Release build passed locally before delivery. Exact-SHA GitHub run [36988949282](https://github.com/managedcode/KeyLoad/actions/runs/36988949282) failed: analyzer tests passed 84/88, comparison tests 2/4, and RF3 integration tests 3/23. Governance also failed on all three OSes because its required plan file was ignored, and Windows normalized the preserved `AGENTS.md` prefix; the unit and process-recovery suites did not run because governance stopped those jobs. The first repair set is in progress; no exact-SHA qualification is claimed. Numeric coverage collection and its baseline are still not configured.
236+
Commit [`3559225a5f918160e46e32c9a812c3f71790e382`](https://github.com/managedcode/KeyLoad/commit/3559225a5f918160e46e32c9a812c3f71790e382) is the shared `main` baseline. Repair checkpoint [`6949fa0c3099443c6f34f91245ab8064ef22c63c`](https://github.com/managedcode/KeyLoad/commit/6949fa0c3099443c6f34f91245ab8064ef22c63c) is on `codex/runtime-qualification-20261002`. Its exact-SHA GitHub run [37005805424](https://github.com/managedcode/KeyLoad/actions/runs/37005805424) passed the full solution build, formatter, governance and 88/88 analyzer regressions on all three OSes. Runtime qualification failed: unit tests passed 719/770 on Ubuntu, 717/770 on macOS and 720/770 on Windows; RF3 passed 6/26 and comparisons 2/4. Recovery and measured comparison profiles did not execute after those failures. Subsequent scoped repairs await another exact-SHA run. The [runtime ledger](docs/implementation/runtime-qualification-20261002.md) retains each failure, job and artifact receipt. Numeric coverage collection and its baseline are still not configured.
237237

238-
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 qualification. The read-only product contract migration preserves JSON/base64 and fingerprints under [ADR-041](docs/ADR/ADR-041-read-only-public-collections.md). The exact-SHA analyzer run executed 88 TUnit cases: 84 passed and four span/cohesion cases failed. Numeric complexity rules are configured, while compatible coverage collection, container export and its baseline remain pending. See the [current source and gate evidence](docs/implementation/code-quality.md) and exact run [36988949282](https://github.com/managedcode/KeyLoad/actions/runs/36988949282).
238+
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 [37005805424](https://github.com/managedcode/KeyLoad/actions/runs/37005805424) passed all 88 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.
239239

240-
Memory and read-work repairs are in progress across storage, SQL/search, events, time series, graph, messaging, replication and transport. The [located repair inventory](docs/implementation/memory-performance.md) records authored changes and remaining proof separately. Earlier baseline CI [36936319423](https://github.com/managedcode/KeyLoad/actions/runs/36936319423) passed on its earlier SHA; candidate CI [36988949282](https://github.com/managedcode/KeyLoad/actions/runs/36988949282) failed and does not qualify correctness or performance.
240+
Memory and read-work repairs are in progress across storage, SQL/search, events, time series, graph, messaging, replication and transport. The [located repair inventory](docs/implementation/memory-performance.md) records authored changes and remaining proof separately. Earlier baseline CI [36936319423](https://github.com/managedcode/KeyLoad/actions/runs/36936319423) passed on its earlier SHA; candidate CI [37005805424](https://github.com/managedcode/KeyLoad/actions/runs/37005805424) failed and does not qualify system correctness or performance. Portable vector scoring is present; further SIMD validation, software-fallback checks and matched RF3 resource/latency measurements remain open.
241241

242242
All test qualification and load measurements run in GitHub Actions. The comparison harness uses deterministic JSON, float32 vectors and cyclic graphs, verifies the complete returned payload, and retains every measured attempt, including failures. Reports include useful throughput, p50/p95/p99, separate enqueue/receive/ACK timings and load-generator CPU/allocation/RSS. These resource metrics describe the client process. See the [comparison methodology](docs/implementation/comparative-benchmarks.md).
243243

244244
The [public benchmark lab](https://www.keyload.cloud/) displays verified CI reports with workload, scenario, measure and repetition controls. CI runs a correctness smoke and two measured profiles with 1 KiB/16 KiB documents, eight/four clients and three/five graph hops. GitHub Pages publishes their reports only after the complete CI workflow succeeds; [website operations](docs/implementation/website.md) describes provenance and the custom domain. Current external baselines are single-node and contracts differ; matched-durability, database resource budgets, Marten/Wolverine and scaling qualification remain planned. These development observations do not establish an equal-durability winner or production readiness.
245245

246-
The separate TimeSeries comparison profile is implemented under [ADR-050](docs/ADR/ADR-050-timeseries-timescale-comparison.md). Its CI test starts a digest-pinned, ephemeral TimescaleDB container, sends the same UTC samples through KeyLoad's RF3 .NET SDK and TimescaleDB's hypertable, and checks bucket results against the published `ManagedCode.TimeSeries` in-memory aggregation library. The library is not a persistence provider, and the Timescale container has no cross-run data volume; reports label each guarantee separately. Candidate run 36988949282 reached the comparison suite but failed its Timescale resource-name collision and a container digest assertion that included Aspire-built KeyLoad images. Both source corrections are in progress; a new exact-SHA run is still required.
246+
The separate TimeSeries comparison profile is authored under [ADR-050](docs/ADR/ADR-050-timeseries-timescale-comparison.md). Its test is designed to start a digest-pinned, ephemeral TimescaleDB container, send identical UTC samples through KeyLoad's RF3 .NET SDK and TimescaleDB's hypertable, and verify bucket results against the published `ManagedCode.TimeSeries` in-memory aggregation library. The library is not a persistence provider, and the Timescale container has no cross-run data volume; reports label each guarantee separately. Candidate run 37005805424 failed the native image assertion before Timescale startup. The source assertion now preserves Aspire's native repository/digest representation; actual database startup, workload, schema isolation and cleanup still need exact-SHA GitHub qualification.
247247

248248
The product website redesign is in progress under [ADR-040](docs/ADR/ADR-040-static-site-threejs-evidence.md): a product introduction, a conceptual Three.js RF3 illustration and the complete evidence workspace. Its independent TUnit site suite runs in GitHub Actions against authentic historical reports. Website source, measured source and raw hashes stay distinct; the preview does not qualify current database changes or publish the pending nine-engine comparison profiles.
249249

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Collections.Immutable;
2+
using System.Text.Json;
3+
4+
namespace KeyLoad.Comparisons;
5+
6+
/// <summary>Exposes an immutable array through a repeatable, allocation-bounded async enumerable.</summary>
7+
internal static class ImmutableArrayAsyncView
8+
{
9+
internal const string InvalidCollectionMessage = "A required collection must be an initialized JSON array.";
10+
11+
internal static IAsyncEnumerable<T> Create<T>(ImmutableArray<T> values) => Create(values, static value => value);
12+
13+
internal static IAsyncEnumerable<TResult> Create<T, TResult>(ImmutableArray<T> values, Func<T, TResult> project)
14+
{
15+
ArgumentNullException.ThrowIfNull(project);
16+
if (values.IsDefault)
17+
{
18+
throw new JsonException(InvalidCollectionMessage);
19+
}
20+
21+
return new View<T, TResult>(values, project);
22+
}
23+
24+
private sealed class View<TSource, TResult>(ImmutableArray<TSource> values, Func<TSource, TResult> project)
25+
: IAsyncEnumerable<TResult>
26+
{
27+
public IAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default) =>
28+
new Enumerator<TSource, TResult>(values, project, cancellationToken);
29+
}
30+
31+
private sealed class Enumerator<TSource, TResult>(ImmutableArray<TSource> values, Func<TSource, TResult> project,
32+
CancellationToken cancellationToken) : IAsyncEnumerator<TResult>
33+
{
34+
private int _index = -1;
35+
private TResult? _current;
36+
37+
public TResult Current => _current!;
38+
39+
public ValueTask<bool> MoveNextAsync()
40+
{
41+
cancellationToken.ThrowIfCancellationRequested();
42+
var next = _index + 1;
43+
if (next >= values.Length)
44+
{
45+
return ValueTask.FromResult(false);
46+
}
47+
48+
_index = next;
49+
_current = project(values[next]);
50+
return ValueTask.FromResult(true);
51+
}
52+
53+
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
54+
}
55+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Text.Json;
2+
3+
namespace KeyLoad.Comparisons;
4+
5+
/// <summary>Write-only case projection which streams its existing sample array.</summary>
6+
internal sealed record StreamedComparisonCase(string Target, Scenario Scenario, int Repetition, string Status,
7+
string? Detail, Measurement? Measurement, IAsyncEnumerable<OperationSample> Samples)
8+
{
9+
internal static StreamedComparisonCase Create(ComparisonCase comparisonCase)
10+
{
11+
if (comparisonCase.Samples.IsDefault)
12+
{
13+
throw new JsonException(ImmutableArrayAsyncView.InvalidCollectionMessage);
14+
}
15+
16+
var samples = ImmutableArrayAsyncView.Create(comparisonCase.Samples);
17+
return new StreamedComparisonCase(comparisonCase.Target, comparisonCase.Scenario, comparisonCase.Repetition,
18+
comparisonCase.Status, comparisonCase.Detail, comparisonCase.Measurement, samples);
19+
}
20+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Collections.Immutable;
2+
using System.Text.Json;
3+
4+
namespace KeyLoad.Comparisons;
5+
6+
/// <summary>Write-only report projection which streams its existing case array.</summary>
7+
internal sealed record StreamedComparisonReport(int SchemaVersion, Guid RunId, DateTimeOffset StartedAt,
8+
ComparisonOptions Options, string DatasetSha256, string LoadModel, string HostOs, string Architecture,
9+
int LogicalProcessors, string Runtime, string Storage, string? SourceRevision,
10+
ImmutableArray<TargetProfile> Targets, IAsyncEnumerable<StreamedComparisonCase> Cases)
11+
{
12+
/// <summary>Gets GitHub Actions provenance for the report, when available.</summary>
13+
public GitHubProvenance? Provenance { get; init; }
14+
15+
/// <summary>Gets the load-generator image reference, when available.</summary>
16+
public string? LoadGeneratorImage { get; init; }
17+
18+
internal static StreamedComparisonReport Create(ComparisonReport report)
19+
{
20+
ArgumentNullException.ThrowIfNull(report);
21+
if (report.Cases.IsDefault)
22+
{
23+
throw new JsonException(ImmutableArrayAsyncView.InvalidCollectionMessage);
24+
}
25+
26+
var cases = ImmutableArrayAsyncView.Create(report.Cases, StreamedComparisonCase.Create);
27+
return new StreamedComparisonReport(report.SchemaVersion, report.RunId, report.StartedAt, report.Options,
28+
report.DatasetSha256, report.LoadModel, report.HostOs, report.Architecture, report.LogicalProcessors,
29+
report.Runtime, report.Storage, report.SourceRevision, report.Targets, cases)
30+
{
31+
Provenance = report.Provenance,
32+
LoadGeneratorImage = report.LoadGeneratorImage
33+
};
34+
}
35+
}

‎benchmarks/KeyLoad.Comparisons/ReportWriter.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static async Task WriteAsync(ComparisonReport report, string directory, C
3333
Options = FileOptions.Asynchronous | FileOptions.SequentialScan
3434
}))
3535
{
36-
await JsonSerializer.SerializeAsync(stream, report, JsonOptions, cancellationToken).ConfigureAwait(false);
36+
await JsonSerializer.SerializeAsync(stream, StreamedComparisonReport.Create(report), JsonOptions, cancellationToken).ConfigureAwait(false);
3737
}
3838
cancellationToken.ThrowIfCancellationRequested();
3939
await File.WriteAllTextAsync(Path.Combine(directory, MarkdownFileName), Markdown(report), cancellationToken).ConfigureAwait(false);

0 commit comments

Comments
 (0)