Symptom
In any freshly created scene (community: new project; both personal and org-moved discriminated identically), draw a slab, then draw a wall on it. The wall renders correctly on the slab, but commits as:
height: 2.5 // == the level's derived DEFAULT_LEVEL_HEIGHT
supportOffset: 0.05 // == the slab's elevation
supportSlabId: "ground"
i.e. data says terrain-hosted while the wall visibly stands on the slab — the #630-class plane-bound regression. Scenes with pre-existing geometry (e.g. the seeded dev fixture) are NOT affected, which is why private-editor's PR gate never caught it.
Not a recent regression
Bisect over bab7ff1b..182f7c94 found the baseline already bad — this predates the Aug-19 window (so #689/#690/#651/night-6 are exonerated). The variable is scene structure, not code history.
Mechanism (file:line, editor @ 182f7c9)
In a fresh scene the newly drawn slab is the only registered top surface. The pointer support resolver then returns it as a node-top sourceNodeId (packages/editor/src/components/tools/shared/pointer-support-cap.ts:155). The wall tool equates any such sourceNodeId with flatConstructionBase = true (packages/nodes/src/wall/tool.tsx:745), and resolveWallConstruction then forcibly elects ground, preserves the level-derived draft height, and records the slab elevation as supportOffset (packages/core/src/hooks/spatial-grid/support-host-patch.ts:472). With pre-existing geometry the ray/surface route differs, ordinary slab election runs (no source node), and the wall stays plane-bound.
Suspected fix locus: the sourceNodeId → flatConstructionBase → ground coercion — a slab-sourced support should elect the slab, not ground.
Acceptance test, ready and waiting
pascalorg/private-editor e2e/community/wall-plane-bound.spec.ts now runs against an isolated fresh org project and is test.fixme'd with this exact reason (private-editor#389). Removing the fixme is the acceptance test: it asserts the committed wall carries no stamped height/supportOffset and a real slab supportSlabId.
Found by the regression-testing program's fixture-isolation work; discriminator screenshots + field dumps in the session records.
🤖 Generated with Claude Code
Symptom
In any freshly created scene (community: new project; both personal and org-moved discriminated identically), draw a slab, then draw a wall on it. The wall renders correctly on the slab, but commits as:
i.e. data says terrain-hosted while the wall visibly stands on the slab — the #630-class plane-bound regression. Scenes with pre-existing geometry (e.g. the seeded dev fixture) are NOT affected, which is why private-editor's PR gate never caught it.
Not a recent regression
Bisect over
bab7ff1b..182f7c94found the baseline already bad — this predates the Aug-19 window (so #689/#690/#651/night-6 are exonerated). The variable is scene structure, not code history.Mechanism (file:line, editor @ 182f7c9)
In a fresh scene the newly drawn slab is the only registered top surface. The pointer support resolver then returns it as a node-top
sourceNodeId(packages/editor/src/components/tools/shared/pointer-support-cap.ts:155). The wall tool equates any suchsourceNodeIdwithflatConstructionBase = true(packages/nodes/src/wall/tool.tsx:745), andresolveWallConstructionthen forcibly electsground, preserves the level-derived draft height, and records the slab elevation assupportOffset(packages/core/src/hooks/spatial-grid/support-host-patch.ts:472). With pre-existing geometry the ray/surface route differs, ordinary slab election runs (no source node), and the wall stays plane-bound.Suspected fix locus: the
sourceNodeId → flatConstructionBase → groundcoercion — a slab-sourced support should elect the slab, not ground.Acceptance test, ready and waiting
pascalorg/private-editore2e/community/wall-plane-bound.spec.tsnow runs against an isolated fresh org project and istest.fixme'd with this exact reason (private-editor#389). Removing the fixme is the acceptance test: it asserts the committed wall carries no stampedheight/supportOffsetand a real slabsupportSlabId.Found by the regression-testing program's fixture-isolation work; discriminator screenshots + field dumps in the session records.
🤖 Generated with Claude Code