refactor(app): isolate composition and presentation / 完成 App 装配与展示层拆分 - #9897
Merged
Conversation
…sources Problem: asynchronous App actions and cleanup can outlive the session or controller that initiated them, especially across background cancellation and A-to-B-to-A navigation. Root cause: mutable active-view state and independent effect cleanup were used as authority for pending operations and shared subscriptions. Fix: wire committed source-bound command owners, canonical controller cancellation, generation fences, navigation receipts, and subscription leases into App composition. Keep the runtime root and page tree together for this slice. Add a separate three-runner memory screening workflow that verifies one clean build, complete protocols, and unique same-attempt shard evidence. Document the remaining offline heap-retainer and control attribution duty. Verification: 302 frontend discovery suites; App lifecycle and real browser replay; production/test typechecks; production build and measured bundle budgets; repository lint; 21 memory protocol/path negative tests; actionlint; focused independent security review of workflow permissions and aggregation.
Carry the final settings fixture migration and merged pure-kernel base into the ownership slice. The production tree is unchanged, preserving the independently reviewed ownership boundary.
Include the linked bilingual acceptance contract from the renderer parent. The frontend source and build inputs are unchanged.
Problem: the migrated command owners still share a large App entry with the entire page tree, obscuring the source-authority and presentation boundary. Root cause: runtime composition and JSX assembly remained in one module; context and subagent presentation code also remained in eager consumers. Fix: retain the original hook and command order in AppRuntime, render the same stable regions through AppRuntimeView, and make App.tsx a small facade. Extract pure context helpers and lazy subagent presentation with preserved live outcome tuples and historical output parsing. Enforce the entry and transitive AST layer contracts, remove the obsolete App size allowance, reduce remaining ContextPanel debt, and ratchet measured raw assets to 2381.3 KiB for the 2381.2 KiB result. Keep independent memory screening. Verification: all 302 discovered suites plus the remaining test:all groups; App lifecycle and actual browser replay; typechecks; production build and bundle budgets; AST negative fixtures and repository lint; independent read-only review of hook order, command provenance and outcome compatibility.
Include the updated settings and renderer parents and their bilingual acceptance documentation. Preserve the final shell extraction and memory protocol unchanged.
Record the renderer parent integration of the final legacy fixture ownership test. This merge leaves the ownership implementation and memory build inputs unchanged.
Keep the final shell and presentation source unchanged while recording the current settings, renderer and ownership parent commits for independent CI qualification.
Carry the reviewed renderer batch-to-geometry fix into the session ownership slice. Preserve the session command and lifecycle boundary while qualifying the updated renderer with this slice.
Carry the approved measurement transaction through the final App composition. Keep shell extraction behavior unchanged and run the complete native and App memory qualification on the resulting head.
Problem: Layout scroll observations and stale pointer releases could detach tail following without current user input. Root cause: scroll geometry and input-release callbacks lacked distinct intent ownership. Fix: Integrate the kernel input lease and release identity correction from the renderer slice. Verification: Renderer transcript, Chromium/WebKit suites and type checks passed; this slice production build passes at 2408.2 KiB raw with an attributable 0.2 KiB increase.
Problem: Tail following and newer gestures could be displaced by layout observations or stale releases. Root cause: Intent ownership was not distinct from geometry and queued callbacks. Fix: Integrate the reviewed renderer correction through the ownership slice. Verification: Production build and bundle gates pass at 2381.4 KiB raw; the measured 0.2 KiB increase preserves the deferred shell boundary.
Fix: Incorporate the renderer branch ancestry update after both prerequisite slices merged. Verification: The merge changes no production files and retains the validated ownership and input-intent tree.
Fix: Carry the merged prerequisite ancestry through the ownership stack so pull-request validation can run on the current base. Verification: The merge preserves the previously validated app-shell tree without production file changes.
This was referenced Sep 7, 2026
Carry the shared measurement publication and native input contracts into the session ownership slice, including its independent cancellation prerequisite.
Keep the App shell slice on the same measured geometry publication and input ownership implementation as the preceding session ownership slice.
Problem: rejected remote session opens could publish an error while observers still saw the rejected session identity. Root cause: failure state publication and restoration of the previous selection had separate owners, allowing reconnect or later selection work to interleave. Fix: commit restoration and failure state through one revision-checked completion owner. Order route metadata, terminal state, close and generation replacement with the existing publication fence; cover HTTP, busy, listing, missing-target and reconciled transport failures. Verification: deterministic regression failed before the repair. Remote tests, five race repetitions of rejection and lifecycle cases, full desktop tests, full desktop race tests, golangci-lint and repository lint pass. No public API, persisted format or provider prompt bytes change.
Keep the presentation slice on the reviewed session-ownership implementation. The remote failure owner restores identity before publishing errors and fences competing lifecycle transitions. Full desktop tests and race tests pass on the shared implementation.
Problem: concurrent clients could fail to open a remote workspace when the serve owner released its lock between a failed mkdir and Stat. Root cause: lock acquisition treated a missing observation as a permanent creation failure. A frontend wiring check also still referenced the replaced post-publication rollback helper. Fix: recontend through exclusive mkdir once per missing observation for structured contention-capable errors. Bound consecutive ambiguous failures and preserve cancellation, permission and transport errors. Test real SFTP release ordering and update the async handoff contract; leave stale-lock reclamation unchanged. Verification: deterministic regression fails before the repair. Bootstrap race tests, bounded-error cases, root lint and repolint pass. The root suite passed except an unchanged control timeout; its full package passed on one isolated rerun. All 302 frontend suites and remaining test:all groups pass. No API, persisted-format or provider-byte change.
Inherit the bounded bootstrap lock-release handoff repair and current async wiring check from the ownership slice. Its deterministic SFTP regression, race tests, lint and full frontend test:all pass; presentation assets remain unchanged.
Problem: native GTK scrolling could reverse visible rows after input paused, even when the scroll writer accepted no reader writes. Root cause: newly mounted rows inherited estimates until the reader lease expired. Releasing their accumulated size debt then moved later visible rows. Short Markdown parsing added another asynchronous first-paint handoff. Fix: measure new DOM before paint, preserve existing visible coordinates with a generation-bound window origin, and acknowledge only the complete prefix. Preload the history renderer and synchronously format bounded windowed answers; large worker results still format automatically after active input ends. Keep the native single-writer and existing safety thresholds. Normalize the small attributable raw bundle delta from 2408.2 to 2408.5 KiB with a 2408.7 KiB ceiling. Model native extent clamping in the deterministic DOM harness. Verification: fixed-height regressions cover both estimate directions, reverse travel, input release and the leading edge. Markdown tests, viewport tests, production build, repository lint and isolated GTK diagnostic replay pass. Final-head browser and CI qualification are tracked in the PR.
Problem: the App presentation slice inherited estimated first-paint geometry that could move visible rows when native input ended. Root cause: the shared renderer deferred measurements for newly mounted DOM. Fix: integrate the ownership slice repair without changing App composition, source-bound commands or hook order. Resolve only the independent raw asset budget: the shell measures 2381.6 KiB, with a 2381.8 KiB ceiling. Verification: the integrated shell passes the production build, TypeScript, hook and AST layer gates, CSS contracts and all bundle budgets. Shared repair passes 303 frontend suites, performance, Chromium/WebKit reader replay and App browser lifecycle checks. Latest-head native and memory gates remain required before merge.
Problem: the safety browser gate could fail with no selection before the fault transition, instead of testing whether a real selection survives. Root cause: its text walker included the Compress toolbar label, which is visible but not a native text-selection target. Fix: select only the existing transcript-selectable surface and exclude interactive controls. Require a real native selection and selection ownership before injecting the geometry fault. Retain every post-transition identity, selection, displacement, zero-write and memory assertion unchanged. Verification: the original replay captured Compress as its drag target and no selected text before the fault. The corrected full browser replay covers 24 safety cycles with real drag selection, pointer holds and tail ownership.
Problem: a toolbar label could satisfy the old visible-text fixture while never establishing the selection the safety transition was meant to retain. Fix: integrate the shared browser fixture correction and its pre-fault selection assertion. Production files and bundle contents are unchanged. Verification: all 24 browser safety cycles pass, including real native drag selection, reader holds, tail ownership and zero page errors. The inherited production build and Chromium/WebKit reader replay remain unchanged.
Problem: enlarging an offscreen predecessor could move the held reader by its full growth (371px in the Windows browser replay). Root cause: measurement selected the first visible block from already changed DOM bounds. The enlarged predecessor became visible and replaced the real input-captured anchor before the new prefix was committed. Fix: ordinary size publication retains the Kernel anchor. Only window-origin removal supplies a coordinate-conversion anchor, selected from the previously committed prefix and its old sizes. An untrusted new DOM rectangle cannot claim reading ownership. Preserve existing transaction priorities and fallback to the Kernel anchor when no cold prefix candidate is available. Verification: deterministic predecessor-growth regressions fail before the repair and pass after it for both estimate directions. The model also covers mid-history origin release, leading-edge continuity and input write exclusion. Production build and repository lint pass; affected transcript and browser gates are rerun before publication. Architecture contracts document the owner.
Problem: a growing offscreen predecessor could replace the input-captured reading anchor during shared renderer measurement. Fix: integrate the verified Kernel-anchor publication repair and committed prefix origin conversion. App runtime composition and action owners are unchanged, as are the independent shell asset budgets. Verification: the shared repair passes deterministic red/green regressions, complete transcript tests, TypeScript, production build, repository lint, Chromium/WebKit reader replay and all 24 safety browser cycles. The integrated shell build and latest-head official gates are checked before merge.
Problem: main-v2 advanced while the split renderer was being qualified, leaving an asset-budget conflict and stale integration coverage. Fix: merge main-v2 4947013, preserving session-level Stop, its original-tab reconciliation, the stale sessioncatalog repair and the source-bound App owners. Retain the mainline locale ceiling. The integrated raw payload is 2408.7 KiB; set the smallest rounded 2408.9 KiB ceiling with 0.2 KiB headroom. Verification: production build and bundle gates pass. Frontend Stop reconciliation passes 31 checks; focused desktop Stop race tests pass. Independent read-only review confirms same-tab cancellation, controller identity and remote rejection publication ownership remain compatible. Complete App lifecycle and control/sessioncatalog race gates are tracked before latest-head CI qualification and merge.
Problem: mainline Stop and catalog fixes advanced while the split was being qualified, and the raw bundle ceilings conflicted across the two layouts. Fix: retain the mainline behavior with the split runtime composition and same-tab cancellation owner. The integrated shell measures 2381.8 KiB raw; its narrow ceiling is 2382.0 KiB, with the inherited locale limit unchanged. Verification: production type, hook, AST, CSS and build checks pass; the raw asset gate passes with measured headroom. The shared merged base passes Stop frontend/desktop race, control and catalog race, App lifecycle and actual App browser checks. Later mainline updates remain to be integrated.
Problem: mainline recovery-wait and rejection-containment fixes advanced while App effects were extracted, conflicting with the old App subscription. Fix: merge main-v2 17a81d7 and preserve the recoverable-error toast through the shared App effect owner. A committed callback prevents layout-teardown delivery while effect cleanup removes the one global subscription. Keep the mainline rejection classification, warning severity and six-second duration. Raw startup assets measure 2411.3 KiB after the inherited UI changes; retain a narrow 2411.5 KiB ceiling rather than the obsolete pre-recovery budget. Verification: lifecycle regression covers StrictMode, 32 callback replacements, latest-sink delivery and layout teardown. Recovery crash classification, lineage-dialog and wait-banner tests pass. Production build/type/hook/CSS and asset checks pass. Independent read-only review found no lost feature or new subscription ownership defect. Owning Go and App browser checks complete the integrated-base qualification before final-head CI and merge.
Problem: mainline recovery notifications lived in the old App effect while the presentation slice had moved runtime ownership to shared composition. Fix: integrate the shared App effect owner, latest committed toast delivery, recovery wait UI and error containment. Preserve the bridge-free App facade, AST layer boundaries and deferred presentation assets. The integrated raw payload is 2384.5 KiB; its narrow ceiling is 2384.7 KiB. Verification: production type/hook/AST/CSS/build and measured asset gates pass. The shared subscription lifecycle test passes on this composition. Owning recovery frontend and Go race checks, independent source review and App browser integration pass in the parent slice. Latest-head official CI, native smoke and complete memory screening remain merge gates.
…ship Problem: Mainline advanced with the separately reviewed tool cancellation and liveness fixes while the split PR was qualifying. Root cause: The pending ownership slice shared controller and tool presentation paths with the new mainline revision. Fix: Integrate main-v2 without changing source-bound command or cleanup ownership. Normalize the measured initial raw bundle ceiling from 2411.5 to 2411.9 KiB for the inherited UI growth (2411.7 KiB actual). Verification: Agent and control package race suites pass, all 26 tool elapsed/liveness frontend tests pass, production type/build gates and bundle check pass, repository lint is clean, and the production App browser lifecycle gate passes. Independent integration review found no new blocking issue. Final-head remote CI and full memory protocol remain required before merge.
Problem: The final presentation slice must include the qualified current-mainline ownership integration. Root cause: Mainline added tool elapsed UI, bounded cancellation and controller liveness while the split was qualifying. Fix: Carry the source-owner integration into the extracted shell and preserve its separately measured bundle ceiling (2384.9 KiB actual, 2385.1 KiB limit). Verification: Production type/layer/hook/build checks and the exact build budget pass; the shared agent/control race suites, 26 elapsed/liveness frontend tests, repository lint and App browser lifecycle passed in the owning slice. This intermediate local merge is followed by the newly arrived provider settings integration before final qualification.
Problem: Mainline provider settings integration changed App startup navigation and transcript lifecycle while the ownership slice was qualifying. Root cause: The new mainline implementation retained the pre-extraction App and renderer boundaries, overlapping the split owners. Fix: Keep the source-bound App composition and first-materialization/origin geometry model. Integrate generation-renewed native viewport subscriptions and batched prepend settlement. Route first-run setup through the existing startup lifecycle with cancellation and navigation-generation guards; remove the obsolete onboarding overlay and retain the provider setup banner until configuration succeeds. Carry mainline provider behavior and normalize only measured integrated bundle/locale ceilings. Verification: Full transcript suite, native viewport generation tests, origin/prepend combination tests, startup navigation and unmount tests, 54 provider picker checks, onboarding commands, startup contract, production types/build checks, exact bundle checks and App browser lifecycle pass. Repository lint is clean. Full frontend discovery and final-head remote CI/memory protocol remain required before merge.
Problem: Mainline provider settings and viewport fixes must coexist with the final extracted App shell before delivery. Root cause: The mainline startup and rendering changes overlapped the split lifecycle and presentation boundaries. Fix: Carry the ownership slice integration without restoring App-local async effects or the obsolete onboarding overlay. Preserve lazy shell boundaries and use the measured 2398.2 KiB raw bundle with a 2398.4 KiB ceiling. Verification: Production build, TypeScript, AST layer contracts, hooks, CSS and bundle gates pass. The final shell App browser lifecycle passes navigation, three layouts, source-bound send and Stop. Shared transcript, native subscription, origin/prepend, provider picker and startup lifecycle tests pass in the ownership slice. Final-head CI and complete memory screening remain required before merge.
SivanCola
marked this pull request as ready for review
September 7, 2026 17:16
SivanCola
added a commit
that referenced
this pull request
Sep 8, 2026
Problem: The generated draft referenced 30 of the 38 pull requests merged since v1.38.1, and no entry mentioned the transcript renderer replacement, the Standard/Deep session display setting, or the provider connection and model preference redesign, even though each pull request describes user-visible behavior. Fix: Add three bilingual entries with their pull-request references to both the highlights and the categorized changes lists - transcript renderer replacement (#9893, #9895, #9896, #9897), Standard and Deep session display (#9894), and independent model connections and model preferences (#9907). Verification: node scripts/release-notes.mjs validate (61 releases); node --test scripts/release-notes.test.mjs (10 pass); the rendered v1.38.2 notes inspected in both languages; git diff is additions only.
SivanCola
added a commit
that referenced
this pull request
Sep 8, 2026
Problem: The generated draft referenced 30 of the 38 pull requests merged since v1.38.1, and no entry mentioned the transcript renderer replacement, the Standard/Deep session display setting, or the provider connection and model preference redesign, even though each pull request describes user-visible behavior. Fix: Add three bilingual entries with their pull-request references to both the highlights and the categorized changes lists - transcript renderer replacement (#9893, #9895, #9896, #9897), Standard and Deep session display (#9894), and independent model connections and model preferences (#9907). Verification: node scripts/release-notes.mjs validate (61 releases); node --test scripts/release-notes.test.mjs (10 pass); the rendered v1.38.2 notes inspected in both languages; git diff is additions only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Behavior and scope
Slice 5 of #9777 completes App composition and presentation after source-bound ownership #9896. It depends on #9896; renderer #9895, independent prerequisite #9903, settings #9894 and pure kernel #9893 are already merged.
App.tsx becomes a small bridge-free facade. AppRuntime preserves hook order and command owners; AppRuntimeView renders shared regions without another active-session authority. Pure context helpers and lazy subagent outcome/preview cards leave eager consumers. Live wire outcomes preserve ref/status/error/retryable together, while historical output parsing belongs to the rendered card. An AST gate checks runtime imports, re-exports, aliases and dynamic imports with negative fixtures.
This adopts @SivanCola's repaired #9777 presentation structure and includes the shared renderer repairs qualified through the preceding slices.
The inherited session-ownership slice also fixes a confirmed remote resume rejection race: restoring the previous identity and publishing the error now share one revision-checked completion and lifecycle publication fence. The deterministic regression, sibling rejection paths, repeated race cases, full desktop tests and full desktop race tests pass. The same owner slice handles the remote bootstrap lock release/acquire observation race with bounded structured-error recompetition. The obsolete frontend source-contract check now follows the current async handoff; Go regressions verify the actual error-time identity. These backend/test repairs do not change this slice’s production frontend assets.
The shared renderer now distinguishes first materialization from changes to already painted content. New DOM receives real measurements before first paint; a generation-bound window origin preserves existing visible coordinates while the prefix is refined. Geometry acknowledgements follow the complete measurement commit. Ordinary content growth preserves the input-captured Kernel anchor; only origin removal converts an anchor from the previously committed prefix. Changed DOM bounds cannot let a growing offscreen predecessor replace the reader anchor. Bounded windowed Markdown answers render formatted content immediately, while larger worker results automatically commit after active input ends. The single native scroll writer, mount cap and displacement thresholds are unchanged.
This fixes a GTK regression where publishing initial size debt at input release moved later visible rows. Fixed-height regressions cover both larger and smaller actual sizes, reverse travel, mid-history and leading-edge release, and offscreen predecessor growth into the viewport. The predecessor-growth test fails before the anchor-ownership fix and passes after it. A diagnostic GTK run passed 1,951 rows / 967 frames with zero reverse displacement, blank frames, reader writes and final tail distance. Each PR must still pass official CI on its final head.
Current mainline integration
The final source includes mainline tool cancellation/liveness (#9901) and provider settings (#9907). The extracted startup lifecycle now routes directly to provider setup, preserving cancellation and navigation-generation fences; a late probe cannot override a newer page or publish after unmount. The obsolete key overlay is removed. Generation-renewed viewport subscriptions and batched prepend settlement are integrated with the first-materialization/origin model. Deterministic tests cover retired ResizeObserver delivery, origin removal while prepend owns the transaction, and startup navigation/teardown. Provider behavior remains the current mainline implementation.
Validation and delivery
The final source
da6e8f0237590ba44608dcc8dd467d712ac38b3apasses all 320 discovered frontend suites, dedicated test groups and long-history performance contracts. Production TypeScript, hook/AST/style checks, repository lint, full build and measured resource budgets pass. Chromium/WebKit App replay covers navigation, three layouts, source-bound send and Stop without page errors. Independent source review found no new blocking security or concurrency issue.Final-head CI completed successfully with all 17 jobs. Desktop ordinary and race tests, Windows replay/WebView2 selection and scrolling, and Wails native startup pass. The 1,951-row native fixture passes GTK (984 frames) and WKWebView (4,521 frames), with zero reverse displacement, zero final tail distance and 64 additional rows followed at the tail.
The remote rejection regression fails deterministically before the owner repair; focused lifecycle races, full desktop tests and race sweep pass. The real-SFTP bootstrap release-handoff regression and repeated race cases pass. Current mainline Stop, sessioncatalog, recovery, tool cancellation/liveness and provider behavior are preserved. Origin/prepend settlement and viewport generation replacement have deterministic combination coverage; startup setup probes cannot override newer navigation or publish after disposal.
Final-head memory screening passed its complete three-process aggregate on this exact source: three distinct processes, 896 round trips each (2,688 total), one build/configuration/browser/attempt identity. Each distinct process must complete 128 full + 128 windowed + 128 safety + 512 mixed round trips. Aggregation rejects incomplete or duplicate shards, different source/build/configuration/browser/attempt identities, page errors and persistent screening drift. Automated screening does not establish offline heap-retainer or mainline-control attribution; those remain explicitly outside the automated verdict. The complete same-attempt aggregate is verified. Refs #9777.
Documentation-impact: updated - English and Chinese architecture, acceptance and ownership contracts describe the final boundaries and evidence limits.
Cache-impact: low - inherited development AGENTS.md architecture instructions change; application provider-visible prompt, request and history bytes remain unchanged.
Cache-guard: geometry, input, source-bound command and lifecycle regressions preserve ownership; the independent backend prerequisite tests unchanged canonical history and provider projections for rejected cancelled requests.
System-prompt-review: Codex reviewed the development-instruction update; application system-prompt construction and serialization are unchanged.