Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions evidence/native-content-height-consumption-20261005/SCOPE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Bound native Content formatting at its original render height

Base: Text68/69 merged c1bcc8d33164553432f2a718eeddec1a1ffa4a5f.

Existing Content.render_strips calls its original _wrap_and_format owner for
ALL paragraphs / _FormattedLine resources before slicing that result to the
requested height. Visual's render height already declares which prefix is
needed; RichVisual bounds its own segment stream with islice, while Content
constructs the unused suffix first.

Make the existing Content formatting algorithm an iterator. Migrate its entire
consumer family: complete wrap and height measurement consume all; bounded
strip rendering consumes its required prefix; original negative slicing stays
complete before slicing. Public Visual/render_strips/list and wrap/list
contracts, source selection/link/wide-cell metadata and original Content.split
resource remain unchanged. Delete the unused complete formatted-result list.
No new class, cache, map, timer, flag, alternate renderer or Toad implementation.

The initial published iterator source was
71e8c7fd4486b772252dafe7556b91e23a08fab9 (7 additions / 10 deletions).
The same owner now also yields each wrapped line directly: no complete
per-paragraph formatting list, intermediate truncated-content list, or
throwaway _FormattedLine solely for its content field. Original loop_last
supplies the last-line justification fact at construction instead of mutating
the last member of a completed list. Current production delta is 23 additions /
34 deletions in one file. Unrequested wrapped suffixes no longer construct
formatted lines or apply their truncation/padding. Original Content.split and
divide still acquire source slices and wrapping boundaries; neither is claimed
eliminated or height bounded.

The before AST covers 249 native production files / 460 native test files and
288 Toad production files / 397 test files / 41 tools with zero parse omissions.
It identifies one formatter declaration, three native production readers,
two native test count readers plus one monkeypatch, and ONE extra Toad private
reader: PathContent.render_strips in path_search.py. That reader slices the
formatter result and must migrate before qualification. Heisenberg owns this
Toad change, preserving original path shortening, nowrap/clip/tab8/left/zero
padding and RenderOptions through Content.render_strips. PreparedDiffLine
inherits the original rendering implementation without an override.

ONE final native source batch executed at
81ca92b137e3070b31abb5146b7bae6f8043e228, production tree
90f78e605a8dc1470d1de8c19220ab4b26474706: 348 PASS / 0 FAIL in 0.76s
(pytest), controller 2.499691362027079s, terminal 0. Original Content wrapping,
complete height measurement (including no available width), and public
bounded/full/negative rendering preserve strip cells, link/wide-cell/selection
metadata and post styles. Original log SHA256:
9c92eb8034b308320e4b038c3781be785dd0f3a557acc06d39b237548b1125a4.
Heisenberg published PathContent delegation at
1fbe1f09b80dec9a809609edaeafc6ddb5a661a2 (Toad463); final AST finds zero
Toad private formatter readers. The complete native producer read then found a
caller contract defect: Visual.to_strips supplies widget.styles, not a dict,
and Styles/RenderStyles has no mapping-union operation. PathContent currently
unions that resource with its four fixed rules. Heisenberg corrected that original four-rule leaf policy directly at
a4d7cb17435470edd1276360d9c9a26593c4a031 while preserving all other RenderOptions fields.
Final source AST retains zero Toad private formatter readers, one public
Content delegation, and no parse omissions. Unchanged test/tool AST is carried
by exact original Git tree identity; no repeated parse or checks are claimed.
The original 1fbe counterexample remains recorded as source evidence, not an
executed UI failure. Complete declared source family and native source controls
are closed; the changed installed caller/frame journey remains unqualified. No installed App/frame/motion qualification
exists for Text70. Unregistered external private readers and runtime rebinding
are not proved by the AST.

The original recorded59.605 RichVisual stack does NOT identify Content or its
widget/invalidation cause. This independent unused-resource source finding is
not an attribution of that sample, a CPU share or a measured speedup.

