LearnNewsExamplesServices
Frontmatter
id18532
titleNative vessel re-show has no runtime witness that the outer footprint is preserved (mechanism mapped, preconditions measured)
stateClosed
labels
enhancementaitestingdashboard
assigneesneo-opus-vega
createdAtSep 9, 2026, 10:50 AM
updatedAtOct 3, 2026, 9:16 AM
githubUrlhttps://github.com/neomjs/neo/issues/18532
authorneo-opus-grace
commentsCount10
parentIssue18460
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[x] 19372 A parked vessel''s terminal re-show lands one title bar too high
blocking[x] 19375 A tear-out''s outer size has no runtime witness that it equals the tab body it replaced
closedAtOct 3, 2026, 9:16 AM

Native vessel re-show has no runtime witness that the outer footprint is preserved (mechanism mapped, preconditions measured)

Closed v13.2.0/archive-v13-2-0-chunk-20 enhancementaitestingdashboard
neo-opus-grace
neo-opus-grace commented on Sep 9, 2026, 10:50 AM

Serves: #18460 — Workstation vessel integration. Follow-up to #18515 (correct, merging).

The Problem

Native vessel park/re-show moves and resizes a real OS window, and nothing at runtime asserts the window ends up where it started. #18515 fixes a genuine coordinate-space defect on that path and proves it with unit tests that hand-feed the chrome value — so they verify the arithmetic, not the platform.

The defect class here is "the number meant something different than we assumed." A unit test that supplies chrome = {left: 8, top: 67} as a literal cannot catch it, because the assumption under test is the one the fixture encodes.

The Architectural Reality

The system deliberately captures position and size in different coordinate spaces, and that is the whole hazard:

resolveVesselConversionSourceRect()   →  Window.get(id).innerRect      position: INNER
parkTearOutVessel → restoreRect       →  sourceOuter.{x,y,width,height}  size: OUTER
Main#moveWindow                       →  win.moveTo(x, y)              places the FRAME
Main#resizeWindow                     →  win.resizeTo(w, h), verified against outerWidth/outerHeight

manager/Window.mjs:113 defines the bridge — outerRect.x = innerRect.x − chrome.left — which is exactly #18515's frame = rect − chrome. Correct, and correct only while every one of those four lines keeps its current meaning. Nothing fails loudly if one drifts.

What the pre-fix bug looked like: moveTo received the inner origin, so the frame landed where the content had been — the window shifted down-right by the chrome on every park/re-show, cumulatively. That is precisely the class an outer-rect assertion catches on the first cycle and a unit test never does.

Current coverage: test/playwright/unit/apps/workstation/Workspace.spec.mjs only, table-driven over [{left: 0, top: 0} → unchanged] and [{left: 8, top: 67} → subtracted]. No e2e, no real window, no chrome read from a browser.

Premise correction (2026-09-14)

There is no standalone park. NativeVesselTransaction#parkVessel refuses on !admissions.targetFocus.granted, and the target comes from VesselWorkspace.vesselConversionTargetWindowId, set only inside vessel-over-vessel conversion handlers. Calling parkTearOutVessel({itemId}) directly returns false and moves nothing — measured. AC-1/AC-2 above are re-worded accordingly.

Open and blocking the build, not the ticket: a two-vessel probe drove the real gesture and the park still refused with targetHasHandle/targetFocusCapable false, because resolveAdmissions reads the target window own nativeRoute and a popped-out vessel appears not to carry one. Whether the admissible target is therefore main rather than a second popup is unresolved. That question gates the harness; the invariant and the mechanism map below are unaffected.

The Fix

An e2e witness on a real native window asserting the invariant the design actually holds: a parked vessel re-shows at its original outer footprint.

AC

  • AC-1 An e2e spec parks a real tear-out vessel and re-shows it — re-worded, see the premise correction below. An e2e spec drives a real vessel-over-vessel conversion: two popped-out vessels, the source moved so its corner anchor lands inside the target, which is what sets the conversion target and parks the source; then moved back off, which restores it. It asserts the restored outer rect equals the pre-park outer rect within the platform admitted tolerance. The outer rect is the assertion subject — an inner-rect assertion passes under the pre-fix bug.
  • AC-2 The spec repeats that conversion cycle and asserts no cumulative drift. The pre-fix defect was per-cycle and additive, so a single round trip is the weakest form of this test.
  • AC-3 Chrome is read from the real window, never supplied by the fixture. A test that feeds its own chrome value reproduces the unit test's blind spot at higher cost.
  • AC-4 Mutation-proven: reverting #18515's frame to rect turns the spec red. Green on the fixed code proves nothing on its own.
  • AC-5 A window that publishes no chrome still re-shows content-on-frame — the documented pre-chrome fallback — so the spec covers chrome == null as well as a real value.

Related invariant, worth covering while the harness is open

The initial tear-out holds a separate contract: the popup's OUTER size must equal the tab body it replaced, so neighbouring items are not overlapped (the content is legitimately smaller by the chrome). #resizeWindow verifies against outerWidth/outerHeight, so the engine half is consistent — but this is an operator-stated UX invariant with no runtime witness that names it. If it is cheap once AC-1's harness exists, assert it; if not, it wants its own ticket rather than silent omission.

Out of Scope

#18515's arithmetic, which is correct. The reshowTearOutVessel implementation. Any change to Main's move/resize routes.

Avoided Traps

Do not assert the inner rect — it is preserved under both the buggy and fixed code, so the test would pass either way. Do not supply chrome from the fixture (AC-3). Do not accept a single park/re-show cycle as coverage (AC-2). Do not run the arm isolated if it has predecessors in its file — a spec whose siblings establish state fails differently alone.

Decision Record impact

none — test coverage for existing behaviour.

Sweeps and ownership

Live open-issue sweep run before filing; no ticket covers native vessel restore geometry. Verified against pull/18515/head.

Raised by @tobiu: "if this PR is messing with this one, without new e2e tests, i am scared." The PR does not mess with it — it repairs it — but the absence of a runtime witness is real and is what this ticket closes.

tobiu referenced in commit 79df068 - "test(workstation): a torn-out vessel's native control route gets a witness (#18824) (#18825) on Sep 17, 2026, 7:12 PM
tobiu referenced in commit 0fda799 - "test(workstation): a parked vessel re-shows at the outer frame it was parked from, witnessed on real chrome (#18532) (#19376) on Oct 3, 2026, 9:16 AM
tobiu closed this issue on Oct 3, 2026, 9:16 AM