Skip to content

Commit 922a9f3

Browse files
committed
Repair RF3 bootstrap admission and retain native test identity
1 parent 876c523 commit 922a9f3

16 files changed

Lines changed: 429 additions & 28 deletions

File tree

‎.github/workflows/build-and-tests.yml‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ jobs:
116116
- name: Build KeyLoad
117117
id: build
118118
run: dotnet build KeyLoad.slnx --no-restore --configuration Release
119+
- name: Prepare native source and test-image identity receipts
120+
id: native-source-identity
121+
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
122+
shell: pwsh
123+
run: |
124+
$root = $env:GITHUB_WORKSPACE
125+
$evidence = Join-Path $root 'TestResults/native-source-identity'
126+
& pwsh -NoLogo -NoProfile -File scripts/Features/CodeQuality/functional-coverage.production-source-manifest.ps1 `
127+
-Mode prepare -Root $root -EvidenceRoot $evidence
128+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
119129
- name: Verify the pinned native full-text package
120130
run: |
121131
node --input-type=module <<'JS'
@@ -175,6 +185,15 @@ jobs:
175185
- name: Test recovery after process crashes
176186
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
177187
run: node scripts/Features/TestInfrastructure/run-tests.mjs --KeyLoadTests:Suite=recovery --KeyLoadTests:ReportTrx=true
188+
- name: Verify native source and test-image identity receipts
189+
if: ${{ !cancelled() && steps.build.outcome == 'success' && steps.native-source-identity.outcome == 'success' }}
190+
shell: pwsh
191+
run: |
192+
$root = $env:GITHUB_WORKSPACE
193+
$evidence = Join-Path $root 'TestResults/native-source-identity'
194+
& pwsh -NoLogo -NoProfile -File scripts/Features/CodeQuality/functional-coverage.production-source-manifest.ps1 `
195+
-Mode verify -Root $root -EvidenceRoot $evidence
196+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
178197
- name: Save test results
179198
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
180199
if: always()