AST complete production/dependency/test caller and override evidence precedes
editing; coherent source change then one affected control batch and joined
installed meaningful frame check. No App/build/installed/SDK/provider/media
purpose exists now. Text68/69 wheel a0c2 and qualification stay frozen.
276 changes: 276 additions & 0 deletions evidence/native-content-height-consumption-20261005/after.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
{
"roots": [
{
"repository": "/home/ts/wt/textual-native-subtree-strips-20261002",
"head": "325a912635f55f6ec15b8365530a66c04edaf1ad",
"root": "src/textual",
"parsed": 249,
"omitted": []
},
{
"repository": "/home/ts/wt/textual-native-subtree-strips-20261002",
"head": "325a912635f55f6ec15b8365530a66c04edaf1ad",
"root": "tests",
"parsed": 460,
"omitted": []
},
{
"repository": "/home/ts/wt/toad-viewport-raster-cpu-continuation-20261001",
"head": "a4d7cb17435470edd1276360d9c9a26593c4a031",
"root": "src/toad",
"parsed": 288,
"omitted": []
},
{
"repository": "/home/ts/wt/toad-viewport-raster-cpu-continuation-20261001",
"head": "1fbe1f09b80dec9a809609edaeafc6ddb5a661a2",
"root": "tests",
"parsed": 397,
"omitted": []
},
{
"repository": "/home/ts/wt/toad-viewport-raster-cpu-continuation-20261001",
"head": "1fbe1f09b80dec9a809609edaeafc6ddb5a661a2",
"root": "tools",
"parsed": 41,
"omitted": []
}
],
"formatter_sites": [
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 1724,
"node": "ClassDef",
"name": "_FormattedLine",
"source": "class _FormattedLine:"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 638,
"node": "FunctionDef",
"name": "_wrap_and_format",
"source": " def _wrap_and_format("
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 650,
"node": "Name",
"name": "_FormattedLine",
"source": "_FormattedLine"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 1532,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 1552,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 736,
"node": "Name",
"name": "_FormattedLine",
"source": "_FormattedLine"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 736,
"node": "Attribute",
"name": "_wrap_and_format",
"source": "self._wrap_and_format"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 1011,
"node": "Attribute",
"name": "_wrap_and_format",
"source": "self._wrap_and_format"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 1535,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 1537,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 691,
"node": "Name",
"name": "_FormattedLine",
"source": "_FormattedLine"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 707,
"node": "Name",
"name": "_FormattedLine",
"source": "_FormattedLine"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 618,
"node": "Attribute",
"name": "_wrap_and_format",
"source": "self.without_spans._wrap_and_format"
},
{
"root": "src/textual",
"path": "src/textual/content.py",
"line": 688,
"node": "Name",
"name": "_FormattedLine",
"source": "_FormattedLine"
},
{
"root": "src/textual",
"path": "src/textual/document/_wrapped_document.py",
"line": 197,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/document/_wrapped_document.py",
"line": 212,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/document/_wrapped_document.py",
"line": 267,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/widgets/_log.py",
"line": 231,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/widgets/_log.py",
"line": 235,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/widgets/_log.py",
"line": 239,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/widgets/_log.py",
"line": 240,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "src/textual",
"path": "src/textual/widgets/_log.py",
"line": 233,
"node": "Name",
"name": "new_lines",
"source": "new_lines"
},
{
"root": "tests",
"path": "tests/test_content_measurement_projection.py",
"line": 17,
"node": "Constant",
"name": "_wrap_and_format",
"source": "\"_wrap_and_format\""
},
{
"root": "tests",
"path": "tests/test_content_measurement_projection.py",
"line": 16,
"node": "Attribute",
"name": "_wrap_and_format",
"source": "content.without_spans._wrap_and_format"
},
{
"root": "tests",
"path": "tests/test_content_measurement_projection.py",
"line": 25,
"node": "Attribute",
"name": "_wrap_and_format",
"source": "content.without_spans._wrap_and_format"
}
],
"limits": "Syntactic source evidence only; runtime rebinding and unregistered external private readers unresolved. Native source/tests AST is reused from identical 325a source; Toad source successor is pinned independently. No installed frame, motion or CPU attribution.",
"toad_private_formatter_readers": [],
"toad_public_content_delegations": [
{
"root": "src/toad",
"path": "src/toad/widgets/path_search.py",
"line": 70,
"source": "Content.render_strips(\n line,\n width,\n height,\n style,\n replace(\n options,\n rules={\n \"text_wrap\": \"nowrap\",\n \"text_overflow\": \"clip\",\n \"text_align\": \"left\",\n \"line_pad\": 0,\n },\n ),\n )"
}
],
"path_contract_counterexample": {
"source": "1fbe1f09b80dec9a809609edaeafc6ddb5a661a2",
"producer": "src/textual/visual.py Visual.to_strips constructs RenderOptions with widget.styles; src/textual/widgets/_option_list.py uses that path",
"failure": "Styles/RenderStyles supports get but not mapping union; PathContent options.rules | dict is not supported by the real producer",
"correction_owner": "Heisenberg, Toad463",
"required_correction": "Preserve the four original fixed render rules directly; leave the other RenderOptions fields unchanged. No native change or reproduction required.",
"corrected_source_head": "a4d7cb17435470edd1276360d9c9a26593c4a031",
"correction": "Original four fixed Path render rules are supplied directly in replace(options); native Styles is no longer used as a mapping-union operand."
},
"source_preserving_transitions": [
{
"root": "tests",
"parsed_at": "1fbe1f09b80dec9a809609edaeafc6ddb5a661a2",
"source_head": "a4d7cb17435470edd1276360d9c9a26593c4a031",
"tree": "72d50efa1f3c1fe3379fbff2981313fefddb9a1a",
"source_equal": true
},
{
"root": "tools",
"parsed_at": "1fbe1f09b80dec9a809609edaeafc6ddb5a661a2",
"source_head": "a4d7cb17435470edd1276360d9c9a26593c4a031",
"tree": "5f291b2f613803e0b1596581215557f35c65c8d6",
"source_equal": true
}
]
}
Loading
Loading