Commit graph

2469 commits

Author SHA1 Message Date
Erik
3f2f00c9fa docs(overhaul): correct S4 c3b gate provenance
Disclose that both official c3b artifact sets were captured pre-commit on the restored uncommitted implementation tree at parent a0523e605 with WorktreeDirty=true. Reconcile the transcript status entry as transient mutation-worktree dirtiness rather than an active gate mutation.

Narrow verification: both summary identities match; both 30-entry SHA256SUMS manifests verify with zero mismatches; base, implementation tip, contract HEAD, and worktree transcript blobs are c755c1379f; the hermetic TRX source-truth pin passed; diff-check and packet-only scope passed.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-04 15:16:03 +02:00
Erik
5110bf6760 docs(overhaul): contract S4 c3b provenance fix 2026-09-04 15:16:03 +02:00
Erik
26e97ba412 refactor(render): delete superseded alpha sidecars
Remove the dead classic-group CachedBatch/InstanceGroup sort-center sidecar and its cache, append, reset, and diagnostic-digest plumbing. Remove the discarded camera parameter chain from grouped alpha deferral and dispatcher submission diagnostics while preserving walk/particle CYpt keys, FIFO submission ordinals, and opaque camera distance.

Add production-facing reflection/source pins for the deleted shapes and camera chain, retained per-cell and opaque owners, the exact three AlphaFlushCounts reasons, and deleted alpha-order symbols. Update directly affected cache/digest/group lifecycle tests and record the complete section 22 result.

Gates: Release 0W/0E; focused App 132/132 plus Core 29/29; new pins 4/4; real allocation pins 2/2 at 0 B; shaders 32/32; hermetic 16755/16755; InstalledDat exactly 385 pass, 10 documented fail, 1 skip; diff-check clean.

Mutations: InstanceGroup and CachedBatch sidecars fail their Assert.Null pins; Defer and digest camera parameters fail method-shape pins; false count prose fails the exact-reason pin; RetailAlphaOrdering resurrection fails the deletion pin. Each was restored independently before the final matrix.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-04 15:16:03 +02:00
Erik
a0523e6057 docs(overhaul): contract S4 c3b deletions 2026-09-04 14:45:52 +02:00
Erik
b1d33c9b88 docs(overhaul): close S4 c3a landing 2026-09-04 14:41:56 +02:00
Erik
67c76026e6 docs(overhaul): correct c3a mutation evidence
Correct packet section 18.7 mutation 9: renaming AP-241 first fails the earlier AP-table-boundary Assert.True with rowIndex=-1; the later Assert.Single is not reached. Advance only the S4-c3a ledger row to the owner-authorized evidence-exception review.

This commit explicitly supersedes the false mutation-9 sentence recorded in historical candidate commit 44e2bc227b without rewriting or amending that commit. It changes no other c3a evidence or renderer behavior.

Narrow mutation: AP-241 rename first failed at line 329 with 'AP-241 row must be inside the AP table before the TS section; rowIndex=-1, AP=[275116,751256).'. The register row was restored byte-identically and the same isolated test passed 1/1. Diff-check passed; only packet and plan changed; no graphical client.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-04 14:37:40 +02:00
Erik
316193043d docs(overhaul): authorize narrow S4 c3a evidence fix 2026-09-04 14:37:37 +02:00
Erik
b6b0156045 fix(render): retain surfaceless particle metadata
Preserve a successfully decoded GfxObj ParticleGfxInfo when SurfaceId is zero and condition only texture acquisition. Missing/no-Gfx descriptors retain Default behavior; material, additive, routing, and untextured drawing remain unchanged.

Add a production-path GfxObj-backed synthetic no-surface pin with distinct authored/AABB centers, non-unit size, nonidentity orientation, object/particle merge order, visual center, and unassigned texture-slot assertions. Correct the synthetic-DAT evidence wording and advance only the S4-c3a ledger row.

Final F2 source audit found no defect: preparation holds reconstruction inputs only; Append reserves once; false and exception roll back the exact tail once; first-use rejection remains registered; accepted tokens stay stable; independent 3000-entry caps preserve row-2 immediate duplicates; flush/end/abort/next-preparation cleanup converges; retained capacity/bytes remain bounded; warmed production paths remain 0 B.

Gates: no-surface target 1/1; unchanged section 19 baseline 95/95; AP boundary/count 1/1; real allocations 2/2 at 0 B; shader/manifest 32/32; Release solution 0 warnings/0 errors; diff-check pass. No graphical client.

Mutation: restoring eea5793d2's SurfaceId-zero-to-Default ternary first failed CellTurn_GfxObjBillboardWithoutSurfaceRetainsAuthoredSortCenterAndUntexturedFallback at the authored-distance assertion, expected 40 actual 100.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-04 14:37:31 +02:00
Erik
8bd75ba312 docs(overhaul): bound final S4 c3a fix 2026-09-04 14:37:28 +02:00
Erik
01674bcc78 fix(render): repair particle CYpt preparation
Retain the GfxObj-authored SortCenter independently from the rendered AABB center and use its scaled, oriented world point for billboard/mode-2-5 CYpt. Keep the visual center unchanged.

Reserve prepared source payload only at Append, roll back the exact tail once on false or exception, cap retained preparation at 3000 CLIP plus 3000 ALPHA, preserve immediate duplicates, account the bounded scratch, and correct the static-record ordering comment. The lead-authorized plan edit records candidate 44e2bc227b's retail FAIL and this section 19 result.

Gates: Release solution build 0 warnings/0 errors; focused particle/driver/queue/order/bounds 95/95; register boundary/count 1/1; real allocations 2/2 at 0 B; shader/manifest 32/32; one-shot hermetic 16751/16751; InstalledDat 385 pass/10 documented fail/1 skip; diff-check pass. No graphical client.

Mutations: rendered pos first failed distance expected 40 actual 116; AABB center expected 40 actual 116; dropped size expected 40 actual 65; dropped orientation expected 40 actual 160; eager reservation first failed Assert.Empty with one payload; omitted false rollback first failed Assert.Single with two payloads; omitted exception rollback first failed Assert.Empty with one payload; removed caps first failed prepared count expected 6000 actual 6002.

Evidence note: the first ordinary InstalledDat filter produced 385 pass/2 expected fail/1 skip but excluded the eight required KnownFailure rows; the separate inclusive no-retry artifact produced the exact documented 10-failure set. Initial test fixture compilation/analyzer setup failures are recorded in packet section 19.5.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-04 14:37:23 +02:00
Erik
8e0c6fb145 docs(overhaul): bound S4 c3a retail fix round 2026-09-04 14:36:54 +02:00
Erik
a86ec73ece fix(render): restore retail per-cell alpha order
Reconstruct one combined static/dynamic object-part stream for each ordinary outdoor or interior cell, compute authored SortCenter CYpt keys, and stable-sort far to near before projecting opaque and delayed subsets. Prepare real cell-particle records at the leaf, preserve every S4-c2 router outcome, and merge object and particle delayed records by retained key before either source appends to the unchanged CLIP/ALPHA FIFO lists. Cell turns remain cell-major; equal cross-source ties are deterministically object-first.

File AP-241 and AP-242 for the remaining separate opaque/row-5 channels and unrepresented equal-key common ordinal. File AP-243 for the paired-binary correction: retail shares the cell CYpt/heading beyond 50 m while this bounded port always uses the more exact authored per-part center. Pin 162 active AP rows and correct world-alpha and AlphaFlushCounts prose.

Lead-approved scope clarification: RetailPViewPassExecutor.WalkLeaf.cs and RetailPViewPassExecutor.cs are the minimum existing production leaf adapter and thin particle-prepare forwarder omitted by the literal Walk/Wb file list. They contain no router, queue, mask, state, depth, or flush behavior; relocating them would create an artificial seam.

