Skip to content

Commit cb6bbcf

Browse files
committed
Fix remote lifetime capture and bounded movement digests
1 parent da3a920 commit cb6bbcf

8 files changed

Lines changed: 68 additions & 23 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ The corrected [working database functional gates](docs/Features/DatabaseComposit
9696

9797
The earlier resource-lifetime and analytics-root repair checkpoint passed its strict solution build, all **45 selected native whole-operation tests**, all **three selected process/native recovery tests**, and the actual SDK/MCP RF3 authorization scenario through all-three-node same-root cold restart. These are local development proofs. Earlier scenarios and failures retain their original source scope; whole-product and Linux qualification remain open.
9898

99-
The later integrated native resource-lifetime command/read and controlled blob outcome source passes the full strict Release build with zero warnings/errors and the full canonical format verifier. Its focused native unit, recovery, RF3 and public functional qualification remains open; these source checks do not refresh the earlier runtime results.
99+
The later integrated native resource-lifetime command/read and controlled blob outcome source passes the full strict Release build with zero warnings/errors. Its latest selected native test run is **49 passed / 11 failed / 0 skipped**, improving from42/60 after the remote-document repair. Remaining failures cover distributed-search phase serialization, a scoped-budget test counter and a supporting movement fixture budget. Full formatting passed before these runtime repairs; current RF3 and public functional qualification remains open. These checks do not refresh earlier runtime results.
100100

101101
The separate [all-model cold-reopen pair](docs/Features/DatabaseComposition/FunctionalDatabaseColdReopen.md) also passed on `57cea624`: **one node in 104.61 seconds, then RF3 in 118.73 seconds**. After all original nodes restarted through Aspire, both clients replayed the original SQL, mixed-model and blob-stage commands with complete receipt/value checks, then verified persisted grant revocation, repair and a healthy write. These tests keep the same physical roots and credentials. They use three cold-only identities and do not claim the normal gate's eight-user concurrency.
102102

‎docs/implementation/status.json‎

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,66 @@
22
"RESOURCE-LIFETIME-NATIVE-20261016": {
33
"title": "Integrated native resource lifetime command/read and controlled blob outcome checkpoint",
44
"status": "in_progress",
5-
"implementation": "Canonical native source integrated; full strict Release compiler/analyzers and canonical full formatter passed. Runtime qualification on this integrated source remains pending.",
5+
"implementation": "Integrated source passes the full strict Release build; fresh focused native cohort improved from42/60 to49/60. Eleven failures in three groups remain and are being repaired; runtime/public qualification is open.",
66
"scope": [
77
"D1 canonical resource pairs and mandatory command coverage",
88
"Native document/query/ANN source and target authority",
99
"Effect-sensitive controlled blob OutcomeV2 and bounded native carriers",
1010
"Aspire-owned RF3 fixture image lifetime and exact17 local admission controls"
1111
],
1212
"strictBuild": {
13-
"label": "root-r544-test-bindings-final-release",
13+
"label": "root-r545-runtime-repair-release",
1414
"result": "passed",
15-
"elapsedSeconds": 364.02593612507917,
15+
"elapsedSeconds": 748.201546916971,
1616
"errors": 0,
1717
"warnings": 0,
1818
"sourceDrift": 0,
19-
"stdoutSha256": "dc48573d7b95d83fcddfe5c66332517e8fa29f369160d778e1ea45daae41156d",
20-
"completionSha256": "39f680eefbe95342d8266d383cc3efc9b9c7679b8fc8e6cf89f09ac978a6509a"
19+
"stdoutSha256": "d902546b398feacd6394651b76997e9782a17cfb7554643b3499f76f4b3aaf71",
20+
"completionSha256": "d5436d455c3af73c5173fe975de17a3a70a5973d944920f6fbd6bc8c51c27936"
2121
},
2222
"fullFormatVerify": {
2323
"label": "root-r543-token-order-final-format-verify",
2424
"result": "passed",
2525
"elapsedSeconds": 430.19493220793083,
2626
"sourceDrift": 0,
2727
"compiledDrift": 0,
28-
"completionSha256": "d5ad537e35db482c432e9a8f787dff0b4df518451451b39dfe70eefcaa7f81c4"
28+
"completionSha256": "d5ad537e35db482c432e9a8f787dff0b4df518451451b39dfe70eefcaa7f81c4",
29+
"scope": "Passed on the pre-runtime-repair source; no fresh full-format result is claimed for the later six-file runtime repair."
2930
},
30-
"focusedUnit": "OPEN: selected60 is source prediction only; native TUnit TRX and functional coverage required.",
31-
"processRecovery": "OPEN: three selected real process regressions require a fresh native run.",
31+
"focusedUnit": "FAILED: fresh native TUnit selected60,49passed,11failed,0skipped; seven original remote-document failures repaired. Query phase serialization5, scoped-budget counter oracle4 and overconstrained supporting Move budget2 remain open.",
32+
"processRecovery": "R538 passed3/3 before the later six-file runtime repair. Its original source identity remains authoritative; no fresh current-source recovery qualification is claimed.",
3233
"publicQualification": "OPEN: actual native RF3 and fresh matched one-node/three-node functional and cold flows required after product changes. Earlier e292 normal and57cea624 cold results retain their own recorded source scope.",
3334
"limits": "No full SQL, resource DROP/recreate, Linux, power-loss, endurance, performance or release completion claim. Original105 remain20done85in_progress.",
34-
"next": "Run selected native unit and recovery flows, then actual SDK/MCP RF3 and matched functional/cold gates; D2 authoritative conservative resource owner inventory is separate prepared-only work until qualified adoption."
35+
"next": "Complete the three confirmed remaining runtime groups as one repair batch, join independent native D2 source/tests and cold-user extension, then execute focused native/process and actual SDK/MCP ONE/RF3 functional and cold gates. Public DROP/recreate remains open.",
36+
"previousStrictBuild": {
37+
"label": "root-r544-test-bindings-final-release",
38+
"result": "passed",
39+
"elapsedSeconds": 364.02593612507917,
40+
"errors": 0,
41+
"warnings": 0,
42+
"sourceDrift": 0,
43+
"stdoutSha256": "dc48573d7b95d83fcddfe5c66332517e8fa29f369160d778e1ea45daae41156d",
44+
"completionSha256": "39f680eefbe95342d8266d383cc3efc9b9c7679b8fc8e6cf89f09ac978a6509a"
45+
},
46+
"focusedUnitRun": {
47+
"label": "root-r546-runtime-repair-unit",
48+
"result": "failed",
49+
"total": 60,
50+
"passed": 49,
51+
"failed": 11,
52+
"skipped": 0,
53+
"elapsedSeconds": 109.84697304177098,
54+
"sourceDrift": 0,
55+
"consumedImageDrift": 0,
56+
"stdoutSha256": "2dc131115abb57d6c6cc4e41e0d55826d6ede1c7803fe1f673419806d6e006ea",
57+
"predecessor": {
58+
"label": "root-r537-final-lifetime-unit",
59+
"passed": 42,
60+
"failed": 18
61+
},
62+
"concurrency": "PredecessorR537 actual overlapping native TRX intervals50; configured native maximum remains50.",
63+
"scope": "Full source and consumed image identities frozen; only unrelated nonconsumed IntegrationTests assembly was allowed to finish its separate compile."
64+
}
3565
},
3666
"FUNCTIONAL-COLD-20261016": {
3767
"title": "Native all-model same-root cold-reopen functional pair",

‎src/KeyLoad.Core/Features/ClusterRouting/Queries/PartitionMoveFamilyCapture.cs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ namespace KeyLoad.Core.Features.ClusterRouting.Queries;
99

1010
internal static class PartitionMoveFamilyCapture
1111
{
12+
private const int ControlOwnedPageRecords = 1;
13+
1214
internal static PartitionMoveImageFamily Capture(IKeyValueView view, PartitionMoveSourceFenceRecord fence,
1315
string family, ReadExecutionBudget work, PartitionMoveCaptureBudget captureBudget, DatabaseLimits limits, int maximumPageBytes,
1416
long maximumImageBytes, ImmutableArray<PartitionMoveImagePage>.Builder pages, ref long retained)
@@ -24,11 +26,13 @@ internal static PartitionMoveImageFamily Capture(IKeyValueView view, PartitionMo
2426
long count = PartitionMoveProtocol.EmptyCount;
2527
long rawBytes = PartitionMoveProtocol.EmptyCount;
2628
ReadOnlyMemory<byte> after = default;
29+
var controlOwned = ControlOwned(family);
2730
while (true)
2831
{
2932
work.Check();
3033
var remaining = maximumImageBytes - retained;
31-
var page = PartitionRecordPageReader.Read(view, fence.Partition, family, limits.MaxBatchMutations,
34+
var page = PartitionRecordPageReader.Read(view, fence.Partition, family,
35+
controlOwned ? ControlOwnedPageRecords : limits.MaxBatchMutations,
3236
Math.Min(maximumPageBytes, remaining), limits.MaxQueryReadBytes, captureBudget.Observe,
3337
after, work.Cancellation);
3438
foreach (var record in page.Records)
@@ -43,7 +47,7 @@ internal static PartitionMoveImageFamily Capture(IKeyValueView view, PartitionMo
4347
count = checked(count + PartitionMoveProtocol.SequenceStep);
4448
rawBytes = checked(rawBytes + record.Key.Length + record.Value.Length);
4549
}
46-
if (!ControlOwned(family) && !page.Records.IsEmpty)
50+
if (!controlOwned && !page.Records.IsEmpty)
4751
{
4852
var captured = new PartitionMoveImagePage(PartitionMoveProtocol.Version, fence.MoveId,
4953
fence.Partition, family, pages.Count, page.Records, PartitionMoveImageDigest.Records(page.Records));

‎src/KeyLoad.Core/Features/DocumentStorage/Queries/RemoteDocumentLifetimeReadAdmission.cs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ internal void ValidateRemoteDocumentReadV2(RemoteDocumentReadFrameV2 original, R
6666
var directory = PhysicalOwnerDirectorySerialization.Read(view)
6767
?? throw Errors.Fail(ErrorCode.OwnershipLost, RemoteDocumentFenceChanged);
6868
var destination = directory.Owners.Single(entry => entry.Owner.PhysicalShardId == placement.PhysicalShardId);
69-
var resource = Resource(view, reference.Partition, reference.Collection, ResourceKind.Collection);
69+
RequireNoUnpublishedPartitionMoveTarget(view, reference.Partition);
70+
// This source cut supplies authorization metadata for the admitted remote data owner.
71+
var resource = BindResourceDefinition(view, reference.Partition, reference.Collection, ResourceKind.Collection);
7072
var coverage = PartitionControlLifetimeCoverage.Capture(view, reference.Partition, [resource], Limits.MaxBatchBytes);
7173
var route = new RemoteDocumentReadFenceV1(principal.Id, principal.TenantId, principal.PolicyEpoch,
7274
placement, directory.Revision, destination);

‎tests/KeyLoad.UnitTests/Features/QueryExecution/Cases/QueryLifetimeNativeTests.cs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,12 @@ await QueryLifetimeNativeAssertions.UnchangedAsync(flow, async () =>
9494
{
9595
Coverage = null!
9696
};
97-
await QueryLifetimeNativeAssertions.RefusedAsync(() => _ = flow.Query(captured: missing), ErrorCode.OwnershipLost);
98-
await QueryLifetimeNativeAssertions.RefusedAsync(() => _ = flow.Statistics(missing), ErrorCode.OwnershipLost);
97+
await QueryLifetimeNativeAssertions.RefusedAsync(() => _ = flow.Query(captured: missing), ErrorCode.Corruption);
98+
await QueryLifetimeNativeAssertions.RefusedAsync(() => _ = flow.Statistics(missing), ErrorCode.Corruption);
99+
await QueryLifetimeNativeAssertions.RefusedAsync(() => _ = flow.Query(captured: missing, nativeRoundTrip: false),
100+
ErrorCode.OwnershipLost);
101+
await QueryLifetimeNativeAssertions.RefusedAsync(() => _ = flow.Statistics(missing, nativeRoundTrip: false),
102+
ErrorCode.OwnershipLost);
99103
var malformed = original with
100104
{
101105
Coverage = original.Coverage with

‎tests/KeyLoad.UnitTests/Features/QueryExecution/Helpers/QueryLifetimeNativeFlow.cs‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ internal ResourceLifetimeCoverageV1 CreateOtherLifetime()
8080
}
8181

8282
internal PartitionQueryLeafResultV1 Query(string path = QueryLifetimeNativeProtocol.Star,
83-
PartitionQueryLifetimeMetadata? captured = null, Predicate? filter = null)
83+
PartitionQueryLifetimeMetadata? captured = null, Predicate? filter = null, bool nativeRoundTrip = true)
8484
{
8585
var metadata = captured ?? Capture();
8686
var database = fixture.Destination.Database;
@@ -94,14 +94,16 @@ internal PartitionQueryLeafResultV1 Query(string path = QueryLifetimeNativeProto
9494
var input = new PartitionQueryOwnedLeafRequestV2(new(plan,
9595
PhysicalOwnerDirectoryWholeFlow.Destination.Owner, RemoteDocumentNativeFixture.Tenant),
9696
metadata.Definition, metadata.Coverage, metadata.Principal);
97-
var roundTrip = NativeSerialization.Deserialize<PartitionQueryOwnedLeafRequestV2>(NativeSerialization.Serialize(input));
97+
var roundTrip = nativeRoundTrip
98+
? NativeSerialization.Deserialize<PartitionQueryOwnedLeafRequestV2>(NativeSerialization.Serialize(input)) : input;
9899
return PartitionQueryLifetimeLeafExecution.Execute(engine, RemoteDocumentNativeFixture.Reader, roundTrip,
99100
PhysicalOwnerDirectoryWholeFlow.Destination.Owner, database.EvaluationClock,
100101
database.EvaluationClock.GetUtcNow() + TimeSpan.FromSeconds(database.Limits.QueryDeadlineSeconds), CancellationToken.None);
101102
}
102103

103104
internal DistributedSearchLeafResultV1 Statistics(PartitionQueryLifetimeMetadata? captured = null,
104-
string field = RemoteDocumentNativeFixture.Title, string text = QueryLifetimeNativeProtocol.Text)
105+
string field = RemoteDocumentNativeFixture.Title, string text = QueryLifetimeNativeProtocol.Text,
106+
bool nativeRoundTrip = true)
105107
{
106108
var metadata = captured ?? Capture();
107109
var database = fixture.Destination.Database;
@@ -112,9 +114,10 @@ internal DistributedSearchLeafResultV1 Statistics(PartitionQueryLifetimeMetadata
112114
PhysicalOwnerDirectoryWholeFlow.Destination.Owner, RemoteDocumentNativeFixture.Tenant,
113115
database.Limits.MaxQueryReadBytes, database.Limits.MaxScanRecords,
114116
QueryResultBudgetPolicy.Resolve(database.Limits, UnitExecutionOptions.QueryExecution().Value)
115-
/ QueryLifetimeNativeProtocol.GrantDivisor, null, null, null, null, []);
117+
/ QueryLifetimeNativeProtocol.GrantDivisor, null, null, null, null, default);
116118
var input = new DistributedSearchOwnedLeafV2(original, metadata.Definition, metadata.Coverage, metadata.Principal);
117-
var roundTrip = NativeSerialization.Deserialize<DistributedSearchOwnedLeafV2>(NativeSerialization.Serialize(input));
119+
var roundTrip = nativeRoundTrip
120+
? NativeSerialization.Deserialize<DistributedSearchOwnedLeafV2>(NativeSerialization.Serialize(input)) : input;
118121
return DistributedSearchOwnedLeafExecution.ExecuteV2(database, RemoteDocumentNativeFixture.Reader,
119122
roundTrip, PhysicalOwnerDirectoryWholeFlow.Destination.Owner, UnitExecutionOptions.QueryExecution(),
120123
database.EvaluationClock, database.EvaluationClock.GetUtcNow() + TimeSpan.FromSeconds(database.Limits.QueryDeadlineSeconds),

‎tests/KeyLoad.UnitTests/Features/ResourceExecution/Assertions/ResourcePairBindingAssertions.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ await EqualAsync(new DocumentResult(new(state.Source.Partition, Documents, value
5858
var page = database.ReadStream(Root, stream);
5959
await EqualAsync(new StreamHead(FirstRevision, FirstRevision, FirstRevision), page.Head);
6060
await EqualAsync(new EventRecord(stream, FirstRevision, value.Sequence,
61-
new(value.Id, EventType, EventJson), value.Time), page.Events.Single());
61+
new(value.Id, EventType, StoredEventJson), value.Time), page.Events.Single());
6262
await EqualAsync(new StreamPage(stream, new(FirstRevision, FirstRevision, FirstRevision),
63-
[new(stream, FirstRevision, value.Sequence, new(value.Id, EventType, EventJson), value.Time)],
63+
[new(stream, FirstRevision, value.Sequence, new(value.Id, EventType, StoredEventJson), value.Time)],
6464
database.Store.Position, false, null, database.Store.Position), page);
6565
await EqualAsync(new MessageInspection(new(value.Id, MessageState.Ready, Zero, FirstRevision, value.Sequence, null, null),
66-
QueueJson, Headers), database.InspectMessage(Root, new(state.Source.Partition, Queue), value.Id)!);
66+
StoredQueueJson, Headers), database.InspectMessage(Root, new(state.Source.Partition, Queue), value.Id)!);
6767
}
6868
foreach (var row in state.Rows)
6969
{

‎tests/KeyLoad.UnitTests/Features/ResourceExecution/Contracts/ResourcePairBindingProtocol.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ internal static class ResourcePairBindingProtocol
3030
internal const string LifetimeSpace = "resource-lifetime-v1";
3131
internal const string DocumentJson = """{ "amount": 17, "raw": "\u0061" }""";
3232
internal const string EventJson = """{"kind":"Created","amount":17}""";
33+
internal const string StoredEventJson = """{"amount":17,"kind":"Created"}""";
3334
internal const string QueueJson = """{"job":"pair","amount":17}""";
35+
internal const string StoredQueueJson = """{"amount":17,"job":"pair"}""";
3436
internal const string EventType = "Created";
3537
internal const string Headers = "{}";
3638
internal const string PutKind = "putDocument";

0 commit comments

Comments
 (0)