Skip to content

Production parity implementation — 2026-09-09

Neither delivery gate is complete. This records implementation and verification following the source audit; it does not replace the broader coverage contract or certify Adventure Arena as 1:1.

Implemented

  • Removed the batch-only stack sizing, text-width subtraction, and padding wrappers. Both candidates now exercise the ordinary Lua/native constructors.
  • AppKit and UIKit stacks measure current content, inherit flexibility by axis, preserve explicit zero sizes, ignore hidden siblings, and distribute weighted spacers. Constrained HStacks negotiate text widths; native labels wrap and recover their intrinsic size after resizing or editing.
  • Corrected AppKit multiline paragraph metrics, native label drawing mode, and asymmetric top/bottom padding. Text rendering remains a native NSTextField.
  • Corrected scroll document measurement and clipping. AppKit preserves the top reading position across viewport changes; UIKit no longer resets scroll offset on every layout pass or inherits old document widths/heights.
  • Native macOS tabs preserve initial/current selection and fill their parent. Selected content receives layout after native tab selection and resizing.
  • Added AppKit NavigationStack through public NSPageController. UIKit uses UINavigationController and restores native titles/Back behavior for pushed screens. Both expose depth/currentController and retain root page state.
  • UIKit TextField now separates value from placeholder and dispatches native editing/Return events through the same onChange/onCommand contract as AppKit.
  • AppKit Image accepts the path property and uses native NSImageView centering and clipping for aspect fill. Image modes and clear/restore round-trip on both platforms. Plain/icon AppKit buttons use NSButton instead of an opaque compound card. Stack overlays can opt out of hit testing with allowsHitTesting=false; the hero artwork button is reachable beneath its caption overlay.
  • Adventure Arena catalog data now preserves all nine sorted source entries, descriptions, genres, corrected counts, and all 21 reviews. Views and session state were extracted from the controller. Catalog → detail → session stays in one app root, with a typed-command composer and startup-error recovery. The fabricated ongoing-session row was removed.
  • ZIL loading and execution restore global IO/import paths after success or failure, including streamed iOS reads. This is not full runtime-state isolation or deterministic replay.
  • Screenshot capture applies requested size before its settling interval, uses process arguments instead of shell interpolation, and returns failure for missing captures. Native macOS captures required execution outside the sandbox; sandboxed captures could not access WindowServer images.

Verification

  • make test parity-check uikit ios-host: 57/57 Lua test files pass; 13 gallery cases validate; AppKit and both UIKit build targets succeed.
  • Python batch protocol suite: 8/8 pass.
  • lua/parity/contracts.lua: 63 native assertions, invoked by the macOS headless test and the live UIKit batch host. Covers empty/fixed/hidden stacks, resize and text mutation, weighted spacers, asymmetric padding, editing events, navigation, overlay hit testing, and image-property round-trips.
  • Independent SwiftUI geometry comparison, without candidate adapter adjustments: macOS 222/224, iOS 218/224. These are geometry results only; no gallery case or delivery gate was promoted to verified.
  • Final source/build/run identities and remaining case IDs are retained in production-geometry-2026-09-09.json. Full generated runs are under build/parity/runs/parity-production-macos-008 and build/parity/runs/parity-production-ios-005, compared with the independent reference-final / ios-reference-final runs.
  • Native macOS screenshots inspected at 420×360, 640×720, and 1000×900, covering home, detail, a real Wondertown session, and injected startup failure in light and dark appearances. Layout dumps were inspected before and after fixes.
  • iPhone 17 / iOS 26.5 screenshots inspected for home in both appearances, detail, a real Wondertown session, and startup failure. Pushed screens show native navigation titles and Back controls. UI evidence is an application smoke test, not a paired visual comparison against the SwiftUI app.

Local visual artifacts: /tmp/adventure-macos-*.png, /tmp/adventure-ios-*.png, /tmp/adventure-mvp-layout.xml, and /tmp/adventure-mvp-small.xml. They are generated development evidence, not committed golden images. A temporary harness under build/parity/adventure-qa selects app states without adding production-only testing branches.

Remaining work

  1. Resolve the two macOS and six iOS narrow HStack geometry cases. Remaining differences involve nested width negotiation, native text rounding and height-constrained wrapping. Do not add candidate-only normalizations.
  2. Run paired visual and interaction verification for the 13 gallery cases and the rest of the exported API inventory. Existing export gaps remain those in the plan/coverage ledger. Full keyboard, accessibility, and every affected example's state matrix have not been signed off.
  3. Implement retained structural reconciliation before expanding dynamic app subtrees. The existing ui.viewdesc.apply stub is still unfinished.
  4. Adventure Arena still needs persistent saves/replay/deletion, its featured carousel and gradient treatment, the complete detail/review layout, ongoing sessions, full composer/history/suggestions/exits/companion behavior, reading preferences, the create-game form, settings/help, and translation-related behavior. The current in-memory session is not saved by closing its screen.
  5. Align or deliberately resolve the different zilscript submodule pins; prove independent session/RNG state and replay fidelity. Only Wondertown startup and command execution have been exercised against the real engine in this pass.

Native implementation references: SwiftUI layout proposals and NSPageController history.