‎README.md‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,14 @@ KL-075 now has its first scaling source stage; six-node, open-loop, shard-skew,
337337
fanout, recovery and movement acceptance remains open. The joined stage has
338338
passed the local Release build with zero analyzer errors and warnings. The current
339339
native process-recovery suite passed **235/235**, with no skips. The latest full
340-
uninstrumented unit report, before the ANN test-scheduling correction, passed
341-
**2,762/2,763**, with one ANN construction deadline failure and no skips.
342-
Complete normal/scalar reruns and delivered-source Linux qualification remain
343-
open. The [original Linux source788 run](docs/implementation/runtime-qualification-37349838022.json)
344-
passes the official MCP SDK guidance case but fails the complete RF3 and release
345-
gates. [Checkpoint evidence](docs/implementation/partition-runtime-development-2026-10-05.json)
346-
keeps those failures and the remaining scalar, recovery, RF3 and scale gates explicit.
340+
uninstrumented unit report passed **2,763/2,763**. The [original Linux run at
341+
876c5237](https://github.com/managedcode/KeyLoad/actions/runs/37546085722)
342+
also passed normal and scalar **2,763/2,763** and recovery **235/235** without skips.
343+
The subsequent RF3 bootstrap admission and membership-image assertion fixes pass
344+
the local Release build and focused normal/scalar tests; their complete current-source
345+
reruns remain open. RF3, functional coverage, scale and release qualification remain
346+
open. The [implementation status](docs/implementation/status.json) records each
347+
source and report boundary.
347348

348349
Functional coverage excludes load/comparison runs and admits complete operation
349350
flows only. The current Query profile binds exactly 25 named cases and 103 source

‎docs/ADR/ADR-005-canonical-keyspace-codec.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,22 @@ normal/scalar suites at2889/2889 each, recovery228/228 and1000 unique actual
106106
atomic process cuts. Literal fractional decimal goldens pass under invariant
107107
and custom-sign cultures. Exact delivered-source Linux/RF3 originals, endurance,
108108
power-loss and measured acceleration remain separate required gates.
109+
110+
TASK-KEYCODEC-NATIVE-IDENTITY makes the existing exact-source Linux review
111+
concrete. The Build and Tests `verify` job prepares the unchanged native
112+
CodeQuality production-source manifest and test-image sidecars immediately
113+
after its Release solution build, runs the original normal/scalar/full-recovery
114+
commands, then verifies those same receipts and uploads them with the original
115+
reports. Root freezes and reviews this contract; the workflow owner changes only
116+
`.github/workflows/build-and-tests.yml` and joins on the existing
117+
`functional-coverage.production-source-manifest.ps1` prepare/verify calls. Review
118+
the 33 owned KL-007 source rows and original source/run/attempt/artifact provenance
119+
against the executed UnitTests and RecoveryTests DLL/PDB hashes, MVID,
120+
portable-PDB and compiler-source identities from that same build. A different
121+
job's rebuilt images cannot establish this binding. This adds no schema, binary
122+
archive, format change, test subset or new acceptance prerequisite. All18 mapped
123+
normal/scalar cases and the original unfiltered recovery stage must pass; other
124+
failures remain visible and RF3/endurance/power-loss gates remain separate.
125+
Verification comprises the existing native source-ownership regressions,
126+
workflow static checks, and the original Linux artifacts. Rollback removes only
127+
the additive workflow receipt steps; no storage or runtime rollback is needed.

‎docs/ADR/ADR-042-admission-resource-ownership.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,29 @@ actual configured Linux GitHub gates.
9595

9696
Primary guidance: [CA2000 ownership transfer](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2000)
9797
and [async disposal](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync).
98+
99+
## Physical catalog startup control admission
100+
101+
TASK-ADM-CATALOG-BOOTSTRAP implements the ResourceExecution refinement of
102+
REQ-RESOURCE-001 / AC-RESOURCE-001 and REQ-ADM-001 / AC-ADM-001. Original Linux
103+
run37541109923 rejects `BootstrapPhysicalShardCatalog` during node1 startup at
104+
`PhysicalShardCatalogStartup.SubmitBootstrapAsync`; its ordinary data ceiling is
105+
4,096 bytes, exactly the governor's envelope floor, and serialized bootstrap
106+
work cannot fit. Node2's subsequent unavailable-majority error is secondary.
107+
The initial catalog mutation must use the existing bounded control reserve.
108+
It remains administrator-authenticated, authorized and RF3 committed through
109+
the same unique request grain; no admission or credential bypass is introduced.
110+
111+
Root freezes this contract, the worker changes only
112+
`src/KeyLoad.Core/Features/ResourceExecution/Commands/CommandAdmissionGovernor.cs`
113+
and its existing `CommandAdmissionGovernorTests.cs`, then root reviews and joins
114+
strict build/format, focused normal/scalar governor operations and the unchanged
115+
actual Aspire RF3 admission case. Add only the existing bootstrap operation kind
116+
to the reserved classifier; preserve every lane ceiling and shared replication
117+
or inbox consumer. The regression executes full data/control reserve,
118+
rejection, exact lease release and healthy reuse, rather than asserting the
119+
classifier result alone. Delivered qualification requires the original Linux
120+
SDK/control/RF3 flow; source or local governor success cannot establish it.
121+
No wire, storage, deployment, format or dependency change is needed. Rollback
122+
removes only this operation's classifier inclusion and its matching regression;
123+
the original startup failure remains unqualified until real execution passes.

‎docs/ADR/ADR-106-partition-owner-movement.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,22 @@ integration, strict checks, original Linux RF3 evidence and commit. No stored-da
222222
an unmapped route or undisposed owner cannot be reported as delivered membership.
223223

224224
Ownership movement and current same-view session tokens retain the contract in [ADR-017](ADR-017-ownership-session-tokens.md). Unknown or unverifiable lineage invalidates explicitly.
225+
226+
## Native immutable-image oracle repair
227+
228+
TASK-MEMBERSHIP-IMAGE-ORACLE implements the existing AC-MEMBERSHIP-006 pre-start
229+
identity check using pinned Aspire13.6.0 semantics. The native
230+
[`WithImageSHA256` implementation](https://github.com/dotnet/aspire/blob/v13.6.0/src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs)
231+
stores its supplied digest unchanged and retains tag metadata; native
232+
[`TryGetContainerImageName`](https://github.com/dotnet/aspire/blob/v13.6.0/src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs)
233+
adds the `@sha256:` separator for the runtime reference. The accepted KeyLoad
234+
builder already supplies the unprefixed digest correctly. Repair only the
235+
existing test oracle's contradictory null-tag/prefixed-digest expectations.
236+
Root freezes this contract before the worker changes
237+
`tests/KeyLoad.IntegrationTests/Features/ClusterRouting/Assertions/TwoRf3MembershipImageAssertions.cs`;
238+
root reviews and joins strict build/format and the unchanged actual six-container
239+
startup, signed membership, closed-client and teardown flow. Require exact
240+
accepted repository/tag/digest metadata and exact resolved reference for all
241+
six nodes before Start. No new helper, image/provider replacement, deployment
242+
change, bound increase or omitted assertion is required. Rollback changes only
243+
the test expectation; actual Linux RF3 evidence remains required and unqualified.

‎docs/AGENTS.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@
2222
- Read the [root policy](../AGENTS.md), [architecture map](Architecture.md), [RepositoryGovernance feature](Features/RepositoryGovernance.md), and [ADR-032](ADR/ADR-032-mcaf-governance.md) first.
2323
- This documentation module owns durable records for all canonical slices: `RepositoryGovernance`, `BenchmarkComparisons`, `DocumentStorage`, `EventStreams`, `Messaging`, `GraphTraversal`, `TimeSeries`, `Search`, `QueryExecution`, `Authorization`, `ChangeFeeds`, `StorageRecovery`, `ClusterReplication`, `ClusterRouting`, `ClientApi`, and `BackupRestore`.
2424
- Feature docs use `Features/<SliceName>.md`; architecture, implementation and ADR records remain under their existing global documentation roots.
25+
26+
## Native TUnit entry, owner correction 2026-10-07
27+
- ADR-117 and the root's latest native-entry correction supersede the earlier outer AppHost test commands here. CI invokes native TUnit/Microsoft.Testing.Platform directly after build with Detailed output; C# fixtures own Aspire startup, readiness, discovered endpoints, real client workloads and joined cleanup. `scripts/Features/TestInfrastructure/run-tests.mjs` selects native arguments and environment only. Preserve every required suite, original report, exact-source Linux gate and development/qualification distinction.
28+
- The canonical current Build and Tests workflow is `.github/workflows/build-and-tests.yml`; historical `ci.yml` references above are not current dispatch instructions.

‎docs/Features/Authorization.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ the cluster control boundary is defined by [ADR-036](../ADR/ADR-036-orleans-foun
1111
| REQ-AUTH-002: public credential changes cannot disable or impersonate the cluster's membership authority | AC-AUTH-002: a persisted protected internal principal has no public API key; even an administrator cannot edit it or create a credential for it; revoking a public administrator does not revoke internal membership |
1212
| REQ-AUTH-003: internal authority can perform only its approved membership control operation | AC-AUTH-003: ordinary callers cannot submit Membership; the internal principal cannot submit data/security operations; real store outcomes preserve exact denial and unchanged effects |
1313

14+
15+
### Current unit case-to-acceptance crosswalk
16+
17+
| Native case class | Existing requirement / acceptance | Evidence boundary |
18+
|---|---|---|
19+
| `ClusterPrincipalPolicyTests`, `ClusterPrincipalInitializationIntegrityTests` | REQ-AUTH-002 / AC-AUTH-002 | Protected internal-principal bootstrap/idempotence, public edit/credential denial, snapshot copy, and missing/modified/corrupt row rejection at an existing apply cut. This is local store/snapshot evidence, not quorum or RF3 proof. |
20+
| `ClusterPrincipalAuthorizationTests` | REQ-AUTH-003 / AC-AUTH-003 | Ordinary/public internal-membership denial, internal data/security denial, and internal membership after public-root revocation. |
21+
| `DocumentRowTenantMutationAuthorizationTests` | REQ-AUTH-005 / AC-AUTH-005, with the owning document boundary REQ-DSTORE-003 / AC-DSTORE-003 | Put/Patch/Delete cannot forge row owner or tenant. It does not cover all row-scoped read/query adapters. |
22+
| `DocumentFieldMutationAuthorizationTests`, `DocumentReplacementFieldAuthorizationTests`, `DocumentDeleteIndexAuthorizationTests` | REQ-AUTH-006 / AC-AUTH-006, with the owning document boundary REQ-DSTORE-003 / AC-DSTORE-003 | Persisted field-write and index-use grants are independently enforced on the tested mutation paths; this is not the complete adapter/lineage matrix. |
23+
| `ResourcePolicyUpdateTests`, `ResourcePolicyUpdateRejectionTests`, `ResourcePolicyUpdateVisibilityTests` | See the exact REQ-RPOL-001..004 mapping in [ResourcePolicyUpdates](Authorization/ResourcePolicyUpdates.md) | The unit cases map to RPOL-001/002/003; RPOL-004 remains the real SDK/MCP RF3 criterion. The blob-quota exclusion case is validator-only, not a store-apply flow. |
24+
25+
`SignedEnvelopeTests` is physically under the Authorization test directory but
26+
is owned by InternalSerialization: map it only to REQ-IS-007 / AC-IS-007 in
27+
[InternalSerialization acceptance](InternalSerialization/Acceptance.md#requirements-and-acceptance).
28+
It is not evidence for public credential verification or persisted principal
29+
authorization.
30+
31+
1432
Slice map: new policy code `src/KeyLoad.Core/Features/Authorization/`; focused
1533
tests mirror `tests/KeyLoad.UnitTests/Features/Authorization/`. HTTP/MCP adapters
1634
remain ClientApi and invoke Orleans request grains. Principals/API keys remain

‎docs/Features/ClusterRouting/PartitionTransfer.md‎

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ above against actual ZoneTree/TestDatabase primitives, without mocks, fake view,
5252
skips or weakened limits. Preserve callbacks' borrowed lifetime. Root reviews
5353
the complete private packets, then executes Aspire normal/scalar tests.
5454

55-
Complete ownership is a later root-owned stage. Current epoch7 outcome keys have
56-
no partition locator; their hash cannot recover one. Copying every global outcome
57-
or dropping outcomes is incorrect. Existing-store migration needs its exact
58-
accepted upgrade/rollback contract. Current persisted authorization remains
55+
Complete ownership is a later root-owned stage. Global control outcomes have no
56+
movable partition locator; their hash cannot recover one. Copying every global
57+
outcome or dropping outcomes is incorrect. The current product must preserve
58+
explicit partition-associated outcomes and shared control authority without a
59+
data conversion or alternate reader. Current persisted authorization remains
5960
authority and an acknowledged revocation must fence all serving groups. Source
6061
and destination group indexes are never directly comparable; explicit ownership
6162
epoch invalidation is the first candidate under KL-072, pending full freeze.
@@ -81,7 +82,7 @@ flowchart LR
8182
Page --> Later[Later complete ownership and fenced transfer]
8283
```
8384

84-
The accepted native epoch/outcome prerequisite is [TokenOwnershipLineage](TokenOwnershipLineage.md), REQ/AC-PMOVE-005..006 and REQ/AC-MTOKEN-001..004 under ADR-017. Its partition-associated locator is additive; global authority and old unknown-scope outcomes remain explicit complete-image blockers. Family pages or a locator alone do not authorize installation or cutover.
85+
The accepted native epoch/outcome prerequisite is [TokenOwnershipLineage](TokenOwnershipLineage.md), REQ/AC-PMOVE-005..006 and REQ/AC-MTOKEN-001..004 under ADR-017. Its partition-associated locator is part of the current product; shared global authority remains an explicit complete-image dependency. Family pages or a locator alone do not authorize installation or cutover.
8586

8687

8788
# Accepted Stage 1A: shared Orleans membership; later physical movement contracts
@@ -92,7 +93,7 @@ Related: [PartitionTransfer](PartitionTransfer.md), [PhysicalShardCatalog](Physi
9293

9394
## Scope and source-backed boundary
9495

95-
The original plan requires controlled copy/catch-up/barrier/switch/cleanup (KL-036), whole atomic partitions with generation readiness and restartable cleanup (KL-071), and either a supported old-token invalidation or correct lineage translation without comparing independent log positions (KL-072). Current contracts intentionally stop before those operations: AC-PMOVE-004 forbids an installer, `AtomicPartitionPlacementV1` only resolves to the single committed `DefaultShard`, `PhysicalShardCatalog` only boots epoch 1, and AC-MTOKEN-004 explicitly excludes epoch bump/cross-group cutover. This proposal is a new movement contract; it does not reclassify current PMAP, bounded pages, token issuance, outcome association or prior-frame compatibility as movement. Source anchors: `docs/design/architecture-v0.3.uk.md` §§4, 6, 28 and KL-036/071/072; `docs/ADR/ADR-016-atomic-physical-placement.md` §§1–5; `docs/ADR/ADR-017-ownership-session-tokens.md`; current `PhysicalShardCatalog`/`AtomicPartitionPlacement` and `PartitionTransfer` contracts.
96+
The original plan requires controlled copy/catch-up/barrier/switch/cleanup (KL-036), whole atomic partitions with generation readiness and restartable cleanup (KL-071), and either pre-movement token invalidation or correct lineage translation without comparing independent log positions (KL-072). Current contracts intentionally stop before those operations: AC-PMOVE-004 forbids an installer, `AtomicPartitionPlacementV1` only resolves to the single committed `DefaultShard`, `PhysicalShardCatalog` only boots epoch 1, and AC-MTOKEN-004 explicitly excludes epoch bump/cross-group cutover. This proposal is a new movement contract; it does not reclassify current PMAP, bounded pages, token issuance, outcome association or current-frame recovery as movement. Source anchors: `docs/design/architecture-v0.3.uk.md` §§4, 6, 28 and KL-036/071/072; `docs/ADR/ADR-016-atomic-physical-placement.md` §§1–5; `docs/ADR/ADR-017-ownership-session-tokens.md`; current `PhysicalShardCatalog`/`AtomicPartitionPlacement` and `PartitionTransfer` contracts.
9697

9798
Stable identity remains the complete four-field `PartitionRef` / `AtomicPartitionId`. Physical shard identity remains a separate opaque ID for an independently configured RF3 replica group. A node-local `PartitionHost` owns its canonical ZoneTree store, replica log, file locks, materializer and apply gate. Orleans activation migration changes no physical ownership. Replica voters and Orleans silos are not separate logical shards.
9899

@@ -361,3 +362,21 @@ transport/test ownership, and root owns integration and native evidence.
361362
There is no data/wire migration. Rollback disables the explicit profile and
362363
cannot retain an unmapped authority handler or abandoned disposable owner as a
363364
working six-node implementation.
365+
366+
### Native immutable-image oracle repair
367+
368+
TASK-MEMBERSHIP-IMAGE-ORACLE repairs the pre-start test oracle for the existing
369+
AC-MEMBERSHIP-006. `RuntimeContainerImage.Add` supplies the accepted tag and the
370+
64-character digest separately to native Aspire13.6.0. Its image annotation
371+
retains the tag and stores the digest without the `sha256:` prefix; the native
372+
resolved reference uses `repository@sha256:digest`. The current test's null-tag
373+
and prefixed-annotation assertions reject that valid pinned configuration before
374+
any of the six resources starts. Require the exact accepted repository, tag and
375+
digest metadata plus exact native resolved reference on all six resources;
376+
retain the existing fail-before-start mismatch behavior and actual six-container
377+
startup, signed membership, closed public calls and joined teardown. The patch
378+
owns only `TwoRf3MembershipImageAssertions.cs`; no image construction, profile,
379+
credential, topology, timeout or production behavior changes. Root freezes and
380+
reviews the contract, the worker prepares the guarded correction, and root joins
381+
strict build/format plus the existing exact-source Linux RF3 case. Source review
382+
alone does not qualify membership. Rollback restores only the prior test oracle.

0 commit comments

Comments
 (0)