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
11 changes: 11 additions & 0 deletions evidence/focus-rule-supply-20261006/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Focus rule supply

The existing RuleSet parser owns pseudo-class dependencies from every selector, including ancestor and nested selectors. Stylesheet.rules_map now indexes those declarations alongside target names. Focus/blur/focus-within acquisition selects indexed rules and deletes its scan of every rule for every changed scope. Actual dynamic selector checks, nested-scope target traversal, component/virtual DOM handling and cascade application remain unchanged. Candidate collection unions rule identities; cascade precedence still comes from the unchanged apply path.

The rules_map reader first acquires rules, so a pending read/parse cannot serve an older index. Successful parse and reparse retire the same existing index; copies retain their normal source/parse lifetime. New pseudo-class keys cannot collide with native target keys (type, *, #id, .class). No new cache or registry.

AST before: 249 native production, 467 test and 288 Toad production modules, zero omissions. RuleSet._post_parse is the dependency producer; Stylesheet.rules_map is the one index; App application focus, Widget focus and Screen changed focus-within scopes converge on _update_focus_dependencies. Existing matching/index readers were inspected. After native parser: 249 modules, zero omissions. External dynamic mutation is not proven absent by lexical AST; no new support for post-parse selector mutation is claimed. Three production lines replaced; index lifetime and all three focus consumers use the existing owner.

Seven focused controls passed, including real mounted descendants/components across CSS read and reparse. One original matched sidebar App finished zero with empty stderr, 508 widgets/10 tabs, no provider. Right profile: same three focus updates, own declaration discovery 7.05ms -> .47ms and full method 19.03ms -> 11.22ms. Left full method 18.51ms -> 7.99ms. This is a single source headless observation. First-display medians 41.8/42.2ms versus 40.1/45.6ms, tails vary, paint was slower: no reliable overall frame or live speedup claim.

RESULT.json binds original raw profiles/logs and source evidence. No new build, install, provider, public operation or repeated benchmark. The existing empty-damage pending_for checkpoint remains on this same PR, independently scoped.
44 changes: 44 additions & 0 deletions evidence/focus-rule-supply-20261006/RESULT.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"source": "6c5c0a055",
"controls": "7 passed in 1.09s",
"app_exit": 0,
"app_widgets": 508,
"app_tabs": 10,
"providers": 0,
"metrics": {
"before": {
"channels": {
"calls": 3,
"own_seconds": 0.006711723,
"inclusive_seconds": 0.018510871
},
"thread": {
"calls": 3,
"own_seconds": 0.007046747000000001,
"inclusive_seconds": 0.019031289
}
},
"after": {
"channels": {
"calls": 3,
"own_seconds": 0.00039156600000000004,
"inclusive_seconds": 0.007986836
},
"thread": {
"calls": 3,
"own_seconds": 0.00046633400000000005,
"inclusive_seconds": 0.011223700000000001
}
}
},
"scope": "Single source App completed headless first-display check, not installed/live/terminal-pixel latency. Whole-frame medians and tails vary; no reliable overall speedup.",
"keepers": {
"evidence/focus-rule-supply-20261006/before.json": "66889e3b9ba8f9bcb5b50e9c5d9bdfd0114f0b83a43897a89287bf99891d77bf",
"evidence/focus-rule-supply-20261006/after.json": "554f279fe1d0248212feea3dcbf0d3f69bb0ac2276fcdbd635676319dfd9312e",
"evidence/focus-rule-supply-20261006/controls.log": "c928e2b325450f4fe53ea38feef281d6c7aed611956284bd9706a12f60e5c96a",
"/home/ts/.cache/agent-scratch/focus-rule-supply-20261006/app.stdout.log": "5247e1d6a489d95bcead12039f0c6af7ada02fe1327cdf371d94b8a1a02f3c2d",
"/home/ts/.cache/agent-scratch/focus-rule-supply-20261006/app.stderr.log": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"/home/ts/.cache/agent-scratch/focus-rule-supply-20261006/toggle-channels.pstats": "187497551c23b99916e7083098982a659112bdf7dcba9f7ea08ea63fff617fc6",
"/home/ts/.cache/agent-scratch/focus-rule-supply-20261006/toggle-thread.pstats": "762601eab880b54be284c0412aab7b5787a8b40bcc284a4b9af5962401140b89"
}
}
103 changes: 103 additions & 0 deletions evidence/focus-rule-supply-20261006/after.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"revision": "6c5c0a055d3ae2eb881858ea2e97228eda97bebe",
"parsed": 249,
"omissions": [],
"sites": [
[
"src/textual/app.py",
4423,
"self.stylesheet.update_app_focus",
"Load"
],
[
"src/textual/css/stylesheet.py",
172,
"self._rules_map",
"Store"
],
[
"src/textual/css/stylesheet.py",
227,
"self._rules_map",
"Load"
],
[
"src/textual/css/stylesheet.py",
408,
"self._rules_map",
"Store"
],
[
"src/textual/css/stylesheet.py",
464,
"self._rules_map",
"Store"
],
[
"src/textual/css/stylesheet.py",
571,
"self.rules_map",
"Load"
],
[
"src/textual/css/stylesheet.py",
980,
"self.rules_map",
"Load"
],
[
"src/textual/css/stylesheet.py",
219,
"self._rules_map",
"Load"
],
[
"src/textual/css/stylesheet.py",
226,
"self._rules_map",
"Store"
],
[
"src/textual/css/stylesheet.py",
499,
"self._rules_map",
"Store"
],
[
"src/textual/css/stylesheet.py",
628,
"self.rules_map",
"Load"
],
[
"src/textual/css/stylesheet.py",
948,
"self._update_focus_dependencies",
"Load"
],
[
"src/textual/css/stylesheet.py",
957,
"self._update_focus_dependencies",
"Load"
],
[
"src/textual/css/stylesheet.py",
961,
"self._update_focus_dependencies",
"Load"
],
[
"src/textual/screen.py",
1101,
"self.app.stylesheet.update_focus_within",
"Load"
],
[
"src/textual/widget.py",
4322,
"self.app.stylesheet.update_widget_focus",
"Load"
]
]
}
Loading
Loading