Gates: Release solution build 0W/0E; shader/manifest 32/32; focused production 210/210; real allocation 3/3 at 0 B; one-shot hermetic 16743/0/0 across 14 assemblies; InstalledDat 385 pass/10 documented fail/1 skip with all six AlphaFlushSites passing; git diff --check PASS. Initial no-restore solution build failed NETSDK1004 for 42 missing scratch assets; one solution restore preceded the official build.

Mutation proof, each restored before final gates:

1. Reverse comparator: authored-center order expected [202,101], actual [101,202].

2. Move ties left: multipart/subset order expected [11,12,21,22], actual [22,21,12,11].

3. Restore static/dynamic blocks: expected [2,3,1], actual [3,1,2].

4. Use entity origin: authored-center order expected [202,101], actual [101,202].

5. Restore particle tail: expected [Wb,Particle,Wb,Particle], actual [Wb,Wb,Particle,Particle].

6. Scope-global sort: first cell model X expected 5, actual 50.

7. Restore dead camera parameter: SubmitWalkAlphaInstance parameter count expected 2, actual 3.

8. Restore stale global-queue prose: exact Assert.DoesNotContain failure on distance-sorts one shared queue.

9. Remove AP-241 identity: Assert.Single found no matching row.

10. Allocate in real merge: expected 0 B, actual 3072 B.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-04 14:36:48 +02:00
Erik
06b986622b docs(overhaul): stop S4 c3a after final review 2026-09-04 14:22:50 +02:00
Erik
5c9da6fc25 docs(overhaul): define S4 c3 upstream order repair 2026-09-04 12:42:01 +02:00
Erik
d8c88adeb0 docs(overhaul): close S4 chunk 2 landing 2026-09-04 12:32:06 +02:00
Erik
252886e84f fix(rendering): repair EnvCell retail CLIP state
Exclude deferred EnvCell subsets from the opaque turn, preserve exact CLIP/ALPHA fixed-state groups through leaf replay, and use retail's row-3 override, blend, depth, and texture-class alpha references. Keep the existing building-detail sentinel distinct from the two CLIP references.

Bound rejected source payload, replace no-op allocation proofs with actual EnvCell and particle RHI paths, rebuild checked-in SPIR-V, and correct AP-238/AP-240 plus the S4-c2 evidence record.

Gates: Release 0W/0E; hermetic 16735/0/0; InstalledDat 255 pass/10 known fail/1 skip; shaders 32/32; focused 239/239; allocation 2/2 at 0 B. The evidence/comment repair re-ran Release 0W/0E, shaders 32/32, affected 37/37, and allocation 2/2; mesh_detail.vert.spv remained byte-identical at SHA-256 5346247ab7d606046943e19b28888c814e08dc6cb27cd9750096ac055457eb57.

Mutation proof, with each mutation restored after its named first failure:

1. Restoring the opaque predicate to !IsAdditive fails WholeLeaf_MixedCellDrawsOpaqueAtTurnThenClipAndAlphaAtDrain first at draw count: expected 1, actual 3.
2. Selecting _alphaPipeline for CLIP fails WholeLeaf_ClipDrainBindsExactStateAndTextureClassReference first at the bind sequence: expected [envcell-clip], actual [envcell-alpha].
3. Disabling CLIP depth write fails that production Theory first at Assert.True(clipPipeline.Depth.Write): expected true, actual false.
4. Swapping palette/DDS references fails the DDS row first: expected 0.784313738, actual 0.392156869; the palette row reports the inverse.
5. Mutating mesh_modern.frag from < to <= fails ClipShaders_UseGreaterEqualForThePerRangeReference first at Assert.Contains("if (color.a < alphaCutoff) discard;"): the required source spelling is absent.
6. Restoring row-3 OverrideClipmap=true fails the real-interface clip Theory first at Assert.False: expected false, actual true.
7. Deleting failed-append rollback fails the flush/end/abort rejection-storm rows first at the bounded pending-count assertion: expected 0, actual 9000.
8. Selecting _transparentDetailPipeline for a ClipMap detail contribution fails the leaf detail pin first at the bind sequence: expected second bind envcell-retail-detail-clip, actual envcell-retail-detail-alpha.
9. Resetting detail ParamB to zero fails the same detail pin first at the second pushed reference: expected 0.784313738, actual 0.
10. Classifying CLIP with exact mask equality excludes legal 0x09 and fails WholeLeaf_PositiveStippleClipMaskUsesClipPipelineAndDdsReference first at pipeline: expected envcell-clip, actual envcell-alpha.
11. Mapping the new blend to SRC_ALPHA/INVSRCALPHA fails AllRetailBlendModesAreRepresentable first at the tuple: expected (One, OneMinusSrcAlpha), actual (SrcAlpha, OneMinusSrcAlpha).
12. Restoring mesh_detail.vert's uParamB > 0.5 category predicate fails ClipShaders_UseGreaterEqualForThePerRangeReference first because vDetailCategory = uParamB == 1.0 is absent.
13. Treating every positive detail uParamB as a cutoff fails that source pin first because isRetailClipReference(uParamB) ? uParamB : 0.05 is absent.
14. Adding arbitrary 0.5 as an accepted reference to either mesh_modern.frag or mesh_detail.frag fails that source pin first at Assert.DoesNotContain("value - 0.5"); both mutations were run and reversed independently.

Retail: D3DPolyRender::SetSurface @ 0x0059c4d0; paired binary @ 0x0059c72a, 0x0059c747/0x0059c74f, 0x0059c821, 0x0059c838, 0x0059c866.
2026-09-04 11:53:45 +02:00
Erik
0aa166aa09 fix(render): complete S4 chunk 2 final alpha parity round
Final allowed fix round for S4-c2 on cc8e5677a. This lands every item in
the campaign packet section 12 without adding a flush site, shader, distance,
overflow recovery draw, or graphical-client run.

R2-1 particle row 5: ParticleRenderer now constructs and owns the actual
particle-mesh-opaque pipeline using the existing particle_mesh shaders and
layout, Blend=None, depth test/write enabled with WorldCompare, dynamic
per-batch cull, clockwise front face, and no alpha-to-coverage. The production
dispatch selects it for an opaque-classified mesh particle whose clamped
material alpha is 1.0. Nonopaque mesh pipelines remain depth-write-off. The
production route keeps cached reserve/immediate delegates and the warmed
append/immediate paths allocate 0 B.

R2-2 EnvCell exact per-subset routing: ObjectMeshManager carries Content's
TextureBatchData.RetailSurfaceMask onto ObjectRenderBatch at the real upload
boundary. EnvCellRenderer scans the active prepared cell snapshot and feeds
each real transparent batch's exact mask through RetailAlphaMeshRouter. Pure
0x08 Base1ClipMap reaches CLIP, 0x02 alpha-family reaches ALPHA, and table
Immediate subsets draw at the cell turn. Separate fixed-route draw sources
coalesce to at most one token per (cell,list) and filtered replay draws only
that list's subsets; a mixed cell contributes to both lists without duplicate
replay. Detail-on routes eligible subsets immediately with the detail pass.
The warmed dispatch/source allocation pins measure 0 B; the production scan/filter is covered behaviorally and uses only retained scratch/enumerators (static allocation audit).

R2-3 capacity cleanup: RetailAlphaQueue registers a source before the 3,000
entry capacity return. A source whose first append is rejected is therefore
reset by flush, EndFrame, or abort, but its rejected payload is never prepared
or drawn.

