docs(overhaul): bound portal publication acknowledgement repair #474

This commit is contained in:
Erik 2026-09-05 09:11:25 +02:00
parent 3a9d5b01a8
commit 31960039be
3 changed files with 188 additions and 1 deletions

View file

@ -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. not yet proven to have the same cause.
Existing tests prove these halves separately: Existing tests prove these halves separately:
`RuntimeCollisionMutationTransactionTests.ActivationWaitsForExactWithdrawAndPlaceReceipts` `RuntimeCollisionPrefixQuiescenceTests.ActivationWaitsForExactWithdrawAndPlaceReceipts`
manually acknowledges without the graphical loaded-backend gate; manually acknowledges without the graphical loaded-backend gate;
`RuntimePlacementPresentationSinkTests.Place_WithoutLoadedDestinationBackendRemainsPending...` `RuntimePlacementPresentationSinkTests.Place_WithoutLoadedDestinationBackendRemainsPending...`
proves the gate while assuming streaming can independently finish. proves the gate while assuming streaming can independently finish.

View file

@ -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.

View file

@ -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 readiness. C1c remains review-closed/unlanded; section45 geometry activation
and full lanes/C2 follow this blocker, not in parallel with its implementation. and full lanes/C2 follow this blocker, not in parallel with its implementation.
No merge main before G4. 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.