| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
refactor(flowchat): give the viewport one register, and a permanent trail Six viewport faults were fixed this week and four were the same shape: a writer moved the viewport on purpose, and another component read that movement as a displacement to undo. What coordinated them was a hand-written predicate per writer — O(n^2) pairs, where forgetting one pair is a bug. The snap back that travelled 0.7px and was reissued 958 times over 20 seconds was one forgotten pair. The pairs collapse into a register. flowChatViewportOwnership.ts is a pure state machine over an ordered list of owners; useFlowChatViewportOwner.ts holds the claim and performs the write, because taking ownership and moving the viewport being one call is what stops a writer being added without the rest of FlowChat knowing. The order is the design: user-gesture > one-shot-navigation > snap-back > follow-output > layout-correction > anchor-correction The register decides whether, never where. Targets stay with the writer that owns them and the anchor's correction stays idempotent — ordering answers what idempotency cannot, which is whether a movement was ours on purpose. The contract carried a standing objection to any coordinator: single-writer semantics are unreachable while the virtualizer writes scrollTop from inside the library. Both halves of that premise have since expired. Its adjustment for a re-measured item is off, and scrollToFn is a first-class option, so every library write — scrollToIndex, scrollToOffset, and the re-aim that follows them for up to 5s — is now attributed to whoever asked for the aim and refusable like any other. That attribution is also what lets a gesture preempt a navigation still chasing its Turn, with no extra machinery. Two departures from the design as planned, both found while building it. The opening reveal cannot be an owner: it is a phase, the thing moving the viewport during it is follow-output, and a claim standing in for the reveal would outrank and refuse follow-output. And prepend-compensation became layout-correction, since putting the reader back after history arrives above them and after the box resizes is one act. Fewer flags collapsed than expected: only isViewportOwnedElsewhere and isSnapBackInFlight were really answering "is someone else moving the viewport". smoothScrollFramesRef is follow-output yielding to its own animation, and the rest are frame budgets and paging policy. The trail is the other half. Every fault here has been intermittent, invisible in the DOM once over, and identical in the UI to two other causes: a Turn that lands and is dragged away and a Turn that never landed leave the same final position. So flowChatViewportDiagnostics.ts records, behind the existing app.logging.flow_chat_diagnostics switch, the writes at the register — with every refusal — and the decisions at each writer. The second half is the one that pays: a write that never happened leaves nothing at the register to find, and "nothing happened" has been the report more often than a wrong move has. A placement is recorded with what became of it, sampled a frame later and again once settled, which is how the two writers that do not go through the register — the sticky Task indicator and cross-session focus — are watched without being changed on no evidence. Repeated events collapse into one entry per 500ms carrying the count and travel they stand for, keyed so that a transition always emits. analyze-flowchat-log.mjs is rewritten around that stream: episodes of activity ranked by travel per pixel of progress, placements that did not stick ranked by drift, refusals as owner by who outranked them, declines as writer by reason. It weighs a coalesced entry by the run it stands for, and says so at the top when entries were dropped, because both would otherwise flatter the result. The two existing regression nets pass unchanged: useFlowChatFollowOutput needed the real register wired into its harness, and useFlowChatViewportAnchor a writeViewport that assigns scrollTop. Manual verification of contract items 25-30 is pending. | 1 个月前 | |
refactor(flowchat): give the viewport one register, and a permanent trail Six viewport faults were fixed this week and four were the same shape: a writer moved the viewport on purpose, and another component read that movement as a displacement to undo. What coordinated them was a hand-written predicate per writer — O(n^2) pairs, where forgetting one pair is a bug. The snap back that travelled 0.7px and was reissued 958 times over 20 seconds was one forgotten pair. The pairs collapse into a register. flowChatViewportOwnership.ts is a pure state machine over an ordered list of owners; useFlowChatViewportOwner.ts holds the claim and performs the write, because taking ownership and moving the viewport being one call is what stops a writer being added without the rest of FlowChat knowing. The order is the design: user-gesture > one-shot-navigation > snap-back > follow-output > layout-correction > anchor-correction The register decides whether, never where. Targets stay with the writer that owns them and the anchor's correction stays idempotent — ordering answers what idempotency cannot, which is whether a movement was ours on purpose. The contract carried a standing objection to any coordinator: single-writer semantics are unreachable while the virtualizer writes scrollTop from inside the library. Both halves of that premise have since expired. Its adjustment for a re-measured item is off, and scrollToFn is a first-class option, so every library write — scrollToIndex, scrollToOffset, and the re-aim that follows them for up to 5s — is now attributed to whoever asked for the aim and refusable like any other. That attribution is also what lets a gesture preempt a navigation still chasing its Turn, with no extra machinery. Two departures from the design as planned, both found while building it. The opening reveal cannot be an owner: it is a phase, the thing moving the viewport during it is follow-output, and a claim standing in for the reveal would outrank and refuse follow-output. And prepend-compensation became layout-correction, since putting the reader back after history arrives above them and after the box resizes is one act. Fewer flags collapsed than expected: only isViewportOwnedElsewhere and isSnapBackInFlight were really answering "is someone else moving the viewport". smoothScrollFramesRef is follow-output yielding to its own animation, and the rest are frame budgets and paging policy. The trail is the other half. Every fault here has been intermittent, invisible in the DOM once over, and identical in the UI to two other causes: a Turn that lands and is dragged away and a Turn that never landed leave the same final position. So flowChatViewportDiagnostics.ts records, behind the existing app.logging.flow_chat_diagnostics switch, the writes at the register — with every refusal — and the decisions at each writer. The second half is the one that pays: a write that never happened leaves nothing at the register to find, and "nothing happened" has been the report more often than a wrong move has. A placement is recorded with what became of it, sampled a frame later and again once settled, which is how the two writers that do not go through the register — the sticky Task indicator and cross-session focus — are watched without being changed on no evidence. Repeated events collapse into one entry per 500ms carrying the count and travel they stand for, keyed so that a transition always emits. analyze-flowchat-log.mjs is rewritten around that stream: episodes of activity ranked by travel per pixel of progress, placements that did not stick ranked by drift, refusals as owner by who outranked them, declines as writer by reason. It weighs a coalesced entry by the run it stands for, and says so at the top when entries were dropped, because both would otherwise flatter the result. The two existing regression nets pass unchanged: useFlowChatFollowOutput needed the real register wired into its harness, and useFlowChatViewportAnchor a writeViewport that assigns scrollTop. Manual verification of contract items 25-30 is pending. | 1 个月前 | |
fix(workspace): harden worktree lifecycle and cache topology - Cache repository-scoped worktree topology with metadata-based refresh, request coalescing, and explicit invalidation. - Avoid redundant Git queries during workspace activity tracking and reuse resolved worktree metadata across consumers. - Reject worktree creation in unborn repositories, exclude managed worktree directories, and resolve new checkouts directly. - Distinguish worktree creation failures from workspace opening failures in the frontend. - Add coverage for topology caching, invalidation, worktree creation, and error reporting. - Add a Windows process-event probe for diagnosing BitFun child process activity. | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 1 个月前 | ||
| 2 个月前 |