Skip to content

Native forms: share geometry and paint owners without a styles mirror - #135

Merged
trissim merged 8 commits into
mainfrom
refactor/native-forms
Oct 16, 2026
Merged

trissim merged 8 commits into
mainfrom
refactor/native-forms

Conversation

@trissim

@trissim trissim commented Oct 15, 2026 •

Copy link
Copy Markdown

Status

Draft; Codex independent source approval received. Not globally installed or application-accepted. Current source e2fd8a336 pairs native forms with #134 at 9a18a0f0fe41a2d5edde25f9e2371de1c3877559. The only merge conflict was Widget imports; both paint/geometry and primary-activation imports are retained. #134 implementation and safeguards are not replaced.

Paired Toad Textualize#670 at ea3371713 uses this exact source in both pyproject and uv.lock, with ObjectState #61, FormBridge #13 and Core Textualize#921. Its shared Toad ModalScreen capability is retained from Textualize#664. uv lock --check --offline passes; this is graph validation, not runtime acceptance.

Ownership change

  • BoxGeometry owns the existing sizing, extrema, gutter, alignment, offset, relative/auto and dock-split algorithms. StylesBase supplies CSS inputs through inheritance; native widgets supply themselves. DOMNode.geometry returns the existing Styles object for CSS. No effective-style mirror.
  • Geometry consumers migrated across Widget/DOM/measurement/resolve/arrange/layout, stream/horizontal/vertical/grid, compositor/screen/scroll and built-in controls. Old BoxModel/Extrema resolve paths are deleted. Meaningfully distinct gutter, placement offset and declared scrollbar-size contracts remain distinct.
  • Widget DEFAULT_LAYOUT supplies layout policy through the owning type; forms choose StreamLayout without CSS.
  • PaintState.resolve owns inherited alpha/color resolution over PaintLayer. CSS supplies its existing descriptor inputs; native widgets supply live inputs without an unrelated CSS-generation cache. The detached resolution function is deleted.
  • FramePaint owns the line painter's inputs and derived plain/key behavior; existing PaintStyles snapshots CSS. StylesCache uses the actual frame/background/style/padding inputs and retires the original cache on changes rather than adding another cache. Widget supplies frame_paint/refresh_paint.
  • Select's existing child construction uses declared CURRENT/OVERLAY types so the native form's current-value child shares the real control. Defaults for normal Select are unchanged.

The source change is load-bearing in both CSS-backed and native paths, not a native wrapper around copied styles. Native forms are supplied by Toad Textualize#670; the converted settings CSS and form/dialog inline writes are deleted there.

Source evidence and current checks

  • Existing NRA syntax/class-family tooling enumerated declarations, writes, decisions, checks, imports, inheritance and consumers before editing. Original 656-module geometry census: 2,658 original classes / 2,642 nominal projections, 16 OPEN, no parse errors. Original source reconstructed from actual Git baseline 96a2ca03f rather than relabeling current source.
  • Earlier combined Core/Toad/Textual/FormBridge/ObjectState/python-introspect source census: 999 modules, 5,166 original classes / 5,150 nominal projections, 16 OPEN, no parse errors; 27,398 selected sites (the field-name pass also includes the bridge ObjectState and preview-request modules). This corrects an earlier dependency input: the previous source census used python-introspect 0.2.8 source, now replaced by the actual cached 0.3.0 registry payload. The four-class change is that dependency correction, not new refactor classes. Dynamic aliases, runtime MRO and invocation effects remain outside nominal static proof.
  • All 983 Python files in the five changed projects parse; whitespace checks pass. Ancestry verifies Share modal editing through native TextArea owners #134 is present in the pinned source.
  • The final three missed consumers are corrected: native Settings sizing shares Screen's breakpoint resolver with CSS classes; scrollbar painting reads BoxGeometry; selection reads geometry.position and the actual default layer. Toad ScreenWidth declarations own thresholds and side-panel widths, with CSS classes derived. Seven existing focused compositor/selection checks passed in 1.68s. Source declaration/resolver smoke covers 99/100/101 columns and reversal. No new census, tests or synthetic app. This is not saved-app or resolved candidate acceptance.

Detailed owned indexes/searches: /home/ts/.cache/agent-scratch/core-native-formbridge/{native-before-index,path-cohort-index}-family-sites.json; source relationships/results: Core Textualize#921 docs/native-formbridge-paths.md and Toad Textualize#670 description.

