[{"data":1,"prerenderedAt":708},["ShallowReactive",2],{"navigation_docs":3,"-decisions-0019-upstream-kyo-issues-as-drafts":223,"-decisions-0019-upstream-kyo-issues-as-drafts-surround":703},[4,26,96,105,202],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":16,"path":17,"stem":18,"icon":19},"The first app","\u002Fgetting-started\u002Ffirst-app","1.getting-started\u002F2.first-app","i-lucide-play",{"title":21,"path":22,"stem":23,"icon":24},"The first test","\u002Fgetting-started\u002Ffirst-test","1.getting-started\u002F3.first-test","i-lucide-flask-conical",false,{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":25},"Guide","i-lucide-book-open","\u002Fguide","2.guide",[32,37,42,47,52,57,62,67,72,77,81,86,91],{"title":33,"path":34,"stem":35,"icon":36},"Components","\u002Fguide\u002Fcomponents","2.guide\u002F01.components","i-lucide-component",{"title":38,"path":39,"stem":40,"icon":41},"Inputs and forms","\u002Fguide\u002Finputs-and-forms","2.guide\u002F02.inputs-and-forms","i-lucide-text-cursor-input",{"title":43,"path":44,"stem":45,"icon":46},"Scrolling and viewports","\u002Fguide\u002Fscrolling","2.guide\u002F03.scrolling","i-lucide-scroll-text",{"title":48,"path":49,"stem":50,"icon":51},"Overlays and layers","\u002Fguide\u002Foverlays","2.guide\u002F04.overlays","i-lucide-layers",{"title":53,"path":54,"stem":55,"icon":56},"Styles and theme","\u002Fguide\u002Fstyles","2.guide\u002F05.styles","i-lucide-palette",{"title":58,"path":59,"stem":60,"icon":61},"Composables","\u002Fguide\u002Fcomposables","2.guide\u002F06.composables","i-lucide-puzzle",{"title":63,"path":64,"stem":65,"icon":66},"Widgets","\u002Fguide\u002Fwidgets","2.guide\u002F07.widgets","i-lucide-blocks",{"title":68,"path":69,"stem":70,"icon":71},"The assistant","\u002Fguide\u002Fassistant","2.guide\u002F08.assistant","i-lucide-message-square",{"title":73,"path":74,"stem":75,"icon":76},"The same app on the web","\u002Fguide\u002Fweb","2.guide\u002F09.web","i-lucide-globe",{"title":78,"path":79,"stem":80,"icon":24},"Testing","\u002Fguide\u002Ftesting","2.guide\u002F10.testing",{"title":82,"path":83,"stem":84,"icon":85},"Running and packaging","\u002Fguide\u002Fpackaging","2.guide\u002F11.packaging","i-lucide-package",{"title":87,"path":88,"stem":89,"icon":90},"The terminal contract","\u002Fguide\u002Fterminal","2.guide\u002F12.terminal","i-lucide-square-terminal",{"title":92,"path":93,"stem":94,"icon":95},"Benchmarks","\u002Fguide\u002Fbenchmarks","2.guide\u002F13.benchmarks","i-lucide-gauge",{"title":97,"icon":98,"path":99,"stem":100,"children":101,"page":25},"AI and agents","i-lucide-bot","\u002Fai","3.ai",[102],{"title":97,"path":103,"stem":104,"icon":98},"\u002Fai\u002Fagents","3.ai\u002F1.agents",{"title":106,"icon":107,"path":108,"stem":109,"children":110},"Decisions","i-lucide-scale","\u002Fdecisions","4.decisions",[111,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198],{"title":112,"path":108,"stem":113,"icon":46},"All decisions","4.decisions\u002Findex",{"title":115,"path":116,"stem":117},"0001. kyo-ui is the DSL","\u002Fdecisions\u002F0001-kyo-ui-is-the-dsl","4.decisions\u002F0001-kyo-ui-is-the-dsl",{"title":119,"path":120,"stem":121},"0002. jatatui renders the cells","\u002Fdecisions\u002F0002-jatatui-renders-the-cells","4.decisions\u002F0002-jatatui-renders-the-cells",{"title":123,"path":124,"stem":125},"0003. Pin Kyo 1.0.0-RC7 and JDK 25","\u002Fdecisions\u002F0003-pin-kyo-rc7-and-jdk-25","4.decisions\u002F0003-pin-kyo-rc7-and-jdk-25",{"title":127,"path":128,"stem":129},"0004. Public Kyo APIs only","\u002Fdecisions\u002F0004-public-kyo-apis-only","4.decisions\u002F0004-public-kyo-apis-only",{"title":131,"path":132,"stem":133},"0005. A SOFT frame contract and an own watcher loop","\u002Fdecisions\u002F0005-soft-frame-contract-and-own-watcher-loop","4.decisions\u002F0005-soft-frame-contract-and-own-watcher-loop",{"title":135,"path":136,"stem":137},"0006. Purity: edge files, lint and a pure painter","\u002Fdecisions\u002F0006-purity-edge-files-and-lint","4.decisions\u002F0006-purity-edge-files-and-lint",{"title":139,"path":140,"stem":141},"0007. Compiler flags from sbt-tpolecat","\u002Fdecisions\u002F0007-compiler-flags-from-sbt-tpolecat","4.decisions\u002F0007-compiler-flags-from-sbt-tpolecat",{"title":143,"path":144,"stem":145},"0008. The artifact split: runner, app, testkit and core","\u002Fdecisions\u002F0008-artifact-split-runner-app-testkit-core","4.decisions\u002F0008-artifact-split-runner-app-testkit-core",{"title":147,"path":148,"stem":149},"0009. tui4s-use and tui4s-widgets, cross-built","\u002Fdecisions\u002F0009-use-and-widgets-cross-built","4.decisions\u002F0009-use-and-widgets-cross-built",{"title":151,"path":152,"stem":153},"0010. The flagship assistant is the blueprint of a real app","\u002Fdecisions\u002F0010-the-flagship-assistant-as-blueprint","4.decisions\u002F0010-the-flagship-assistant-as-blueprint",{"title":155,"path":156,"stem":157},"0011. The web target: a standalone Scala.js app and one theme","\u002Fdecisions\u002F0011-web-target-standalone-scalajs-and-one-theme","4.decisions\u002F0011-web-target-standalone-scalajs-and-one-theme",{"title":159,"path":160,"stem":161},"0012. The documentation is example-first","\u002Fdecisions\u002F0012-documentation-is-example-first","4.decisions\u002F0012-documentation-is-example-first",{"title":163,"path":164,"stem":165},"0013. Benchmarks in the repository, with their own build","\u002Fdecisions\u002F0013-benchmarks-in-repo-with-own-build","4.decisions\u002F0013-benchmarks-in-repo-with-own-build",{"title":167,"path":168,"stem":169},"0014. Release per module, by tag, as 0.1.0-RC1","\u002Fdecisions\u002F0014-release-per-module-tags-and-rc1","4.decisions\u002F0014-release-per-module-tags-and-rc1",{"title":171,"path":172,"stem":173},"0015. Packaging: the AOT cache in the start scripts, native-image as an option","\u002Fdecisions\u002F0015-packaging-aot-cache-and-native-image","4.decisions\u002F0015-packaging-aot-cache-and-native-image",{"title":175,"path":176,"stem":177},"0016. Process: lean mode and agent roles","\u002Fdecisions\u002F0016-process-lean-mode-and-agent-roles","4.decisions\u002F0016-process-lean-mode-and-agent-roles",{"title":179,"path":180,"stem":181},"0017. Deferred: templates, mouse, the kitty keyboard protocol and Windows","\u002Fdecisions\u002F0017-deferred-templates-mouse-and-kitty","4.decisions\u002F0017-deferred-templates-mouse-and-kitty",{"title":183,"path":184,"stem":185},"0018. pini4s is a vendored Git submodule","\u002Fdecisions\u002F0018-pini4s-as-a-vendored-submodule","4.decisions\u002F0018-pini4s-as-a-vendored-submodule",{"title":187,"path":188,"stem":189},"0019. Upstream issues are drafts that the user posts","\u002Fdecisions\u002F0019-upstream-kyo-issues-as-drafts","4.decisions\u002F0019-upstream-kyo-issues-as-drafts",{"title":191,"path":192,"stem":193},"0020. Release from the Actions form","\u002Fdecisions\u002F0020-release-from-the-actions-form","4.decisions\u002F0020-release-from-the-actions-form",{"title":195,"path":196,"stem":197},"0021. The rulebook is CONTRIBUTING.md","\u002Fdecisions\u002F0021-the-rulebook-is-contributing-md","4.decisions\u002F0021-the-rulebook-is-contributing-md",{"title":199,"path":200,"stem":201},"0022. The logo is text","\u002Fdecisions\u002F0022-the-logo-is-text","4.decisions\u002F0022-the-logo-is-text",{"title":203,"icon":204,"path":205,"stem":206,"children":207,"page":25},"Project","i-lucide-compass","\u002Fproject","5.project",[208,213,218],{"title":209,"path":210,"stem":211,"icon":212},"Roadmap","\u002Fproject\u002Froadmap","5.project\u002F1.roadmap","i-lucide-map",{"title":214,"path":215,"stem":216,"icon":217},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing","i-lucide-git-pull-request",{"title":219,"path":220,"stem":221,"icon":222},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security","i-lucide-shield",{"id":224,"title":187,"body":225,"description":696,"extension":697,"links":698,"meta":699,"navigation":700,"path":188,"seo":701,"stem":189,"__hash__":702},"docs\u002F4.decisions\u002F0019-upstream-kyo-issues-as-drafts.md",{"type":226,"value":227,"toc":685},"minimark",[228,233,237,241,244,248,261,265,293,604,608,635,639,667,671],[229,230,232],"h2",{"id":231},"status","Status",[234,235,236],"p",{},"Accepted",[229,238,240],{"id":239},"date","Date",[234,242,243],{},"2026-10-03 (the first draft, A2), 2026-10-11 (gate 0: \"we need issues at kyo and kyoui\"), 2026-10-17 (D13).",[229,245,247],{"id":246},"context","Context",[249,250,251,255,258],"ul",{},[252,253,254],"li",{},"tui4s found bugs and missing APIs in Kyo RC7, kyo-ui RC7 and jatatui 0.31.0 while it built the runner, the widgets and the web app.",[252,256,257],{},"A post on another project's tracker speaks for the user. The cloud session could also not search getkyo\u002Fkyo for duplicates (its GitHub access was bound to yuri4n\u002Ftui4s).",[252,259,260],{},"kyo-ui is a module of getkyo\u002Fkyo, so its issues go to getkyo\u002Fkyo.",[229,262,264],{"id":263},"decision","Decision",[249,266,267,270,273,290],{},[252,268,269],{},"The session writes drafts only (D13; plan A2). The user searches for duplicates and posts each one. Nothing is posted without the user.",[252,271,272],{},"The drafts cite only upstream code and tui4s numbers.",[252,274,275,276,283,284,289],{},"Each workaround in tui4s has a TODO with a GitHub issue of tui4s where it must go away (",[277,278,282],"a",{"href":279,"rel":280},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F8",[281],"nofollow","#8",", ",[277,285,288],{"href":286,"rel":287},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F9",[281],"#9",").",[252,291,292],{},"The drafts and the workarounds, as of 2026-10-20:",[294,295,296,309],"table",{},[297,298,299],"thead",{},[300,301,302,306],"tr",{},[303,304,305],"th",{},"Draft (target)",[303,307,308],{},"Workaround in tui4s",[310,311,312,341,365,385,401,429,452,465,482,498,519,536,556,570,596],"tbody",{},[300,313,314,322],{},[315,316,317,321],"td",{},[318,319,320],"code",{},"Signal.observe"," keeps about 1.7 KB per change (getkyo\u002Fkyo)",[315,323,324,325,328,329,332,333,336,337,340],{},"Own ",[318,326,327],{},"currentWith","\u002F",[318,330,331],{},"nextWith"," watcher loop and a 1 s repair tick (",[277,334,282],{"href":279,"rel":335},[281],"; ",[277,338,339],{"href":132},"ADR 0005",")",[300,342,343,357],{},[315,344,345,346,349,350,352,353,356],{},"A write between ",[318,347,348],{},"current"," and ",[318,351,331],{}," waits for the repair; ",[318,354,355],{},"combineLatest"," widens it (getkyo\u002Fkyo)",[315,358,359,360,336,363,340],{},"Settle re-check, pull check, SOFT contract, CI load flag (",[277,361,288],{"href":286,"rel":362},[281],[277,364,339],{"href":132},[300,366,367,374],{},[315,368,369,370,373],{},"kyo-ui: a synchronous change notice on ",[318,371,372],{},"Signal",", and handler types that reject lifted values (2026-10-03; not updated since W0)",[315,375,376,377,380,381,384],{},"The settle probe; ",[318,378,379],{},"LiftTrapTest","; the CONTRIBUTING.md rule \"type a handler as ",[318,382,383],{},"Any \u003C Async","\"",[300,386,387,395],{},[315,388,389,390,340],{},"kyo-kernel RC7 has JMH in compile scope (getkyo\u002Fkyo; ",[277,391,394],{"href":392,"rel":393},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F40",[281],"#40",[315,396,397,400],{},[318,398,399],{},"excludeAll(ExclusionRule(\"org.openjdk.jmh\"))"," in every module",[300,402,403,419],{},[315,404,405,406,409,410,413,414,340],{},"A runner outside ",[318,407,408],{},"kyo"," cannot honour ",[318,411,412],{},"UI.scrollIntoView"," (getkyo\u002Fkyo; ",[277,415,418],{"href":416,"rel":417},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F41",[281],"#41",[315,420,421,422,425,426],{},"Own follow-focus rule (CSSOM ",[318,423,424],{},"nearest",") and ",[318,427,428],{},"aria-activedescendant",[300,430,431,446],{},[315,432,433,436,437,440,441,340],{},[318,434,435],{},"NativeLoader"," leaves one ",[318,438,439],{},"\u002Ftmp\u002Fjni-*"," folder per start (jatatui; ",[277,442,445],{"href":443,"rel":444},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F42",[281],"#42",[315,447,448,451],{},[318,449,450],{},"internal.NativeCopy"," deletes the copy after the load, Linux only",[300,453,454,462],{},[315,455,456,457,340],{},"L4: a DOM keydown on a field inside a nested reactive region skips the field's handlers (kyo-ui JS; ",[277,458,461],{"href":459,"rel":460},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F26",[281],"#26",[315,463,464],{},"Not recorded",[300,466,467,479],{},[315,468,469,470,473,474,340],{},"L4: no ",[318,471,472],{},"preventDefault"," on a handled keydown (kyo-ui JS; ",[277,475,478],{"href":476,"rel":477},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F27",[281],"#27",[315,480,481],{},"Alt chords on the web; the browser keeps most Ctrl chords and F1",[300,483,484,492],{},[315,485,486,487,340],{},"L4: any Enter (also Shift-Enter) submits the enclosing form (kyo-ui JS; ",[277,488,491],{"href":489,"rel":490},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F28",[281],"#28",[315,493,494,495],{},"The web composer is outside a form; Enter runs ",[318,496,497],{},"send",[300,499,500,512],{},[315,501,502,503,506,507,340],{},"L4: a ",[318,504,505],{},"Stylesheet"," cannot override inline element styles (kyo-ui; ",[277,508,511],{"href":509,"rel":510},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F29",[281],"#29",[315,513,514,515,518],{},"Not recorded (seen on the ",[318,516,517],{},"Panel"," corners)",[300,520,521,533],{},[315,522,523,524,527,528,340],{},"D13: an input bound with ",[318,525,526],{},".value(ref)"," loses keys 10 ms or less apart (kyo-ui JS; ",[277,529,532],{"href":530,"rel":531},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F37",[281],"#37",[315,534,535],{},"Fewer bound round trips (read the text on submit)",[300,537,538,553],{},[315,539,540,541,543,544,547,548,340],{},"L4 review: a bound ",[318,542,526],{}," writes the value into the DOM ",[318,545,546],{},"value"," attribute, in clear text (kyo-ui JS; ",[277,549,552],{"href":550,"rel":551},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F38",[281],"#38",[315,554,555],{},"The key field of the web is not bound",[300,557,558,564],{},[315,559,560,561],{},"D13, not drafted: an Origin or auth hook for ",[318,562,563],{},"runHandlers",[315,565,566,567,340],{},"None needed: the web target has no server (",[277,568,569],{"href":156},"ADR 0011",[300,571,572,584],{},[315,573,574,575,578,579,340],{},"D13: a cell or ",[318,576,577],{},"ch"," length unit (",[277,580,583],{"href":581,"rel":582},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Ftui4s\u002Fissues\u002F39",[281],"#39",[315,585,586,349,589,336,592,595],{},[318,587,588],{},"Surface.rows",[318,590,591],{},"Surface.cols",[318,593,594],{},"em"," in shared views",[300,597,598,601],{},[315,599,600],{},"Not drafted: the JNI cuts a typed non-BMP character to 16 bits (jatatui)",[315,602,603],{},"A bracketed paste keeps it",[229,605,607],{"id":606},"alternatives-considered","Alternatives considered",[249,609,610,617,623],{},[252,611,612,616],{},[613,614,615],"strong",{},"The session posts the issues."," Rejected: only the user posts (gate 0; the standing rule).",[252,618,619,622],{},[613,620,621],{},"No upstream issues; workarounds only."," Rejected by the user at gate 0: \"we need issues at kyo and kyoui if they are not there yet\".",[252,624,625,631,632,630],{},[613,626,627,628,630],{},"Patch Kyo in a fork or in package ",[318,629,408],{},"."," Rejected by ",[277,633,634],{"href":128},"ADR 0004",[229,636,638],{"id":637},"consequences","Consequences",[249,640,641,644,647],{},[252,642,643],{},"Good: each workaround has a named exit, and the drafts are ready to post.",[252,645,646],{},"Bad: until the user posts them, upstream does not know; the workarounds stay (two TODOs in the runner).",[252,648,649,650,653,654,657,658,349,661,657,664,289],{},"Bad: the notes leave the repository, so the draft texts move into GitHub issues (the issues with the label ",[318,651,652],{},"upstream-kyo",": ",[277,655,461],{"href":459,"rel":656},[281]," to ",[277,659,511],{"href":509,"rel":660},[281],[277,662,532],{"href":530,"rel":663},[281],[277,665,445],{"href":443,"rel":666},[281],[229,668,670],{"id":669},"references","References",[249,672,673,682],{},[252,674,675,676,283,679,630],{},"Decision log: eighth round (upstream issues). Plan: A2. Roadmap: D13. Issues ",[277,677,282],{"href":279,"rel":678},[281],[277,680,288],{"href":286,"rel":681},[281],[252,683,684],{},"Handoff: L1a (scroll-into-view), P1 (JMH, JNI copy), L4 (four web findings), T1 (non-BMP).",{"title":686,"searchDepth":687,"depth":687,"links":688},"",2,[689,690,691,692,693,694,695],{"id":231,"depth":687,"text":232},{"id":239,"depth":687,"text":240},{"id":246,"depth":687,"text":247},{"id":263,"depth":687,"text":264},{"id":606,"depth":687,"text":607},{"id":637,"depth":687,"text":638},{"id":669,"depth":687,"text":670},"The session writes upstream bug reports and feature requests as drafts; only the user posts them; tui4s works around each bug in its own code until upstream fixes it.","md",null,{},true,{"title":187,"description":696},"h-5ai-28EcYG5kv3cxupkG8CZoAZPX65-vVDUVVUwiA",[704,706],{"title":183,"path":184,"stem":185,"description":705,"children":-1},"The optional keyed shared-state library pini4s lives in vendor\u002Fpini4s as a Git submodule and an sbt ProjectRef; only the examples use it.",{"title":191,"path":192,"stem":193,"description":707,"children":-1},"A release starts from the form of the workflow Release on main; every check runs before a tag exists; one approval of the environment publishes all the modules of the run in the order of the dependencies; CHANGELOG.md is the one source of the release notes.",1792528757528]