docs(render): correct flap spec — enqueue-once REFUTED, bounded-propagation port

The writing-plans decomp pass read FixCellList (433407) -> AdjustCellView (433741)
-> ClipPortals(update_count) + AddViewToPortals, proving retail RE-PROCESSES a
grown-after-drawn cell. So the approved "enqueue-once / no re-process" approach is
wrong (it would break Build_ViewGrowthAfterDoneCell for the right reason — that test
is actually retail-faithful).

Corrected approach (user chose the faithful moderate port over an epsilon-dedup
band-aid): KEEP re-processing on growth, but BOUND it the way retail does — each
view slice processed once (monotonic update_count watermark) and redundant
reciprocal back-contributions clip to EMPTY (OtherPortalClip -> no copy_view -> no
new slice), so the reciprocal/drift loop can't churn. acdream churns because its
reciprocal yields a drifted non-empty sliver, bounded only by the
MaxReprocessPerCell=16 hack. Remove the cap; bound structurally.

Scope unchanged: PortalVisibilityBuilder only; no rooting/camera/clip-math-rewrite/
seal change. One open precision (exact line where acdream's sliver becomes
non-empty — float-drift-dependent on real geometry) deferred to the plan's first
task: instrument PortalVisibilityBuilder (per-pop re-pop count + reciprocal-clip
in/out + grew), capture at the doorway, pin it, THEN fix.

Spec updated in place with a REVISION banner; superseded enqueue-once body retained
for the audit trail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-08 12:33:06 +02:00
parent 6c3a96b26e
commit ab6ed905f1

View file

@ -1,8 +1,48 @@
# Portal-Flood Enqueue-Once Port — the indoor "flap" fix (verified design)
# Portal-Flood Bounded-Propagation Port — the indoor "flap" fix (verified design)
**Date:** 2026-06-08 (revised — enqueue-once superseded)
**Branch:** `claude/thirsty-goldberg-51bb9b`
**Status:** Design revised after the writing-plans decomp pass; pending re-review.
> ## ⚠️ REVISION (2026-06-08 PM): "enqueue-once" REFUTED — corrected to "bounded propagation"
> The original approach below (§4 enqueue-once, §5 correct-the-test) is **WRONG** and is retained only
> for the audit trail. The writing-plans decomp pass read `FixCellList` (decomp 433407) →
> `AdjustCellView` (433741) → `ClipPortals(update_count)` + `AddViewToPortals`, which proves **retail
> DOES re-process a grown-after-drawn cell**. So:
> - **Re-processing on growth is retail-faithful and STAYS.** Pure enqueue-once is wrong; it would break
> `Build_ViewGrowthAfterDoneCell_PropagatesNewSlicesToExit` for the *right* reason (the test is correct
> — do NOT "correct" it; §5 below is VOID).
> - **The real divergence is BOUNDING.** Retail's re-processing terminates *structurally* — each view
> slice is processed once (the `update_count` watermark is monotonic) and a redundant **reciprocal**
> back-contribution clips to **empty** (`OtherPortalClip` → no `copy_view` → no new slice; decomp
> 433654/433711-712). acdream's reciprocal (`ApplyReciprocalClip`+`ClipToRegion`) instead yields a
> **drifted non-empty sliver**`grew` → re-enqueue → churn, bounded only by the
> `MaxReprocessPerCell=16` **hack**. The churn's fixpoint is eye-sensitive → the flap.
> - **Corrected fix:** port retail's **bounded propagation** — make redundant reciprocal/re-clip
> contributions NOT generate new propagatable slices (match retail's empty-reciprocal + monotonic
> `update_count` watermark), and remove the `MaxReprocessPerCell` cap. Keep re-processing.
> - **Scope:** still `PortalVisibilityBuilder` only; no rooting/camera/clip-math-rewrite/seal change. The
> user approved this corrected "faithful moderate port" direction (over a non-faithful epsilon-dedup
> band-aid) on 2026-06-08.
> - **One open precision (→ plan Task 1):** exactly *where* acdream's reciprocal sliver becomes non-empty
> is float-drift-dependent on real doorway geometry — a runtime fact. The implementation plan's first
> task **instruments `PortalVisibilityBuilder` (per-pop re-pop count + reciprocal-clip in/out + `grew`),
> captures at the doorway, and pins the exact line** before the fix, rather than guessing from decomp.
> - **Corrected retail grounding (the full traversal):** `ConstructView` 433750 (pop-once → draw-list →
> `ClipPortals(cell,0)``AddViewToPortals`); `ClipPortals` 433572 (slices `[update_count,view_count)`,
> `GetClip` per portal, exit→`copy_view`/OutsideView, neighbour→`OtherPortalClip`); `AddViewToPortals`
> 433446 (first-discovery→`InitCell`+`InsCellTodoList`; growth→`AddToCell`+`FixCellList`);
> `FixCellList` 433407 = `AdjustCellPlace` + `AdjustCellView` 433741 (=`ClipPortals(update_count)` +
> `AddViewToPortals`**the re-process**); `OtherPortalClip` 433524 (reciprocal, empty-for-redundant).
>
> Everything below this banner is the ORIGINAL (superseded) enqueue-once design — kept for the record.
> ---
# (SUPERSEDED) Portal-Flood Enqueue-Once Port — original design
**Date:** 2026-06-08
**Branch:** `claude/thirsty-goldberg-51bb9b`
**Status:** Design approved (brainstorm). Pending implementation plan.
**Status:** SUPERSEDED by the revision banner above.
> **Supersedes** the enqueue logic in `docs/superpowers/specs/2026-06-08-portal-flood-membership-stability-design.md`
> (whose §4 enqueue-once was an *incomplete* attempt — it dropped the `AddToCell` growth half) and the