Fix: Collect per-pass effects in scratch collectors#60
Merged
Conversation
- Pin ghost effects from discarded passes: measure-only header reaches live state, superseded-pass status-bar items and focusables persist, preference callbacks accumulate across passes - Pin focus-change ordering: auto-focus fires during traversal instead of after it - Extract the shared FrameHarness into test support - Add PreferenceStorage.callbackCount for tests and diagnostics - Mark desired behavior withKnownIssue until the collectors land (#56)
- Introduce RenderPassCollectors bundling fresh scratch instances per traversal - Add adopt(from:) to KeyEventDispatcher, PreferenceStorage, and AppHeaderState - Record declarative status-bar registrations per pass and replay only the final pass via adoptPassRegistrations(from:) - Document the collector half of the effect classification rule on every adopt API
- Route register/registerSection/activateSection into a staging area between beginPass and commitPass/discardPass - Defer auto-focus, section activation, and onFocusChange to commitPass so discarded passes leave no trace - Keep live semantics for imperative use outside a collecting pass (ViewRenderer, tests) - Extract the shared post-commit validation from endRenderPass
- Render every pass into fresh RenderPassCollectors via a per-pass environment; live managers adopt the final pass atomically before writeFrame - Discard the measurement pass and superseded main pass together with their collectors and staged focus registrations - Read header heights from the pass collectors instead of live state - Repair two uncovered focus validation holes: activate the first committed section when none is active, and clear focus when no sections survive - Promote the collector and correction-pass tests to hard expectations; align the runtime-isolation test with declarative focus semantics
- Move PreferenceStorage.adopt(from:) and callbackCount into a package extension so the collector plumbing does not widen the public surface
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.
Closes #56 (sub-issue of #13, follows #59). Design spec:
.claude/openspec/render-phase-effect-commit.md.Summary
RenderPassCollectors(key handlers, preferences, status-bar registrations, header buffer) injected via a per-pass environment — effect sites stay unchangedwriteFrame; discarded passes (first-frame measurement, superseded main pass) leave no traceFocusManager(beginPass/commitPass/discardPass): auto-focus, section activation, andonFocusChangefire at commit, never during traversal; queries keep reading live stateadoptPassRegistrations(from:)Test plan
./scripts/test-linux.shgreen on macOS (native, Swift 6.0.3) and Linux (Docker) — 1310 testsRenderPassCollectorTests— ghost header/status-bar/focus/preference guarantees are hard expectations; focus-change ordering (after traversal) is a hard expectationRenderPhaseCharacterizationTests: correction-pass handler duplication promoted to a hard expectation; onChange double-fire stays known-issue ([P0-08c] Commit lifetime effects from the final tree #57)