Checkout with DASHBOARD_GITHUB_TOKEN PAT so git push succeeds.
Also add explicit contents: write permission at workflow level.
Fixes 403 'Permission denied to github-actions[bot]' error.
Mark all plan checkboxes as completed. Update to-dos.md with phase 2
completion entry, new performance backlog items (TupleView Equatable,
_printChanges equivalent), and GH Actions workflow issue. Update
whats-next.md with current branch/PR/test state.
Document the EquatableView/RenderCache system in the DocC article:
- How .equatable() works (5-step cache lookup)
- Cache invalidation triggers (State change, environment change)
- When to use / not use .equatable() (decision guide with tables)
- Which types support Equatable conformance
- Debug logging via TUIKIT_DEBUG_RENDER=1
- Code example using FeatureBox from the example app
Also updates existing sections:
- Correct 'no subtree memoization' claim in 'What Is NOT Diffed'
- Add EquatableView to Renderable lists (Direct Rendering, View-Level Modifiers)
Extract static, state-free subtrees into standalone View structs to
prepare for .equatable() memoization in Phase 5:
- FeatureBox: extracted from MainMenuPage's private featureBox() method
- ContainerTypesRow: Card/Box/Panel examples from ContainersPage
- SettingsAndAlignmentRow: settings panel + alignment demos
ButtonsPage left as-is — nearly all sections depend on @State clickCount
through Button actions, making decomposition ineffective for memoization.
Add RenderCache.Stats for cache performance tracking:
- Hit/miss/store/clear counters with hit rate calculation
- Per-frame delta via Stats.delta(since:) for meaningful frame-level logging
- TUIKIT_DEBUG_RENDER=1 env var enables stderr logging (zero cost when off)
- logDebug uses @autoclosure to avoid string allocation in production
Review fixes applied:
- F1: logFrameStats() now logs per-frame delta, not cumulative totals
- F2: clearAll() no longer reads entries.count unconditionally
- F3: Remove unnecessary Sendable from Stats (main-thread only type)
- F5: reset() now also clears stats and frame snapshot
- F7: Move EnvironmentSnapshot to RenderLoop.swift (private, where it belongs)
- F8: Build snapshot from EnvironmentValues, not from ThemeManager directly
Add fetchGitHubSocialAccounts() using /users/{login}/social_accounts API
as primary source. Validate Mastodon domains via NodeInfo instead of
blocklists. Add 5s timeouts to all fetch calls. Expand known instances
list. Skip cross-verification for authoritative sources (github, keybase).
Full refresh now clears cache to prevent stale false positives.
- Add IconBadge component with sm/md/lg variants
- Refactor FeatureCard to use IconBadge
- Update ArchHighlight and RepoInfo for consistency
- Add DASHBOARD_GITHUB_TOKEN to CI for rate limit
Equatable views can opt into render caching with .equatable(). On cache hit,
the entire subtree is skipped and the cached FrameBuffer returned directly.
Cache is cleared on every @State change; GC removes stale entries per frame.