fix(vendor): evidence-based pass — max-first stack ceiling; the local player resolves never-animated MoveTo targets
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run

Both chains pinned by the live [vendor-diag] run (vendor-diag.log)
after three code-reading rounds each failed:

The split bar: ACE serializes descStackSize=1 for EVERY browse row
(live wire, log 343-348) — the R1-era "ACE never populates desc"
claim is retracted with the line quoted. Retail's vendor sites read
pwd._maxStackSize directly (four sites, incl. UpdateItemsList
@0x004c1ea0 stamping min(remaining, _maxStackSize));
ResolveAuthoredStackSize flips to max-first for its vendor-only
consumers. Taper ceiling 1000, scarab 100, seed 1 for exempt.
Pricing still reads the desc (per-1 values on ACE).

Walk-to-use: the local player's getObjectA seam was bound to
TryGetPhysicsHost, which resolves only INSTALLED physics hosts — a
never-animated vendor has none, so TargetManager.SetTarget got null,
the MoveToObject armed with zero nodes, and UseTime never dispatched.
The log's natural=False completions were the user's own movement keys
(retail-correct input-edge cancels); attempt 4 worked because the
greeting animation had installed a host. RuntimePhysicsState gains
the retail CObjectMaint::GetObjectA seam (bound canonical resolver
with installed-host fallback); the graphical host binds the SAME
lazy-minimal-host resolver every remote already uses — whose own doc
comment names this exact never-animated hazard. The reservation
release was already correct (2b premise refuted with evidence); the
production-wiring invariants are now pinned by four new tests
including the pre-fix pathology as a permanent sabotage control.

AP-169 rewritten a second time, honestly. The [vendor-diag] probe
family (ACDREAM_DUMP_VENDOR) lands env-gated for future live triage.

Clean-room complete solution: 11,536 passed / 4 skipped / 0 failed.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-08 17:17:04 +02:00
parent d003449bb4
commit 02b735ba4a
21 changed files with 1139 additions and 102 deletions

View file

@ -193,33 +193,43 @@ public sealed class RuntimeInteractionTransactionState : IDisposable
ObjectDisposedException.ThrowIf(_disposed, this);
ArgumentNullException.ThrowIfNull(transport);
sequence = 0u;
RuntimeInteractionDispatchResult verdict;
if (serverGuid == 0u)
{
reservation?.CancelBeforeDispatch();
return RuntimeInteractionDispatchResult.Rejected;
verdict = RuntimeInteractionDispatchResult.Rejected;
}
if (!transport.IsInWorld)
else if (!transport.IsInWorld)
{
reservation?.CancelBeforeDispatch();
return RuntimeInteractionDispatchResult.NotInWorld;
verdict = RuntimeInteractionDispatchResult.NotInWorld;
}
if (!ownedByPlayer && !useable)
else if (!ownedByPlayer && !useable)
{
reservation?.CancelBeforeDispatch();
return RuntimeInteractionDispatchResult.NotUseable;
verdict = RuntimeInteractionDispatchResult.NotUseable;
}
if (!transport.TrySendUse(serverGuid, out sequence))
else if (!transport.TrySendUse(serverGuid, out sequence))
{
reservation?.CancelBeforeDispatch();
return RuntimeInteractionDispatchResult.Rejected;
verdict = RuntimeInteractionDispatchResult.Rejected;
}
else
{
reservation?.MarkDispatched();
_lastUseSourceId = serverGuid;
_lastUseTargetId = 0u;
IncrementRevision();
verdict = RuntimeInteractionDispatchResult.Dispatched;
}
reservation?.MarkDispatched();
_lastUseSourceId = serverGuid;
_lastUseTargetId = 0u;
IncrementRevision();
return RuntimeInteractionDispatchResult.Dispatched;
if (VendorDiagnostics.DumpVendorEnabled)
{
Console.WriteLine(
$"[vendor-diag] TryDispatchUse guid=0x{serverGuid:X8} ownedByPlayer={ownedByPlayer} useable={useable} verdict={verdict} seq={sequence}");
}
return verdict;
}
public bool TryDispatchTargetedUse(
@ -623,6 +633,11 @@ public sealed class RuntimeInteractionTransactionState : IDisposable
if (_pendingUse is not { } current
|| current.ApproachToken != approachToken)
{
if (VendorDiagnostics.DumpVendorEnabled)
{
Console.WriteLine(
$"[vendor-diag] TryResolveUseApproachCompletion no-match approachToken=({approachToken.ControllerLifetime},{approachToken.ApproachGeneration}) natural={natural} hasPendingUse={_pendingUse is not null}");
}
pending = default;
return false;
}
@ -630,6 +645,11 @@ public sealed class RuntimeInteractionTransactionState : IDisposable
_pendingUse = null;
pending = current;
IncrementRevision();
if (VendorDiagnostics.DumpVendorEnabled)
{
Console.WriteLine(
$"[vendor-diag] TryResolveUseApproachCompletion guid=0x{pending.ServerGuid:X8} natural={natural} accepted={natural}");
}
return natural;
}