Skip to content

Fix: Collect per-pass effects in scratch collectors#60

Merged
phranck merged 5 commits into
mainfrom
issue/56-pass-collectors
Jul 21, 2026
Merged

Fix: Collect per-pass effects in scratch collectors#60
phranck merged 5 commits into
mainfrom
issue/56-pass-collectors

Conversation

@phranck

@phranck phranck commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Closes #56 (sub-issue of #13, follows #59). Design spec: .claude/openspec/render-phase-effect-commit.md.

Summary

  • Render every traversal of a frame into fresh RenderPassCollectors (key handlers, preferences, status-bar registrations, header buffer) injected via a per-pass environment — effect sites stay unchanged
  • Adopt only the FINAL pass's collectors into the live managers at a single commit point before writeFrame; discarded passes (first-frame measurement, superseded main pass) leave no trace
  • Stage focus registrations inside FocusManager (beginPass/commitPass/discardPass): auto-focus, section activation, and onFocusChange fire at commit, never during traversal; queries keep reading live state
  • Record declarative status-bar registrations per pass and replay the final pass via adoptPassRegistrations(from:)
  • Fix two pre-existing focus validation holes surfaced by the new tests (no auto-activation on the commit path; stale focus surviving when all sections disappear)

Test plan

  • ./scripts/test-linux.sh green on macOS (native, Swift 6.0.3) and Linux (Docker) — 1310 tests
  • New: RenderPassCollectorTests — ghost header/status-bar/focus/preference guarantees are hard expectations; focus-change ordering (after traversal) is a hard expectation
  • RenderPhaseCharacterizationTests: 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)
  • No public API change (manifest untouched)

phranck added 5 commits July 21, 2026 21:27
- 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
@phranck
phranck merged commit 079f7d9 into main Jul 21, 2026
6 checks passed
@phranck
phranck deleted the issue/56-pass-collectors branch July 21, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P0-08b] Collect per-pass effects in scratch collectors

1 participant