Remaining acceptance

  • Codex independent source review of this large draft and paired fix for footer Textualize/textual#670.
  • Direct StylesCache.render callers/tests migrated to its FramePaint contract; relevant focused Textual checks.
  • Actual saved settings/sort application journey, including normal CSS controls, native child sizing, focus, validation, theme/content/resize changes, persistence and warm returns.
  • Reviewed Codex global integration and installed live-path acceptance.

Codex explicitly abandoned the earlier uncertain candidate for deployment; its evidence remains untouched and is not reused or replayed. One fresh exact-source candidate in a different output is authorized; global integration/installation stays with Codex. The persistent goal remains BLOCKED.

@trissim

trissim commented Oct 16, 2026

Copy link
Copy Markdown
Author

Implementation and application-verification owner: core-route-counts; Codex owns paired integration/build/install with Toad Textualize#670. Full 2,238-line diff against current Textual main 2d3aecb read: native BoxGeometry/PaintLayer/FramePaint ownership is not present in main and is still needed; deleted CSS-only extrema/box/paint paths are not superseded by merged Vim #134. Keep DRAFT, not merged/installed. Needs ordinary current-main integration preserving the new HintHost lifecycle, completion of the native Forms boundary work and direct render consumers, then real Settings/Sort acceptance. Owner remains BLOCKED on its retained tool-supply/implementation dependencies; this note neither clears the blocked goal nor authorizes replay or a competing implementation.

trissim and others added 4 commits October 16, 2026 18:19
…ma hook tests

StylesCache.render takes FramePaint with padding from widget geometry; the
tests now build PaintStyles the same way. _resolve_extrema no longer exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ction

- BoxGeometry owns sizing_gutter, stable_gutter and the default layer name
  (DEFAULT_LAYER); layout, widget, selection, compositor and styles read
  them instead of re-testing CSS strings.
- Alignment offsets come from the declared AlignHorizontal/AlignVertical
  order instead of per-value ternaries.
- One border_label function replaces DOMNode's duplicated title and
  subtitle style methods and the two matching blocks in StylesCache.
- StylesCache.render requires the caller's padding instead of substituting
  zero; the paint-state cache names its shared reuse precondition once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
StylesCache.render no longer substitutes zero padding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@trissim

trissim commented Oct 16, 2026

Copy link
Copy Markdown
Author

Taken over from forms-migration (claude-forms). Merged current main (2d3aecb) and fixed the debt ratchet failure the branch had.

Ownership changes (0473f98..0e66227)

  • BoxGeometry owns sizing_gutter, stable_gutter and DEFAULT_LAYER. _compositor, css/styles, selection and widget read them instead of re-testing "border-box", "stable", "none" and "default" strings. widget.py now uses geometry.is_docked instead of a duplicate dock != "none".
  • Alignment offsets come from the declared AlignHorizontal/AlignVertical Literal order (start, middle, end) instead of four per-value ternaries. The offsets are identical: index 1 is (free)//2, index 2 is free.
  • One border_label() in _styles_cache.py replaces DOMNode's duplicate _get_title_style_information/_get_subtitle_style_information (StylesCache was their only caller) and the two matching blocks in render_widget.
  • StylesCache.render requires the caller's padding (keyword-only) instead of silently substituting zero. The painted = styles alias is gone.
  • _resolved_paint_state names its shared reuse precondition once instead of two 4-term chains.
  • Tests: render calls pass PaintStyles.of(...) with explicit padding. The two tests of the deleted _resolve_extrema hook are removed.

Checks

  • python -m agent_comms.debt_ratchet --root src --base origin/main --head 0dff6ce46.. exits 0, with no positive deltas and no introduced debt (before the fix: exit 1, with banned vocabulary, +10 string comparisons, StylesCache +13 / DOMNode +4 god-class lines, and +12 boolean-chain terms).
  • Non-snapshot suite: the only failure not on main is test_highlight.py::test_guess_language[import this-foo.py-python]. It is flaky from the environment: Pygments ties the Python and IPython lexers for foo.py, and a direct call returns ipython on main as well. Repeated runs alternate between pass and fail.
  • The snapshot harness fails the same 33 tests on main in this environment. Instead, I compared headless export_screenshot() output at 80x24 for 37 docs examples (styles align/border/title/box-sizing/dock/layers/offset/outline/scrollbar-gutter/text-align, and the whole layout guide): all are byte-identical between main and this branch.

@trissim
trissim marked this pull request as ready for review October 16, 2026 22:31
Copilot AI balanced review requested due to automatic review settings October 16, 2026 22:31
@trissim
trissim merged commit 25aad30 into main Oct 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@trissim
trissim deleted the refactor/native-forms branch October 17, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants