diff --git a/docs/research/2026-09-01-overhaul/474-portal-reveal-diagnosis.md b/docs/research/2026-09-01-overhaul/474-portal-reveal-diagnosis.md index dd86aa49..b30f47b7 100644 --- a/docs/research/2026-09-01-overhaul/474-portal-reveal-diagnosis.md +++ b/docs/research/2026-09-01-overhaul/474-portal-reveal-diagnosis.md @@ -94,7 +94,7 @@ dependency, not an ACE response timeout. The log's preceding slow portal is not yet proven to have the same cause. Existing tests prove these halves separately: -`RuntimeCollisionMutationTransactionTests.ActivationWaitsForExactWithdrawAndPlaceReceipts` +`RuntimeCollisionPrefixQuiescenceTests.ActivationWaitsForExactWithdrawAndPlaceReceipts` manually acknowledges without the graphical loaded-backend gate; `RuntimePlacementPresentationSinkTests.Place_WithoutLoadedDestinationBackendRemainsPending...` proves the gate while assuming streaming can independently finish. diff --git a/docs/research/2026-09-01-overhaul/474-publication-repair-contract.md b/docs/research/2026-09-01-overhaul/474-publication-repair-contract.md new file mode 100644 index 00000000..497dd958 --- /dev/null +++ b/docs/research/2026-09-01-overhaul/474-publication-repair-contract.md @@ -0,0 +1,175 @@ +# #474 bounded repair — destination backend before restore acknowledgement + +Status: lead contract, round0, 2026-09-05. Diagnosis/evidence base +`3a9d5b01a881e56bd93211a5f78a80ea2767a7c0`. This is the immediate S5/G4 blocker; +C1c and section45 geometry work remain preserved/unmodified. + +## 1. Outcome and bounds + +Repair the captured same-prefix collision-refresh/reveal cycle in +`474-portal-reveal-diagnosis.md`. Keep the exact graphical Place receipt gate: +its destination backend must actually exist before acknowledgement. Do not +force reveal, reduce the reveal window, add a timeout, bypass FIFO identity, +invent placement authority, rebuild DAT assets, or change renderer geometry. +Do not alter Runtime's collision/placement algorithm or Headless semantics. + +Expected production scope: + +- `src/AcDream.App/Streaming/LandblockPresentationPipeline.cs`; +- `src/AcDream.App/Streaming/StreamingController.cs`; +- `src/AcDream.App/Streaming/GraphicalRemotePlacementServiceWindow.cs`; +- `src/AcDream.App/Composition/SessionPlayerComposition.cs`. + +`LandblockPhysicsPublisher.cs` is allowed only if required to preserve its +post-engine cancellation/acknowledgement lifecycle, with an exact test. +No other production file without a lead contract amendment. +Tests: concrete-pipeline, controller-readiness and remote-service-window +tests; one focused new test/fixture file if sharing the real Runtime/sink +composition cannot be cleanly expressed in the existing concrete fixture. +Mechanical constructor updates in directly affected tests are allowed. +Do not duplicate a production owner or add a generic evidence framework. +Update the architecture publication paragraph and AD-2 in the same repair +commit; this ordering is an explicit async adaptation, not a retail algorithm. + +## 2. Stage-order contract + +1. Extract the existing spatial publication operation into one retained, + reusable helper. Preserve ONE `GpuWorldState.MutationBatch` around canonical + bucket commit, activation/pins/scripts, static projection reconciliation + and outer observer delivery. Preserve `SpatialCommitted` and + `SpatialPresentationCommitted` exact-once/retry semantics; do not split + bucket mutation from activation across observable transactions. +2. While concrete physics completion is nonterminal, permit that helper ONLY + after `EngineMutationCommitted && RuntimeMutationPending`. The immutable + replacement is then canonical and can never be resealed or rolled back. + Make the backend available before yielding solely for restore receipts. + Preserve the existing later helper call for ordinary/no-debt publication. +3. Do not mark physics complete, static plugin complete or presentation complete + early. Their exact original order remains: physical activation's full ACK + suffix, then static plugin snapshots. Earlier backend activation may run + pins/default-script/observer work before that suffix in the affected case; + document that actual change rather than claiming all ordering is unchanged. +4. Add one borrowed exact-landblock presentation-ready query from the existing + retained transactions. A transaction blocks admission while either + `!PresentationCommitted` or `!SpatialPresentationCommitted`. No mirror map, + persistent second owner or per-frame `ToArray` is required. Do NOT extend + this fence through later EnvCell replay/live recovery, which were downstream + of the former observable boundary already. +5. `StreamingController.IsRenderNeighborhoodResident` and the real graphical + remote-placement service window must consume that same ready query. Near + tier/render-ready alone no longer proves the full prefix is complete. + Wire the latter through the existing controller in SessionPlayerComposition; + no production default/fallback may silently omit this fence. Preserve + canonicalization and existing Far/Near/demotion semantics. Existing portal + generation availability still prevents drawing/picking/simulation early. +6. Every step remains on the existing meter. Do not busy-spin for a callback, + reserve work twice, bypass the meter from a Settings/reset callback, repeat + static scripts or report completion while an exact suffix is outstanding. + +### Cancellation hole that MUST be exercised + +The engine transfer can succeed just as the meter expires BEFORE the early +spatial helper runs. A later recenter/reset calls CancelPendingPublications; +`LandblockPhysicsPublication.TryCancel` sets CancellationRequested and Runtime +then waits on the same restore ACK. Ordinary AdvanceCompleteOne refuses a +cancelled publication. Therefore testing only cancellation AFTER the backend +is installed is insufficient. Explicitly cover cancellation between engine +transfer and backend activation, including a yielded/throwing activation. +Keep the committed engine; resume only the required metered backend/ACK suffix +under exact retained ownership, then let the existing retirement flow detach +and clean it. No post-engine rollback, unmetered hidden resume or leaked +ready fence. If this needs a broader owner/API change, report the exact seam +to the lead before making it. + +## 3. Mandatory discriminating regressions + +Use the real shared `RuntimeEntityObjectLifetime`, real collision activation, +`RuntimePlacementProjectionSubscription`, `RuntimePlacementPresentationSink`, +`LiveEntityRuntime`, `GpuWorldState`, and concrete publication owners. Reuse +the setup recipe in `RuntimeForcePositionRenderCommitTests.HostFixture` where +appropriate. A manual ACK, fake sink, preset completion flag or fake ready +predicate alone does not prove the regression. + +- **T1 captured topology:** a resident in the target prefix, graphics backend + detached/missing, genuine collision refresh. Observe EngineCommitted=true, + physics/static completion=false, actual same-prefix Place at global head, + and backend becoming loaded. At that boundary full neighborhood readiness + and production-shaped remote service window MUST remain false. Drive the + real host retry; assert the exact token retires, publication completes, + readiness opens, and that exact incarnation is resident exactly once. +- **T2 two residents:** same setup with at least two residents; assert exact + ordered receipt identities, no bypass and eventual complete ownership. +- **T3 metering:** small entity budget and deterministic clock exhaustion at + the post-engine/pre-backend edge. Next admissible frame must make progress; + limits hold, engine transfer and completed prefix effects never repeat. +- **T4 cancellation/retry:** both before and after backend activation after + engine transfer; include an injected activation/reconciliation failure. + Preserve no-rollback, exact suffix retry, balanced pins/scripts and eventual + withdrawal/retirement. Test the real controller cancellation path where the + meter/retained publication interaction matters, not only `TryCancel` alone. +- **T5 admission controls:** unpublished/pending-only/Far remains rejected; + completed Near accepted; incomplete unrelated landblock does not block the + selected destination; complete presentation with later replay/recovery + pending preserves the prior admission boundary. No constructor bypass. +- **T6 boundary control:** genuine collision refresh near an outdoor seam, + with adjacent-prefix result/backends recorded. Do not assert the result must + remain in-prefix simply because the park started there. If a valid restore + reaches an absent adjacent backend and the FIFO blocks its publication, + report that counterexample; this one-publication repair is insufficient. + No universal cross-prefix closure claim without evidence. + +Before the fix, run T1 against unchanged source and record its first failure +(or equivalently restore just the old publication order as a test mutation). +Independently remove each admission fence and require its own early-admission +assertion to fail. Restore every mutation byte-identically. Do not classify +compile errors or incidental setup failures as discriminating evidence. + +Run the complete directly affected App test classes, existing Runtime +`RuntimeCollisionPrefixQuiescenceTests`, existing placement-sink/subscription +regressions and the Release build. Record literal command, exit, counts, +first failure and restored state. Full canonical lanes and graphical route +follow review/landing; do not claim them from a narrow filter. + +## 4. Lead retail/binary verification (performed before implementation) + +The lead read the named `LScape::grab_visible_cells @0x00504EC0` body and +independently section-mapped `C:\Turbine\Asheron's Call\acclient.exe` without +launching or attaching to retail. SHA256: +`006FFEADC5D679C871497112A5BD1F87714D0E273E2166BAE5052DDE369297B1`; +CodeView`9E847E2F-777C-4BD9-886C-22256BB87F32`, age1. The138-byte function +window hashes to +`FD51D370B9798EAECCFC2D971D8A88F941D13CFA2506C4831879043B4ACAE906`. + +| Call site | Paired bytes | Resolved named target | +|---|---|---| +| 00504EE7 | E894AE0200 | CLandBlock::init_buildings0052FD80 | +| 00504EEE | E86DA50200 | CLandBlock::grab_visible_cells0052F460 | +| 00504F29 | E812BB0200 | CLandBlock::init_static_objs00530A40 | +| 00504F30 | E87BA40200 | CLandBlock::init_dyn_objs0052F3B0 | + +Retail's first landscape pass initializes buildings/visible cells; its second +initializes static then dynamic objects. Preserve the existing render/building +prefix before static collision construction. The modern engine-commit / host +receipt / metered spatial backend split has NO literal retail counterpart; +AD-2 owns it. This check does not prove all publication callbacks equivalent +to retail and does not expand AP-151's longer-hold claim into a timing fix. + +## 5. Execution, review, gate + +One OpenAI implementer in a fresh `codex/` scratch worktree rooted at this +contract commit; lead reviews/commits. No Claude/Anthropic execution. At most +ten independent review passes per owner override; every code finding gets a +bounded fix contract and docs-only findings are corrected directly. Sequential +retail/behavior then production/lifetime/gate-honesty review; no reviews claimed +in advance. Stop and report any broader required change rather than silently +including it. + +AcDream must be absent before build/test. Owner explicitly keeps retail open: +leave it untouched, use offline builds/tests only during implementation, no +new graphical launch, debugger attach, heap capture or performance claim by +the implementer. Recheck processes. The lead's later Release graphical gate +must use one client/run per background command, record exact binary/package, +PASS/FAIL and PNGs, and close its own run gracefully. Repeated adjacent hop, +long-distance hop and indoor control must converge; record actual latency and +competing process state, never hide a long wait behind a pass count. Owner +acceptance is still required for G4. No merge main. diff --git a/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md b/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md index 68d5ff1a..bb0f8079 100644 --- a/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md +++ b/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md @@ -4408,3 +4408,15 @@ graphical re-gate. Preserve receipt identity, no post-engine rollback, metering and readiness. C1c remains review-closed/unlanded; section45 geometry activation and full lanes/C2 follow this blocker, not in parallel with its implementation. No merge main before G4. + +## 47. #474 repair contract (2026-09-05) + +`474-publication-repair-contract.md` bounds the repair and mandatory composed +regressions. It permits the existing observer-atomic spatial operation after +engine commit but before restore acknowledgement, while retaining the original +physics/static-plugin completion order and explicit readiness/service-window +fences. It calls out cancellation after engine transfer but before a metered +backend step as a mandatory test, and requires a real cross-prefix seam control +before claiming broader closure. The lead independently verified the named +landscape initialization order against the paired PE; the modern receipt split +remains an AD-2 adaptation. Implementation/reviews/gates are not yet claimed.