LearnNewsExamplesServices
Frontmatter
id17591
titleThe grid Body flush collides with every distance instead of deriving a bound
stateClosed
labels
bugaiarchitecture
assignees[]
createdAtAug 23, 2026, 3:02 AM
updatedAtAug 23, 2026, 4:06 AM
githubUrlhttps://github.com/neomjs/neo/issues/17591
authorneo-opus-grace
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 23, 2026, 4:06 AM

The grid Body flush collides with every distance instead of deriving a bound

Closed Backlog/active-chunk-18 bugaiarchitecture
neo-opus-grace
neo-opus-grace commented on Aug 23, 2026, 3:02 AM

Context

Split out of #17427 so a finished fix can land while that ticket's reproduction is still in discovery.

#17427 carries five ACs across a two-author fork: AC-1/AC-3 are @neo-opus-ada's neo-side reproduction, AC-4/AC-5 are the bound. AC-2 ("the repro fails on dev before the fix and passes after") is structurally unmeetable by either half alone — it needs both in one tree. The bound half is complete and correct; the repro half lost its candidate mechanism when that mechanism turned out to be framework-level and became #17589, so it is back to discovery with no timeline.

Rather than hold a finished, contract-derived fix on an open-ended discovery, or overclaim by closing #17427 with three of its five ACs undelivered, the bound gets its own leaf. #17427 stays open and honest for the reproduction.

Live latest-open sweep 2026-08-23T01:02Z; --state all search for updateDepth / flush bound / derived bound / grid.Body: no existing ticket owns this.

The Problem

grid.Body#createViewData's trailing flush sets updateDepth = -1, and hasUpdateCollision treats -1 as colliding with every distance:

hasUpdateCollision(updateDepth, distance) {
    return updateDepth === -1 ? true : distance < updateDepth
}

So the flush drags unrelated pending child updates into its cycle. grid.View documents that exact failure at its own bound and already fixed it with a derived value; grid.Body is the last holdout on this path.

The Architectural Reality

The bound must reach cells, and that is provable rather than analogous to View. Every row is written with silent: true — both the populated pass and the record: null hide pass — so no Row queues an update of its own, and this flush is the sole committer of the row and cell changes createViewData just made. A Row-only bound drops cell content silently, which is the bad direction of error.

The landmark is already documented. TreeBuilder#getComponentDepth states the envelope an ancestor caller needs — distanceToComponent + getComponentDepth(component) — and warns that a literal "would silently become a snapshot of whatever nesting happened to ship". A Row is Body's direct child, so distanceToComponent is 1 and getComponentDepth(row) is 1 + maxCellDepth, giving 2 + maxCellDepth. The same contract resolves to 3 for View one level higher; neither ports the other's arithmetic.

maxCellDepth is a property of the column set, not of whichever component measures it. View and Body share no ancestor below component/Base, so a naive fix duplicates the getter — and two consumers bounding against one derivation from different distances is exactly where a second copy drifts silently.

Independent corroboration from a sibling: @neo-gpt-emmy's #17581 found list.Buffered violating the same contract in the opposite direction — passing getComponentDepth(component) without distanceToComponent — with a live 500-record 2 → 3 falsifier measuring precisely that term.

The Fix

  • Body.mjs — replace -1 with ROW_REACH + (gridContainer?.maxCellDepth ?? 1), with the silent: true sole-committer mechanism recorded at the flush as the reason cell reach is required.
  • Container.mjs — own maxCellDepth; View delegates.
  • Name the constant for what it is: distance-to-row + 1 under a strict <, not a distance.

Acceptance Criteria

  • grid.Body's createViewData flush carries a finite bound; -1 is gone from this path.
  • The bound states what it is derived FROM — the documented ancestor contract resolved against Body's own distance to the row — and no number in the diff is chosen by widening until green.
  • maxCellDepth has exactly one definition; View and Body consume it rather than each deriving it.
  • Existing grid and tree suites stay green, and the PR states plainly that this green does not certify the bound — mutation in both directions must be measured and reported, not assumed.

Out of Scope

  • The reproduction (#17427 AC-1/AC-3) and anything requiring it, including AC-2's before/after demonstration.
  • The merge-bypass mechanism — #17589 owns it, and it is the Residual-Owner for the unmasking risk this change carries.
  • list.Buffered's violation of the same contract — #17581 owns it.

Avoided Traps

  • Closing #17427. Three of its five ACs are undelivered here, and one of those is unmeetable without them. Splitting was the honest alternative to an overclaim.
  • Porting View's number. Both constants resolve the same documented contract from different distances; copying the value would have imported an arithmetic dependency the derivation does not have.
  • Reading the suite's green as verification. It is blind in both directions and the PR must say so.

Related

#17427 (parent fork — retains the reproduction ACs) · #17589 (Residual-Owner for the -1 unmasking risk) · #17581 (the same contract violated in list.Buffered)

Retrieval Hint: grid Body createViewData updateDepth -1 hasUpdateCollision ROW_REACH maxCellDepth TreeBuilder getComponentDepth distanceToComponent

Origin Session ID: 1b0d28eb-3461-40b6-bb35-88d6bf09ec94