R2-4 production proof and prose: both actual Wb submit sites are exercised;
the particle tests call the production dispatcher and inspect the constructed
owner's production pipeline/selector; EnvCell tests upload real Content batch
masks through ObjectMeshManager and drain real filtered MDI calls. The A1
positive proof executes WorldSceneRenderer's real outdoor frame owner through
RetailPViewRenderer.DrawInside and RetailAlphaQueue.EndFrame and observes
[DrawBuilding x N, RenderNormalMode] with no LandscapeFlush. The packet and
register now state the varying retail first-for-list truth and the exact
per-subset EnvCell/AP-238, visible AP-239 compositing, and AP-240 feeder scope.
Physical active register counts remain AP=159 and AD=92.

Final clean-state gates (actual output):
- Release solution build: Build succeeded; 0 Warning(s); 0 Error(s).
- Hermetic solution filter: every project green, 16,728 passed / 0 failed /
  0 skipped total; AcDream.App.Tests 6,875/6,875.
- InstalledDat: 255 passed / 10 failed / 1 skipped / 266 total, exactly the
  allowed identities: TowerAscent_StaircaseStaysConeVisible_EveryStep;
  MainGameUiAndChatInput_MediaBearingChildrenNowBuildAsRealWidgets (#383);
  EveryAuthoredInvisibleWidget_StartsHiddenAcrossAllLayouts (#383);
  Oh_doorway_still_first_frame_diff (#458); and the six
  AlphaFlushCounts_{CathedralArrival,CathedralLeak,CathedralStairArch,
  FoundryDeep,HoltburgDoorwayStill,TerraceEdge}_MatchesRetailFrame2. All six
  AlphaFlushSites_* pass in the same lane.
- VulkanShaderDescriptorContractTests + VulkanShaderManifestTests +
  RenderPackSpirvValidatorTests: 32 passed / 0 failed / 0 skipped.
- Corrected queue/router/walk/driver/particle/Wb/EnvCell/PView production
  filter: 211 passed / 0 failed / 0 skipped.
- Explicit warmed production allocation pins: 2 passed; both measure 0 B.
- Register: physical AP-238/AP-239/AP-240/AD-120/~~AP-34~~ rows each count
  exactly 1; active physical rows AP=159 and AD=92.
- git diff --check: PASS.

Production mutation checks (each applied, run to the named first failure, and
exactly reversed before the final gates):

1. Restoring the particle row-5 throw fails
   OpaqueClassifiedMeshBatch_WithNoMaterialAlpha_DrawsImmediateOnOpaqueDepthState
   first with InvalidOperationException: mutation: row 5 unreachable.

2. Deleting row 5's immediate callback fails that same production-dispatch
   test's first collection assertion: expected [(Mesh, 11, True)], actual [].

3. Constructing the actual owner pipeline with depthWrite:false fails
   ImmediateOpaqueMesh_UsesProductionParticleMeshOpaquePipelineDescription
   first at Assert.True(description.Depth.Write): expected true, actual false.

4. Mapping the production selector back to _meshAlphaPipeline fails that same
   test first at Assert.Same: expected particle-mesh-opaque, actual
   particle-mesh-alpha.

5. Dropping RetailSurfaceMask at the real ObjectMeshManager upload boundary
   fails the mixed-cell production scan first: expected Clip | Alpha, actual
   Immediate.

6. Hardcoding the uploaded EnvCell scan to MaskAlphaFamily fails the mixed-cell
   production scan first: expected Clip | Alpha, actual Alpha; the pure-mask
   pin also reports expected Clip, actual Alpha.

7. Inverting the production detail predicate fails the detail-on production
   pin first: expected Immediate, actual Clip.

8. Removing both EnvCell replay filters fails the mixed production drain's real
   MDI assertions: each call expected DrawCount 1, actual DrawCount 2.

9. Moving RegisterSource below the full-capacity return fails every
   RejectedFirstUseSource_IsCleanedWithoutPrepareOrDraw row (flush, EndFrame,
   abort) at the first ResetCount assertion: expected 1, actual 0.

10. Hardcoding detailSurfaceActive=false at the real Wb dispatch fails both
    production submit-site tests at their first queue-count assertion:
    expected 0, actual 1.

11. Restoring RetailPViewRenderer's removed outdoor LandscapeFlush call fails
    OutdoorProductionPView_DrainsBuildingThenRenderNormalModeWithoutLandscapeFlush
    first at the real drain sequence: expected [DrawBuilding,
    RenderNormalMode], actual [DrawBuilding, LandscapeFlush,
    RenderNormalMode].

12. Deleting WorldSceneRenderer's final EndFrame owner drain fails that same
    full-path A1 test first: expected [DrawBuilding, RenderNormalMode], actual
    [DrawBuilding].

Not done/deferred: none. No retail conflict or infeasible contract item was
found. No graphical client was launched.

Co-Authored-By: Codex <noreply@openai.com>
2026-09-04 11:53:24 +02:00
Erik
9ccb61a8ec fix(render): S4 chunk 2 round 1 - particle throw, detail-off immediate draws, EnvCell FIFO, gate honesty
Fix round 1 of the two the plan allows for S4-c2 (048d5b12f), addressing
every item M1-M8/A1-A8 from the campaign branch's packet section 11.

M1 (BLOCKING): ParticleRenderer.DeferToRetailAlphaQueue threw whenever a
mesh-particle batch's TranslucencyKind.Opaque classification (mask 0x00)
reached a non-Append DrawMesh row - a real, reachable outcome since
TryAppendMeshDraws applies no IsOpaque-style pre-filter unlike
WbDrawDispatcher's path. Deleted both throws (ParticleRenderer.cs,
WbDrawDispatcher.cs SubmitToAlphaQueue), extracted the router-input
derivation into internal static ParticleRenderer.RouteParticleSubmission
(directly testable), and implemented rows 1/5's immediate draw by reusing
the existing per-instance billboard/mesh draw code (new
DrawImmediateParticleSubmissionRhi, no new renderer, no sort per A8).
materialHasAlpha (row 4) is derived from CMaterial::CheckAlphaValues
@0x005396a0 (Ghidra-verified 2026-09-04): has_alpha=0 only when
Ambient.a==Diffuse.a==Specular.a==Emissive.a==1.0f, else 1 - and
CMaterial::SetTranslucencySimple @0x005396f0 (reached from
CPhysicsPart::SetTranslucency <- Particle::Update @0x0051c290's per-frame
alpha-fade) sets all four channels to (1f - translucency) uniformly, so
has_alpha == "this particle's current alpha isn't 1.0" - already carried in
ColorArgb's top byte (Lerp(StartAlpha,EndAlpha,tLife), ParticleSystem.cs
1039-1041/1453).

M3: SubmitToAlphaQueue now takes isBuildingShell + viewProjection and feeds
Row 1's detailSurfaceActive gate for translucent building-shell instances
(retail DrawBuilding @0x0059f2a0 installs building detail before its own
shell subsets reach DrawMesh). Row 1 (detail on) draws the instance
immediately at its own walk-stream AlphaSubmitMark via new
DrawImmediateAlphaInstance/DrawImmediateAlphaInstanceRhi (reusing
WriteDeferredAlphaEntrySlot + the drain's pipeline/detail code for slot 0);
never touches _deferredAlpha/the queue for pure-Immediate submissions (fixes
a latent leak: previously reserving a _deferredAlpha slot for every
candidate meant a frame with ALL-immediate content never registered a
source, so ResetAlphaSubmissions never ran). M3c: DrawPreparedAlphaBatchRhi's
own per-command hasDetail/DrawBuildingDetailRangeRhi branch is deleted -
detail-eligible content no longer reaches the drain (spec: delayed replay
is always detailEnabled=0). New AD-120 register row for the "in place -> at
the entity's own stream mark" granularity adaptation this introduces.

M6: RetailPViewPassExecutor.SubmitOrDrawTransparentCellShell routes an
EnvCell's transparent shell through the SAME RetailAlphaMeshRouter table
(mask 0x02, detailSurfaceActive = EnvCellRenderer.TransparentDetailEnabled)
instead of a hand-coded branch. Detail on: unchanged immediate draw. Detail
off: appends ONE token per CELL via new EnvCellAlphaDrawSource (internal,
delegate-based so it's unit-testable without a GPU harness), replayed
through EnvCellRenderer.RenderTransparentOrdered at the next flush -
RenderTransparentOrdered already replayed a cell's batch on demand, so no
new deferred-replay abstraction was needed (the original landing's claim
that one was required is corrected in the packet).

M4: RetailAlphaEntry.IsFirstForList deleted. Retail's per-DrawMesh-
invocation "first for this list" flag is trivially true for every subset
retail ever appends (DrawMesh @0x0059d4a0 sets both flags true at entry,
0059d4cc/0059d4d0, clearing each independently after ITS OWN first append
within that call, 0059d5ef) - the captures confirm it (new=1 on 9,685/10,556
AM lines, impossible under "first since last drain"). acdream's deleted
isFirstForList = target.Count == 0 computed the wrong quantifier. One
acdream append already IS one DrawMesh call, so the field carried no
information and its own pin was vacuous (feedback_every_new_pin_must_be_
shown_to_fail) - deleted rather than kept as an always-true no-op.

M5: split all six AlphaFlushTranscript_* KnownFailure Facts into live
AlphaFlushSites_* (site+threshold sequence only, content-independent,
unconditional pass) and AlphaFlushCounts_* (KnownFailure, full tuple incl.
drained counts) sharing one RunAlphaFlushTranscriptReplay helper. Rewrote
the KnownFailure reason honestly: THREE independent causes, not "harness
content only" - (1) zero live mesh content, (2) acdream appends one entry
per INSTANCE vs retail's one per SUBSET per DrawMesh call, (3) acdream's
CLIP list is structurally empty for ordinary content (M2). Added ONE live
valve pin (WalkFrameDriverTests.SortCellExit_ValveDrainsThroughReplayAtThe
ExactBoundary, a Theory over 2250/2249) that goes through WalkFrameDriver.
Replay's own SortCellExit arm, not RetailAlphaQueue.Flush called directly.

M2/A2/M8c (register): ~~AP-34~~ restored as struck-through RETIRED (it had
been deleted outright, not struck, breaking the register's own convention)
citing residuals AP-238/AP-239/AP-240. The chunk-2 commit's "AP-236"/
"AP-237" collided with an id ALREADY filed-and-retired on main by an
unrelated #132 fix (docs/ISSUES.md:19976) - ids are never reused, so both
are renumbered: AP-236->AP-238 (EnvCell; rewritten per M6 - granularity-only
residual now, "never through the shared queue" is retired), AP-237->AP-239
(mask-reconstruction gap; the dangling "AP-236b" citation in
RetailAlphaMeshRouter.cs never matched either filed id and is corrected to
AP-239). New AP-240 filed for M2: WbDrawDispatcher.IsOpaque filters
ClipMap out upstream, so ordinary clip-mapped content never reaches
retail's CLIP FIFO (draws immediately on the pre-existing
OpaqueAlphaToCoverage pipeline instead) - no pipeline change this round,
per the contract. AP section header recounted honestly: 159 active (was
stale at 161); AD section 92 (was 91, +AD-120).

M7: AP-239's only cited example (cloud GfxObj 0x01004C35, surface
0x08000023) is DISPROVEN - decoded Type=0x10114 has alpha-family bits
that win in BOTH retail's real priority and acdream's reconstruction, so it
never actually diverges. A 2026-09-04 scan of all 6,152 Portal-dat Surfaces
found 27 real Translucent+Base1ClipMap-no-alpha-family instances
(Type=0x14); cross-referencing GfxObjs found surface 0x08000015 on GfxObj
0x010001EC - cited in place of the disproven cloud example.

M8: (a) RenderDeviceD3D::DrawBlock is @0x005a17c0 per symbols.json, not
@0x005a18d0 (that is its per-land-cell loop head) - fixed across
RetailAlphaQueue.cs, RetailPViewPassExecutor.cs, WalkEvents.cs,
WalkFrameDriver.cs (x3), RetailFrameWalk.cs. (b) RetailAlphaQueue.cs's four
FlushAlphaList addresses were labelled "return site" but are the CALL
instruction's own address (x86 CALL rel32 is 5 bytes) - relabelled "call at
X (returns to X+5)". (d) worldbuilder-inventory.md:420's AP-34 citation
updated.

A1: RetailPViewRenderer.cs's outdoor-root passes.FlushLandscapeAlpha() call
(labelled LandscapeFlush) is deleted - retail's real LandscapeFlush
(PView::DrawCells @0x005a4840's own FlushAlphaList(0f) @0x005a4872) sits
strictly inside if (outside_view.view_count > 0) on the INTERIOR PView; an
outdoor root never reaches it (terrace-edge capture: zero 005a4877 FL
lines). Verified no opaque draw intervenes between this deletion point and
RetailAlphaQueue.EndFrame()'s own RenderNormalMode pass-end flush
(WorldSceneRenderer.cs: DrawPostWorldParticles's PView branch is an
explicit no-op; only diagnostic wireframes follow) - #132's "drain after
the finished opaque world" invariant is kept by that flush alone.

A4: RetailAlphaQueue's ApplyScratchRetention call sites passed the ENTRY
count as the SOURCE-count argument too (observedClip + observedAlpha
twice), so _sources/_sourceDrawOffsets never shrank toward the real source
count. Fixed to capture _sources.Count before Clear().

A5/A6/A7: WalkStaticStreamPopulatorTests.cs's stale "same viewer distance"
banner corrected; two off-by-one entry counts in the packet's section 10
sequences corrected (foundry-deep x10->x11, holtburg-doorway-still x5->x6);
WalkAlphaDepthTrace.cs's "new=" comment explains why IsNew is retained but
never compared (M4's finding makes a per-subset comparison meaningless at
acdream's per-instance granularity); RetailAlphaMeshRouterTests.cs's
IndependentReferenceRoute (never actually independently-shaped) renamed to
RestatedBranchTableRoute with an honest doc comment, and the unverified
"flipped in turn and failed every time" claim deleted.

A3 was resolved as a side effect of M1's SubmitToAlphaQueue doc-comment
rewrite (the wrong "0x02/0x03, 0x04/0x05, 0x08/0x09" enumeration no longer
exists); RetailAlphaMeshRouter.cs's own MaskFromTranslucencyKind comment
updated in the same spirit (M1's particle-site Opaque-reachability finding).

Mutation checks (each applied to a scratch-restored copy, confirmed
failing, then byte-exact reverted - diffed against a /tmp backup after
restore):

- A1 (RetailPViewRendererTests.DrawInside_NeverCallsFlushLandscapeAlphaDirectly):
  restoring the deleted "if (ctx.RootCell.IsOutdoorNode)
  passes.FlushLandscapeAlpha();" line reintroduces a direct
  RetailPViewPassExecutor.FlushLandscapeAlpha call in DrawInside's compiled
  body. Actual failure: "Assert.DoesNotContain() Failure: Filter matched in
  collection ... CompiledCall { ... Target = Void FlushLandscapeAlpha() }".

- A4 (RetailAlphaQueueTests.RetainedSourceCapacity_ConvergesToTheReal
  SourceCountNotTheEntryCount): reverting both ApplyScratchRetention calls
  to (observedClip + observedAlpha, observedClip + observedAlpha) - with
  100 distinct sources in the spike frame (so _sources.Capacity grows to
  128, past its initial 4) followed by three low-demand frames of 10
  entries via ONE repeated source - makes sourceTarget compute from 10
  (Math.Max(4,10*2)=20) instead of 1 (Math.Max(4,1*2)=4). Actual failure:
  "Expected the retained source-array capacity to converge toward the real
  source count (1), but it stayed at 20". (A single-source-only spike does
  NOT discriminate this bug - Math.Min(sourceTarget, _sources.Capacity)
  clamps both formulas to the same unchanged initial 4 - hence the
  100-source setup.)

- M5 valve (WalkFrameDriverTests.SortCellExit_ValveDrainsThroughReplayAt
  TheExactBoundary, 2250 case): flipping RetailAlphaQueue.Flush's no-op
  comparison from "<" to "<=" (S4-c1/c2's own boundary mutation) makes the
  2250-entries case a no-op instead of draining. Actual failure:
  "Assert.Equal() Failure: Values differ Expected: 0 Actual: 2250".

- M6 (EnvCellAlphaDrawSourceTests, both Facts): adding an immediate
  renderTransparentOrdered(new[]{cellId}) call inside
  EnvCellAlphaDrawSource.AddPendingCellId (simulating the M1/M3 "drew
  immediately instead of deferring" bug class) makes
  PendingCellToken_IsDrainedAtTheFlushAndNeverBeforeIt fail with
  "Assert.Empty() Failure: Collection was not empty Collection: [[4660]]"
  and ParticleAppendedBetweenTwoCellTokens_KeepsItsPositionInTheCombined
  Drain fail with 'Expected: string[] ["cell:256", "particle:7",
  "cell:512"] Actual: List<string> ["cell:256", "cell:512", "cell:256",
  "particle:7", "cell:512"]'.

- M1 (ParticleRendererRouteTests.OpaqueClassifiedMeshBatch_WithMaterialAlpha
  _RoutesToAlphaAppend): hardcoding materialHasAlpha to false inside
  RouteParticleSubmission makes the Opaque-mask+has-alpha case route
  Immediate instead of Append. Actual failure: "Assert.Equal() Failure:
  Values differ Expected: Append Actual: Immediate".

Gates (real output lines):

- dotnet build AcDream.slnx -c Release -> "Build succeeded. 0 Warning(s)
  0 Error(s)".
- Hermetic lane (--filter "Lane!=InstalledDat&Lane!=PreparedPackage&
  Lane!=Live&Lane!=Manual&Lane!=Timing&Lane!=Windows&Lane!=Linux&
  Lane!=SystemFont&Purpose!=Diagnostic&Status!=KnownFailure") ->
  "Passed! - Failed: 0, Passed: 6864, Skipped: 0, Total: 6864".
- InstalledDat lane (ACDREAM_RUN_INSTALLED_DAT_TESTS=1,
  ACDREAM_DAT_DIR="C:/Users/erikn/Documents/Asheron's Call",
  --filter "Lane=InstalledDat") -> "Failed: 10, Passed: 255, Skipped: 1,
  Total: 266" - the exact 4 pre-existing failures
  (TowerAscent_StaircaseStaysConeVisible_EveryStep,
  LayoutImporterMediaBearingChildSweepTests, LayoutImporterInvisibleSweep
  Tests, Oh_doorway_still_first_frame_diff) plus the six
  AlphaFlushCounts_* KnownFailure Facts, nothing else; all six
  AlphaFlushSites_* Facts pass inside this same lane (the whole
  WalkTraceConformanceTests partial class carries Lane=InstalledDat, so
  they cannot run hermetically).
- Shader classes (VulkanShaderDescriptorContractTests,
  VulkanShaderManifestTests, RenderPackSpirvValidatorTests) -> "Passed! -
  Failed: 0, Passed: 32, Skipped: 0, Total: 32".
- RetailAlphaQueueTests, RetailAlphaMeshRouterTests, RetailFrameWalkTests,
  WalkFrameDriverTests, ParticleRenderer*Tests, EnvCellRenderer*Tests
  (combined filter) -> "Passed! - Failed: 0, Passed: 120, Skipped: 0,
  Total: 120".
- Register collision grep: AP-238/AP-239/AP-240/AD-120 each count exactly
  1; ~~AP-34~~ count exactly 1; live totals AP=159, AD=92.

Not done / deferred: none - all M1-M8/A1-A8 items landed; A8 was a
no-action note.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 11:53:03 +02:00
Erik
89f1e2676f feat(render): S4 chunk 2 — retail's two-list alpha FIFO cutover
Replaces the single scope-global distance-sorted RetailAlphaQueue with
retail's own two independent FIFO lists (CLIP/ALPHA, capacity 3000 each,
D3DPolyRender::AddMeshToAlphaList's exact append-only/capacity-drop
behavior — Ghidra-verified 2026-09-04), routed by a new
RetailAlphaMeshRouter porting DrawMesh's five-row immediate/delayed
branch table and ConstructMesh's subset-mask formula as pure functions,
and drained at retail's four normal-world FlushAlphaList sites
(DrawBuilding/DrawBlock/PView::DrawCells/RenderNormalMode) under the
exact Ghidra-verified no-op predicate (both counts strictly below
threshold*3000). A new WalkFrameEventKind.SortCellExit /
IWalkEventSink.OnSortCellExit / IWalkFrameLeafRenderer.FlushSortCellExit
fires once per admitted land-block cell for DrawBlock's 0.75f valve,
pinned by a dedicated far/near ordering test in RetailFrameWalkTests.cs.

WbDrawDispatcher's two submit sites and ParticleRenderer's one route
through the router; since none of the three ever draws during the Sky
leaf, installs a detail surface, or sets MultiPassAlpha, rows 1/2/4/5
are provably unreachable there and the call sites assert loudly rather
than building unexercisable immediate-draw plumbing. FlushFartherThan,
RetailAlphaOrdering.ComputeViewerDistance, and every viewerDistance
argument on the submit path are deleted.

Scope note (packet s4-depth-alpha-packet.md §10): C4 (routing EnvCell's
transparent shell batches through the shared queue) was not attempted —
EnvCell draws one per-cell MultiDrawIndexedIndirect call with no
per-subset deferred-replay abstraction, and building one without visual
verification (no graphical client in this worktree) was judged out of
this bounded chunk's scope. AP-34 is therefore retired and replaced by
two narrower rows rather than deleted outright: AP-236 (the carried-
forward EnvCell-immediate residual) and AP-237 (a newly identified gap:
TranslucencyKind.AlphaBlend can arise from either retail's Alpha/
Translucent bits, mask 0x02/ALPHA, or the Translucent+ClipMap "cloud"
override, mask 0x08/CLIP — GroupKey doesn't retain the raw bit to tell
them apart, so the router always picks ALPHA; only known example is
cloud GfxObj 0x01004C35). Both are compositing-order-only divergences,
never blend/visual ones.

Mutation checks (each applied, confirmed failing, then reverted):
- FIFO drain order reversed -> 5 RetailAlphaQueueTests fail (order).
- FlushAlphaList `<` -> `<=` -> boundary/scratch tests fail (2250 case
  reads drained=0 instead of 2250).
- Capacity check loosened (3000 -> 6000) -> overflow-drop test fails
  (TryAppend returns true, PendingCount reads 3001).
- IsFirstForList forced true -> flag test fails once inspected on the
  pre-flush two-entry snapshot (the post-flush single-survivor version
  of this test was vacuous and rewritten).
- Router row 3 condition inverted -> both the hand-traced Theory (6
  cases) and the 160-cell independent-truth-table brute force fail (20
  mismatches).
- SortCellExit emitted before OnLandscapeCellTurn instead of after ->
  RetailFrameWalkTests ordering pin fails ("SCX must immediately follow
  its own cell's SC").
- Prepare-per-list instead of prepare-once-combined -> the CLIP/ALPHA
  boundary batching test throws (index out of range).

Gates: Release build 0 warnings/0 errors. Hermetic lane (Lane!=Installed
Dat&...&Status!=KnownFailure) 6855/6855 passed. InstalledDat lane 249
passed / 10 failed — exactly the 4 pre-existing failures (#383 x2
LayoutImporter, TowerAscent KnownFailure, #458 Oh_doorway_still
KnownFailure) plus 6 NEW KnownFailure Facts
(AlphaFlushTranscript_*_MatchesRetailFrame2, one per capture) extending
this gate from PM/PC to AM/FL: the flush SITE+THRESHOLD sequence matches
the capture exactly for all six poses (including zero SortCellExit
drains in every capture, confirming the 0.75 valve is inert at these
scene complexities in both retail and this replay); the drained-COUNT-
per-list dimension diverges because this hermetic harness (matching the
existing PM/PC gate's own EmptyAlphaDepthWorldData design) carries no
live GfxObj/particle content, so every observed count reads (0,0)
against retail's real per-frame volume — both sequences quoted in full
per pose in the packet's new §10. Shader classes (VulkanShaderDescriptor
ContractTests/VulkanShaderManifestTests/RenderPackSpirvValidatorTests)
32/32 passed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 11:52:40 +02:00
Erik
3f69f1126b docs(overhaul): start S4-c2 completion attempt 2
Record attempt 1's shader-source-hash contract conflict and permit only the deterministic manifest/paired vertex-SPIR-V closure needed by the required comment correction.
2026-09-04 11:34:33 +02:00
Erik
249dabb41b docs(overhaul): authorize five S4-c2 completion attempts
Start attempt 1/5 as an evidence-and-comment-only repair of a094bf2b7. Preserve behavior, assertions, shader/SPIR-V, register, package, sequential review, and no-landing-before-dual-PASS constraints.
2026-09-04 11:31:29 +02:00
Erik
e8d89ba29a docs(overhaul): stop owner S4-c2 repair after retail review
Record a094bf2b7 as behaviorally retail-clean but unlanded because the binding evidence/prose contract failed. Preserve the sequential-review stop: the production lens did not run, no graphical gate ran, and G3/G4 remain unpassed.
2026-09-04 10:53:37 +02:00
Erik
4e863f7486 docs(overhaul): authorize bounded S4-c2 repair
Record the owner override after the required stop and bind the one-attempt repair to exact EnvCell pass membership, retail CLIP state, bounded source scratch, and production-path discriminators. Keep G3/G4 unpassed and the implementation unlanded pending dual review.
2026-09-04 09:42:59 +02:00
Erik
dc971ea2be docs(overhaul): stop S4-c2 after final review 2026-09-04 09:22:06 +02:00
Erik
ac74fbd84e docs(overhaul): contract S4-c2 final fix round 2026-09-04 08:06:14 +02:00
Erik
90d4ef4ac9 docs(overhaul): hand-off intro — no subagent running at hand-over
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 07:33:46 +02:00
Erik
cb71a92d51 docs(overhaul): hand-off at S4-c2 fix round 1 DONE (cc8e5677a in s4-c2-impl) — what is left on chunk 2, the review and landing procedure; ledger S4 row updated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 07:33:34 +02:00
Erik
2a35f0a4c3 docs(overhaul): hand-off rewritten clean at S4-c2 fix round 1 (review verdicts, #464 fixed, #468 filed, landing procedure, fixer-state check)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 06:39:23 +02:00
Erik
2001103ca6 docs+gate: #468 filed — the Holtburg doorway pose seats the player in the interior cell at a floorless point and it falls through the world; route-g3b pose 15 moved to the outdoor standing point
The 'empty plane under fog' frame the S4-c1 capture-pose self-gates produced
at frame 15 is the terrain seen from below by a falling player, not a draw
change: the camera probe holds playerCell=0xA9B4013F at (134.07,17.36) while
z drops 96 -> -20 m after materialization. The S3-state run had seated the
same request outdoors in 0xA9B40029 and stood. Placement is not the campaign's
domain; the gate pose is moved so the G3 frame is deterministic and the
original pose is kept in the issue as the reproduction. #462 recurrence on
the pre-S4 control build noted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 06:37:09 +02:00
Erik
3e76f71d5b docs(overhaul): S4-c2 production/gate lens FAIL recorded; fix round 1 addendum §11.1 (A1–A8)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 06:21:06 +02:00
Erik
92f08721e2 docs: #464 FIXED at 766f9e749 — confirmed by the scripted tilt route at the identical eye (S4-c1's ±12 reject)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 06:17:21 +02:00
Erik
3813f0bbf2 docs(overhaul): S4-c2 review round 1 — retail lens FAIL recorded; fix round 1 contract (packet §11, M1–M8)
The two-list/router/flush core of 048d5b12f is exact at the bytes; the
failures are at the call sites (a data-driven row 5 turned into a throw;
detail-surface input hardcoded false while the drain applies detail),
the register (the structurally empty CLIP list is undeclared; AP-237's
example is wrong; AP-34 not retired by convention), the first-for-list
quantifier, the all-KnownFailure gate, and the skipped C4 that turns out
to be bounded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 06:14:53 +02:00
Erik
5f3b4f98ee docs: owner reports #464 fixed at 766f9e749 (provisional); S4-c2 implementer commit 048d5b12f recorded with its three deviations
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 05:54:00 +02:00
Erik
36fddf17ca docs(overhaul): S4 hand-off — landed state, the in-flight S4-c2 implementer, the #464 RenderDoc plan, the Holtburg doorway A/B, owner-owed items
Written for a fresh session on another account: read order, exact tips and
worktrees, what S1-S4-c1 landed with their proof, how to find the state of
the chunk 2 implementer dispatched this morning, the #464 attribution plan
(RenderDoc pixel history on the scripted artifact frame - the lead's own
job once ACE is up), the Holtburg doorway frame read, tooling gotchas, and a
paste-prompt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 05:00:35 +02:00
Erik
4c6fb8fa6e docs(ledger): S4-c1 landing record, the Holtburg doorway frame read, the dead S4-c2 dispatch, and the account hand-over
The 2026-09-03 session landed S4 chunk 1 at 766f9e749 but ran out of
credits before writing the ledger row: round-2 lens verdicts, the landing
gates, the two capture-pose self-gates whose Holtburg doorway frame came
up as an empty plane under fog, the lead's read of that frame (the client
seated the player in the house-interior cell at the doorway threshold, so
the frame roots indoors with the eye outside), the crashed pre-S4 control,
and the S4-c2 dispatch that died with no commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 04:52:58 +02:00
Erik
d1e3e64f61 feat(render): S4 chunk 1 — retail far-punch bits, the ±12 local-input reject, the depth truth table and cross-frame latch pins
S4-c1 per docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md §6.
S3 chunk 2 already landed the persistent portalsDrawnCount latch, the
gated clear, the exit-seal counting, and the look-in isolation — this
chunk covers only what §1/§2 of the packet name as still owed: C0-C3.

C0 — far-punch depth constant (R1: DrawPortalPolyInternal @0x0059bc90's
tail). portal_depth.vert's punch branch carried the decimal 0.99999988,
which reinterprets as bits 0x3F7FFFFE — fifteen ULPs FARTHER from the
camera than retail's real constant, bits 0x3F7FFFEF. Now writes
`uintBitsToFloat(0x3F7FFFEFu)` so the exact bits survive the GLSL/SPIR-V
compiler instead of trusting a decimal literal to round-trip unchanged.
Recompiled via tools/compile-shaders.ps1 (glslc 1.4.350.0 backend
recorded, managed shaderc path used); portal_depth.vert.spv's SHA-256
re-pinned in VulkanShaderManifestTests
(51c60d0924d62c61548efcf5f9e7672a121b1b68ca0a06755e32f1a4d73a8acf,
was 4ac1c452e7ac0d08a32f67fb03f21229af2d1605baa81f407240a3626251dfd7).

T1 (new Fact PortalDepthVert_FarPunchConstant_MatchesRetailExactBits in
VulkanShaderManifestTests.cs): a SOURCE pin — reads portal_depth.vert's
punch line and reinterprets whatever literal it carries (uintBitsToFloat
hex or a plain decimal) as raw bits, asserts == 0x3F7FFFEF. Verified
against the PRE-CHANGE source by hand-reverting the line to
`clipPos.z = clipPos.w * 0.99999988;` and re-running just this test:

    Assert.Equal() Failure: Values differ
    Expected: 1065353199
    Actual:   1065353214

(1065353199 = 0x3F7FFFEF, 1065353214 = 0x3F7FFFFE). Line restored and
the test re-confirmed green afterward. MUTATION: any other literal fails
the same way.

C1 — the ±12 local-input reject (R2: 0x59BCD6-0x59BD28 then
0x59BD40-0x59BD66). The Ghidra arbitration table in
oh1-depth-lifecycle.md governs over the pseudo-C's own nested-if reading
of the four x87 FCOM results (BinaryNinja's `test ah, 0x44` condition
synthesis is FPU-flag-ambiguous and reads backward at face value — see
feedback_bn_decomp_field_names.md on decompiler flag mush as an artifact
class, not semantics): the table's row says "whole poly on any
local-input x/y == +/-12 boundary is rejected before count/clip" — taken
as written, not re-derived from the pseudo-C's literal branch nesting.

Ported as one shared predicate,
WalkVisibilityMath.IsRejectedByPortalPolygonBoundaryGuard(ReadOnlySpan
<Vector3>): true iff any vertex's X or Y is exactly +12f/-12f (retail
tests LOCAL x/y before xformStart, the world transform). Wired at BOTH
producers that own the LOCAL polygon before it leaves cell/building
space:
  - WalkFrameDriver.OnPunchGeometry (the walk's punch-event producer,
    IWalkEventSink.OnPunchGeometry) — checked on the building-local
    WalkPolygon.Vertices before TransformToWorld; a hit returns before
    MarkIfGrown/any event append (retail's reject -> transform -> clip
    -> count order).
  - RetailPViewPassExecutor.DrawPortalDepthWrite (the exit-seal
    enumeration behind DrawExitPortalMask, the sole caller) — checked on
    cell.PortalPolygons[index]'s local vertices before the
    Vector3.Transform loop; a hit `continue`s with no `submitted++`.

T2 (three layers):
  1. WalkVisibilityMathTests.cs — direct unit tests of the predicate:
     Boundary_guard_rejects_a_polygon_with_one_vertex_exactly_on_plus_minus_12
     (Theory, x/y == +-12 each), Boundary_guard_admits_a_polygon_whose_
     nearest_vertex_is_just_inside_12 (Theory, x/y == +-11.999),
     Boundary_guard_rejects_the_whole_polygon_even_when_only_one_of_
     several_vertices_hits_it, Boundary_guard_ignores_the_vertical_z_
     component, Boundary_guard_admits_the_empty_polygon.
  2. WalkFrameDriverTests.OnPunchGeometry_RejectsWholePolygonOnExact
     PlusMinus12LocalVertex_ButPunchesJustInside — functional: feeds
     OnPunchGeometry a polygon with a vertex at x=12 (no PunchFan/no
     "PUNCH:" log line) then one at x=11.999 (punches normally,
     leaf.Punches has exactly one entry, log has exactly one "PUNCH:3@v0").
  3. RetailPViewPassExecutorTests.DrawPortalDepthWrite_RejectsDegenerate
     LocalPolygons_BeforeTransformOrSubmission — a real functional test of
     DrawPortalDepthWrite needs a live PortalDepthMaskRenderer the suite
     has no fake for, so this is a compiled-call-graph pin (this file's
     established pattern for exactly this situation): the guard call
     precedes both the Vector3.Transform loop and
     PortalDepthMaskRenderer.DrawDepthFan by IL offset, gated by a
     conditional branch immediately after it.

MUTATION texts, all verified live during this session then reverted:
  - OnPunchGeometry_RejectsWholePolygon... with the C1 guard deleted from
    OnPunchGeometry:
      Assert.Single() Failure: The collection contained 2 items
      Collection: [WalkPolygon { Plane = WalkPlane { Normal = <0, 0, 1>, D = -3 }, Vertices = [<0, 0, 3>, <12, 0, 3>, <5, 5, 3>] }, WalkPolygon { Plane = WalkPlane { Normal = <0, 0, 1>, D = -3 }, Vertices = [<0, 0, 3>, <11.999, 0, 3>, <5, 5, 3>] }]
  - DrawPortalDepthWrite_RejectsDegenerateLocalPolygons... with the C1
    guard deleted from DrawPortalDepthWrite:
      Expected call to WalkVisibilityMath.IsRejectedByPortalPolygonBoundaryGuard.
  - Boundary_guard_admits_a_polygon_whose_nearest_vertex_is_just_inside_12
    with the predicate widened to `MathF.Abs(x) >= 11.99f ||
    MathF.Abs(y) >= 11.99f` (all four rows):
      Assert.False() Failure
      Expected: False
      Actual:   True
  - Boundary_guard_rejects_a_polygon_with_one_vertex_exactly_on_plus_
    minus_12 with the predicate narrowed to strict `x > 12f || x < -12f
    || y > 12f || y < -12f` (all four rows):
      Assert.True() Failure
      Expected: True
      Actual:   False
  - Boundary_guard_rejects_the_whole_polygon_even_when_only_one_of_
    several_vertices_hits_it with the guard checking only
    localVertices[0] instead of looping every vertex:
      Assert.True() Failure
      Expected: True
      Actual:   False

C2 — no pipeline change for R3 (depth ALWAYS/write/no-cull, color writes
ENABLED with a zero-alpha SRCALPHA/INVSRCALPHA blend). acdream's
PortalDepthMaskRenderer.Rhi.cs:92,100 sets ColorWrite=false alongside
Blend=None; portal_depth.frag writes no color output at all. Provably
pixel-identical (retail's blend collapses to dst'=dst when srcAlpha is
fixed at 0, for any RGB) and the write mask is the SAFER mechanism going
forward (structurally blocks any future accidental color write,
independent of an authored zero-alpha invariant). Added register row
AD-119 to docs/architecture/retail-divergence-register.md (the next free
id after AD-118), citing DrawPortalPolyInternal @0x0059bc90 and
PortalDepthMaskRenderer.Rhi.cs; section 2's active-row count and running
header note updated (90 -> 91).

C3 — the truth table + cross-frame latch tests. The (root kind,
draw_landscape, outside-view count, previous count) table's cells are
mostly already covered by S3 chunk 2's own tests — this chunk adds only
the genuinely missing rows/cases, and leaves every existing test
untouched:

  Pre-existing coverage (named, not reproduced):
    - interior, ov==0, prior==0 ->
      RunFrame_InteriorFloodWithNoExitView_SkipsLandscapeAndNeverFlushesClearsOrSeals
    - interior, ov>0, prior==0 ->
      RunFrame_InteriorFloodWithExitView_FreshDriverSkipsTheGatedClearThenDrawsSealsAndFloodCells
      and OnInteriorFloodDrawTurn_FirstOvFrameSkipsClear_SecondFrameArmedByFirstsSealsClears
      (its own frame 1)
    - interior, ov>0, prior>0 (T4's "frame 1 seals N>0 -> frame 2
      clears" half) ->
      OnInteriorFloodDrawTurn_FirstOvFrameSkipsClear_SecondFrameArmedByFirstsSealsClears
      (its own frame 2)
    - T4's "frame 1 seals 0 -> frame 2 does not clear" half (repeated
      across three consecutive ov>0 frames, subsuming the two-frame
      case) -> OnInteriorFloodDrawTurn_FloodWithNoExitPortal_NeverClearsAcrossFrames
    - one look-in isolated from the root latch ->
      LookInDrawCells_NeitherArmsNorConsumesThePortalsDrawnCounter
  No further T4 test was added — the two existing facts above already
  prove both halves of the two-consecutive-frames latch case exactly.

  New rows added this chunk:
    - WalkFrame_OutdoorRoot_NeverFiresTheInteriorClearSealMachinery: root
      kind == OUTDOOR. RetailFrameWalk.WalkFrame's outdoor branch
      ((cameraCellId & 0xFFFF) < 0x100) calls DrawLandscape directly and
      never calls DrawInside/OnInteriorFloodDrawTurn at all, so the whole
      LFLUSH/stamp/CLEAR/SEALS mechanism structurally cannot fire —
      driven end-to-end through RunFrame with an outdoor cameraCellId,
      asserting SKY present, LFLUSH/CLEAR/SEALS absent, counter stays 0.
      MUTATION (verified, then reverted): added a stray
      `sink.OnInteriorFloodDrawTurn([], 1);` call to WalkFrame's outdoor
      branch:
        Assert.DoesNotContain() Failure: Item found in collection
                         ↓ (pos 1)
        Collection: ["SKY", "LFLUSH", "SEALS"]
        Found:      "LFLUSH"
    - OnInteriorFloodDrawTurn_OvZeroAfterAPriorArmedCounter_LeavesTheLatch
      CompletelyUntouched: interior, ov==0 immediately after an EARLIER
      ov>0 frame armed the counter — proves the counter is left EXACTLY
      as an earlier frame left it (not merely "not cleared this frame"),
      since S3 §8.1 R3 gates the ENTIRE outside_view.view_count>0 block,
      including the read-then-zero decision itself, on ov>0.
      MUTATION (verified, then reverted): moved
      `int armed = PortalsDrawnCount; PortalsDrawnCount = 0;` out of the
      `if (outsideViewCount > 0)` gate in
      WalkFrameDriver.OnInteriorFloodDrawTurn (unconditional
      read-then-zero every call):
        Assert.Equal() Failure: Values differ
        Expected: 1
        Actual:   0
      (every OTHER WalkFrameDriverTests fact stayed green under this same
      mutation — this new test is the only one that catches it).
    - MultipleLookIns_WithinOneFrameAndAcrossFrames_NeverTouchTheRootLatch
      (T5): extends the single-look-in fact to TWO look-ins in one frame
      then a THIRD in a later frame. MUTATION (verified, then reverted):
      a `_mutationLookInCalls` counter in HandleDrawCellsTurn's
      LookInStatic branch that resets PortalsDrawnCount on the SECOND
      look-in call:
        Assert.Equal() Failure: Values differ
        Expected: 1
        Actual:   0
      — while LookInDrawCells_NeitherArmsNorConsumesThePortalsDrawnCounter
      (one look-in only) stayed green under the identical mutation,
      confirming this test's incremental value over the existing single-
      look-in fact.

Gates: dotnet build (App.Tests and App) 0 warnings/0 errors; hermetic
lane 6832/6832 passed; InstalledDat lane against
C:/Users/erikn/Documents/Asheron's Call — exactly the four known
failures (TowerAscentReplayTests.TowerAscent_StaircaseStaysConeVisible_
EveryStep, LayoutImporterMediaBearingChildSweepTests.
MainGameUiAndChatInput_MediaBearingChildrenNowBuildAsRealWidgets and
LayoutImporterInvisibleSweepTests.EveryAuthoredInvisibleWidget_
StartsHiddenAcrossAllLayouts — both #383 — and
WalkTraceConformanceTests.Oh_doorway_still_first_frame_diff #458),
243 passed / 1 skipped / 4 failed / 248 total, no new failures; shader
tests (VulkanShaderDescriptorContractTests/VulkanShaderManifestTests/
RenderPackSpirvValidatorTests/SkyVertexLayoutTests) 35/35; register
tests (Divergence|Register filter) 52/52.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:38:52 +02:00
Erik
2712a8b221 docs(issues): #464 night close — degrade level and depth contract equal to retail; the hall shell draws over the corridor vault; same-eye retail comparison owed (RenderDoc or the owner's tilt sweep)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:28:58 +02:00
Erik
bc6ed38380 docs(issues): #464 source found — the hall building's shell wins the depth test against the corridor cell's vault; skipping that shell draw restores retail's frame
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:25:23 +02:00
Erik
720d04856c docs(issues): #464 A/B round — no clip overflow, opaque piers, depth clear and alpha flush innocent, extra admissions innocent; the source is the cathedral's own content
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:16:09 +02:00
Erik
0b9e9b64ad docs(issues): #464 reproduced by script — seven outside views draw the artifact, five draw clean; the unclipped punch-fan fallback is the prime suspect
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 23:01:02 +02:00
Erik
49d2447a95 docs(render): S4-c1 fix round 1 verdicts (2 PASS / 1 FAIL) and the round-2 contract (packet §9): seed the portal counter from the capture, both sequences compared, the discriminating ±12 case, the sixth pose
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:49:33 +02:00
Erik
f2c2cdb876 docs(issues): #464 — the arch is cell 0x109's far wall fourteen metres beyond the open face; farther cells show over it (alpha-flush vs Z-clear order is the prime candidate)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:47:48 +02:00
Erik
2f7f45c2dd docs(issues): #464 geometry round — punches vertex-identical to retail, 12 of 16 rejected by the ±12 rule in both clients; no authored wall above the arch
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:45:07 +02:00
Erik
3a6aa7eef4 research(render): retail portal-polygon vertex capture at the #464 pose + the pm-verts cdb template
Sixteen DrawPortalPolyInternal attempts per frame, vertex-identical to
acdream's sixteen collect-time punches; twelve lie entirely on the local
y=12 plane and are rejected by the ±12 guard in both clients, so the hall
building's doorways are never punched in either.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:42:01 +02:00
Erik
d26a2ed035 docs(issues): #464 — the S4-c1 transcript gate replayed at the artifact pose PASSES: punch/seal events match retail exactly; the divergence is punch geometry or shell depth
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:30:31 +02:00
Erik
de33d49f22 docs(issues): #464 — retail capture eliminates admission; the divergence is in the punch/seal machinery at the stairwell's open face
Retail admits exactly acdream's cells and building-portal groups in the
same order; its alpha-depth frame punches each portal polygon to far depth
right before that group's cells and seals the exit views last. The
capture becomes S4-c1's fifth transcript pose.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:27:47 +02:00
Erik
4f12cd06b5 research(render): retail capture cathedral-stair-arch — the #464 artifact pose (walk 5 frames + alphadepth 5 frames)
Root 0xF4180114 with seven outside views; retail admits the same seven
hall building-portal groups in the same order as acdream, yet shows the
solid far face above the arch. The fifth transcript pose for S4.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:26:29 +02:00
Erik
4173cbd6e0 docs(research): move the #464 tilted-frame walk record out of the ignored logs dir
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:19:33 +02:00
Erik
3d746294ae docs(issues): #464 owner's tilted frame with the walk transcript — same admission set, seventh exit view; the open face shows the hall interior where retail shows the shell wall
The frame is saved as logs/464-owner-tilted-frame.walk.txt. Narrowed to
the building shell versus interior-cell order/clip at the stairwell's open
face in the outside pass (S4), with a possible building-portal admission
component only the cathedral-stair-arch retail capture can settle.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:19:17 +02:00
Erik
1be895f153 docs(issues): #464 walk transcript at the owner's pose — the hall cells are admitted through the building's exterior portals in the outside pass
The automation cannot tilt the camera, so the owner's screenshot stays the
record of the frame; the transcript shows the interior root flood of the
three stacked stair cells with six outside views and fifteen building-
portal groups including the hall cells. The retail capture at this pose
decides depth (S4) versus admission.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 22:09:06 +02:00