chore(sync): merge upstream v0.0.38 (t3o-31) - #57
Conversation
…pingdotgg#7774) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: shivam <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: Theo Browne <me@t3.gg>
…g#8367) Reuse one server config subscription for session bootstrap and live updates. Preserve environment theme opt-in, replay, deletion, slow subscriber recovery, and config stream failure handling. Co-authored-by: Adamulek123 <adam.bogucki2018@gmail.com>
Co-authored-by: Simone <185146821+Lucenx9@users.noreply.github.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
…dotgg#9013) Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…pingdotgg#9001) Co-authored-by: Guillermo Casanova <guillermo.casanova.b@gmail.com>
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com> Co-authored-by: maria <254055478+maria-rcks@users.noreply.github.com>
…stream sync (t3o-31 P0) Two test fakes failed with a bare Error in the Effect failure channel, a closure-assigned let narrowed to never, and a single-override pill read overriddenRows[0] under noUncheckedIndexedAccess. None changed behaviour; they were masked because the recursive typecheck never reached apps/server.
595 upstream commits since 0640410. 18 content conflicts, all resolved as upstream's code with the fork's seam re-inserted; the .plans rename/delete conflicts keep the fork's archive. routeTree.gen.ts regenerated (three board routes). The previously unmarked fork hunks that conflicted now carry T3o: markers. .gitignore re-includes .plans/ beneath upstream's new ignore line and the AGENTS.md fork block records why.
…rge caused
- BoardModelRow reads planModeEnabled from client settings, as the composer does.
- findBranchPullRequest resolves the default branch for upstream's widened PR
cache key instead of passing null.
- The orphaned-session integration test mocks the supervisor reactor that the
startup seam yields (new inventory row).
- The projection resume test seeds board projector watermarks into
boards.projection_state, where t3o-26 reads them, and asserts over the union.
- searchSettings("work") now also matches upstream's worktree/network items.
Upstream's new no-native-title-tooltip rule flags every intrinsic-element title= in the board (61 sites). BoardHint wraps the styled Tooltip primitive and renders its child as the trigger, so layout is unchanged; a nullish label renders the child alone.
Merge-log row, the decisions taken (plans stay tracked, upstream's settlement reactor accepted after audit, projector-enumeration policy, launcher protocol note), an unmarked-edits debt table for the next sync, a marker census, the three new upstream workflows to disable, and the runbook's per-package verification notes.
brentkelly
left a comment
There was a problem hiding this comment.
High-level summary
Upstream sync of pingdotgg/t3code v0.0.38 into t3o (595 upstream commits behind one merge commit), reviewed as: the two pre-merge fork commits, the merge commit's hand-resolved hunks (git show --cc), and the three fork commits on top. Upstream's own code was not re-reviewed.
The conflict resolutions hold up: every seam I traced is re-inserted on upstream's rewritten code (ws.ts actor stamp after normalizeDispatchCommand, BoardModeTabs inside the new WorkspacePageHeader, BoardGitLayerLive in place of GitLayerLive alongside PullRequestServiceLive, serverSettings.ts keeping both the indivisible-key branches and upstream's PERSISTED_SERVER_SETTINGS_DEFAULTS, GitHubCli.execute carrying both allowNonZeroExit and upstream's stdin/maxOutputBytes). .gitignore's !.plans/ re-include verified with git check-ignore. The ThreadSettlementReactor acceptance was checked against the supervisor: step liveness keys off session/turn state (threadIsAlive), the only thread event it consumes is thread.activity-appended, and isAutoSettlementCandidate excludes live sessions, pending input and queued turns, so the audit recorded in docs/t3o/seams.md stands. The findBranchPullRequest fix mirrors remoteStatus's default-branch keying, and the ProjectionPipeline test fix routes board projector watermarks through isBoardProjectorName. The two touched web test files pass locally (41 tests). Hover events on disabled buttons were verified empirically against the bundled Chromium 151 for the BoardHint refactor.
Nothing blocking; four nitpicks inline.
Reviewed head 1569f434b. Base branch t3o (the fork trunk), as intended for a sync PR.
| <BoardHint | ||
| label={ | ||
| threadLocked | ||
| ? "This card builds through its plan cards; its own thread opens at review" | ||
| : undefined | ||
| } | ||
| type="button" | ||
| > | ||
| <MessageSquareIcon className="size-3" /> | ||
| Thread | ||
| </button> | ||
| {hasReview ? ( | ||
| <button | ||
| className={tab("review")} | ||
| onClick={() => onSelect("review")} | ||
| title="Adversarial review loop" | ||
| className={cn(tab("thread"), threadLocked && "cursor-not-allowed opacity-50")} | ||
| disabled={threadLocked} | ||
| onClick={() => onSelect("thread")} | ||
| type="button" | ||
| > | ||
| <RefreshCcwIcon className="size-3" /> | ||
| Review | ||
| <MessageSquareIcon className="size-3" /> | ||
| Thread | ||
| </button> | ||
| </BoardHint> |
There was a problem hiding this comment.
Note
Nitpick: disabled-only hints now depend on hover events reaching a disabled <button>
This label (and the blocked/merge-disabled forward button above, the parent chip, the R{n} in-flight label and the round +/− ceilings in BoardCardReviewPane, the non-openable nodes in BoardPlanGraph/BoardPlansPanel) exists only while the control is disabled. A native title renders on a disabled button in every engine; TooltipTrigger relies on pointerenter/mouseenter reaching the element. I verified the bundled Chromium 151 does dispatch those on a disabled button, and upstream uses the identical pattern (PreviewChromeRow), so the Electron/Chrome path is fine. WebKit has historically not dispatched mouse events on disabled form controls, so Safari users of the web surface lose the explanation of why the control is off.
Suggested fix (optional): for the hints that only apply in the disabled state, keep the button enabled with aria-disabled and a no-op click (the pattern SidebarUpdatePill uses), or accept the WebKit gap and note it in BoardHint's doc comment so the next author does not re-discover it.
There was a problem hiding this comment.
Declined for this PR: the hint on the disabled Thread pill degrades to no tooltip on WebKit, where the native title on a disabled button did not show either, so nothing regresses. Tracked with the other BoardHint follow-ups.
| const remoteName = yield* gitCore | ||
| .resolvePrimaryRemoteName(cacheKey) | ||
| .pipe(Effect.orElseSucceed(() => null)); | ||
| const defaultBranch = | ||
| remoteName === null | ||
| ? null | ||
| : yield* gitCore | ||
| .resolveDefaultBranchName(cacheKey, remoteName) | ||
| .pipe(Effect.orElseSucceed(() => null)); |
There was a problem hiding this comment.
Note
Nitpick: two git subprocesses per lookup, even on a cache hit
resolvePrimaryRemoteName and resolveDefaultBranchName (a git remote and a git symbolic-ref spawn; GitVcsDriverCore.ts:1277 is uncached) now run before every prLookupCache read. The point of going at the cache directly was that a card refresh within the 2-minute TTL costs nothing; it now costs two process spawns per card, and board.refreshPullRequest is not serialised (see the note at supervisorReactor.ts:2369). The semantics are right (this mirrors remoteStatus at line 2009, which pays the same price), so this is parity with upstream, not a regression.
Suggested fix: compute defaultBranch lazily inside the cache lookup function, or memoise it per normalised cacheKey under the same epoch invalidation the PR cache already uses, so a hit stays a pure map read.
There was a problem hiding this comment.
Declined: the two subprocesses run only on the board's explicit PR refresh (card opened, View PR, post-merge), not on the status poll, and they mirror what remoteStatus already does for the same lookup. Folding default-branch resolution into the cache key computation is a follow-up alongside the PullRequestService adoption noted in the PR body.
| /> | ||
| <BoardHint label="Thread running"> | ||
| <span | ||
| aria-label="Thread running" |
There was a problem hiding this comment.
Note
Nitpick: aria-label on a bare <span> is not announced
ARIA 1.2 prohibits naming elements with the implicit generic role, so most screen readers ignore aria-label on a plain <span>. The old title was at least exposed as a description. Same shape on the Blocked span below, PhaseMarker in BoardCardReviewPane, the status dots in BoardCardThreadPane, SeverityTriple in BoardCardSummaryRow and the Working spinner in BoardPlansPanel.
Suggested fix: give the decorative dots role="img" (which permits aria-label), or drop the attribute and let the tooltip's aria-describedby wiring carry it.
There was a problem hiding this comment.
Fixed in 58e8a60. The working, running and awaiting dots carry role="img" alongside their aria-label so the name is announced.
| | Date | Upstream delta | Conflicts | Resolution | Time | | ||
| | ---------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | 2026-08-09 | 20 commits, 101 files, ~9.2k insertions (`main` ff'd to `05eb05118`) | **1 file**: `apps/server/src/persistence/Migrations.ts` — two hunks, both "upstream appended `039` where we appended `900`" at the list tails | Kept both lines, upstream's first. No seam needed re-applying; all 38 markers survived intact (verified with `rg "T3o:"` against the inventory). | Merge + resolution ≈ 1 minute; full verification (install, typechecks for contracts/client-runtime/server/web, walking-skeleton + engine + pipeline tests, all green) ≈ 4 minutes. | | ||
| | 2026-09-02 | 595 commits, 1,591 files (`main` ff'd to tag `v0.0.38`, `c0995d2ea`); spec `t3o-31` | **18 files, 27 hunks** + 32 `.plans` rename/delete. 11 were inventoried seams that moved with upstream churn (`ws.ts` dispatch body rewritten around the t3o-18 actor stamp; the t3o-05 tabs moved into upstream's new `WorkspacePageHeader`; three import seams; `index.css`; `orchestration.ts`/`rpc.ts`/`settings.ts`). 7 were **unmarked** fork edits (`serverSettings.ts`, `GitHubCli.ts`, `AppSidebarLayout.tsx`, `ChatComposer.tsx`, `server.ts` layer substitution, `contracts/orchestration.ts` `RuntimeMode` move, `settingsSearch.test.ts`). `routeTree.gen.ts` regenerated. | Every conflict resolved as upstream's code with the seam re-inserted; the unmarked hunks got markers on the way through. After the merge: 3 type errors (`planModeEnabled` on the board model row, a widened PR-cache key, an upstream-new integration test that drives the startup seam), 2 test failures (upstream tests now enumerate `ORCHESTRATION_PROJECTOR_NAMES` against the split `projection_state`; a settings-search substring), and 61 errors from upstream's new `no-native-title-tooltip` rule, fixed with a board-owned `BoardHint`. Ten pre-existing fork type errors were cleared first so the merge's own breakage was attributable. | Trial merge + measurement ≈ 2 h; real merge + resolution ≈ 20 min; fixes ≈ 1 h; verification (per-package typecheck, 5 test suites: 3,539 server / 3,280 web / 633 / 446 / 379, lint, two headless boots against copies of real databases) ≈ 40 min. | |
There was a problem hiding this comment.
Note
Nitpick: merge-log row is out of chronological order
The 2026-09-02 row sits between the two 2026-08-09 rows, so the log no longer reads top-to-bottom. The runbook above points the next sync at this log; an ordered table makes the latest baseline unambiguous.
Suggested fix: move this row to the end of the table (or the top, if the log is meant newest-first; either way, one direction).
There was a problem hiding this comment.
Fixed in 58e8a60. The v0.0.38 row now sits below the two 2026-08-09 rows.
… log Round-1 nitpicks: a bare span's aria-label is not announced, so the working, running and awaiting dots now carry role="img"; the v0.0.38 merge-log row moves below the two 2026-08-09 rows so the table reads chronologically.
🤖 Automated review loop summaryTermination
✅ What was fixed
⏭️ What was rejected
|
Merges upstream
pingdotgg/t3codev0.0.38 intot3o.mainwas fast-forwarded to the tag (c0995d2ea) first. Merge with a merge commit, never squash — squashing a 1,500-file upstream merge destroys the ancestry the next sync relies on.Plan:
.plans/t3o-31-upstream-sync-v0.0.38.md. Commits are one per phase so failures are attributable.Measured
.plansrename/delete, resolved--ours)no-native-title-tooltipT3o:markers on upstream filesVerification
vp lintandvp lint apps/web).VACUUM INTOcopy of the realuserdatadatabase: legacy board tables relocated intoboards.sqlite(13 tables), upstream migrations already current, all pages load.WorkspacePageHeader; board renders cards;BoardHintopens a real tooltip on hover; card modal opens with the workspace header hidden; sub-board drill-in; Settings → Board and settings search; upstream's pull-requests view.Decisions (details in
docs/t3o/seams.md).plans/stays tracked (!.plans/beneath upstream's new ignore; AGENTS.md fork block explains).ThreadSettlementReactoraccepted without a seam after auditing it against the board's own settle dispatches.ORCHESTRATION_PROJECTOR_NAMESget a marked test-side fix routed throughisBoardProjectorName.After merge
Disable the three new
pull_requestworkflows (desktop-macos-preview,mobile-fingerprint-check,web-preview) withgh workflow disable, like the other eight.Follow-ups (not in this PR)
PullRequestServicefor the board's forge merge (~250 unmarked lines become deletable).migrate-dev-dbawareness ofboards.sqlite.title=props on capitalised components (Button title=…) still render native tooltips; the rule exempts them.🤖 Generated with Claude Code