Skip to content

chore(sync): merge upstream v0.0.38 (t3o-31) - #57

Merged
brentkelly merged 602 commits into
t3ofrom
feature/t3o-31-upstream-sync
Sep 2, 2026
Merged

brentkelly merged 602 commits into
t3ofrom
feature/t3o-31-upstream-sync

Conversation

@brentkelly

Copy link
Copy Markdown
Owner

Merges upstream pingdotgg/t3code v0.0.38 into t3o. main was 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

Metric Value
Upstream commits / files 595 / 1,591
Content conflicts 18 files, 27 hunks (+32 .plans rename/delete, resolved --ours)
Conflicts on unmarked fork edits 7 of 18 (now marked)
Merge-caused type errors / test failures 3 / 2
Lint errors from upstream's new no-native-title-tooltip 61, all in the board
Pre-existing fork type errors cleared first 10
T3o: markers on upstream files 88 → 107 (none lost; the rest are new markers on previously unmarked hunks)
Lockfile unchanged

Verification

  • Typecheck per package (contracts, shared, client-runtime, web, server, desktop, mobile): clean.
  • Tests: server 3,539 passed / 10 env-skipped; web 3,280; desktop 643; client-runtime 633; contracts 446; shared 379; effect-acp 32; effect-codex-app-server 33; ssh 26; tailscale 14. 0 failures.
  • Lint: 0 errors (vp lint and vp lint apps/web).
  • Headless boot against a VACUUM INTO copy of the real userdata database: legacy board tables relocated into boards.sqlite (13 tables), upstream migrations already current, all pages load.
  • Headless boot against a copy of the dev database: upstream migrations 41–43 applied, board ledger untouched; thread view carries the Board tab inside upstream's new WorkspacePageHeader; board renders cards; BoardHint opens 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).
  • Upstream's ThreadSettlementReactor accepted without a seam after auditing it against the board's own settle dispatches.
  • Upstream tests enumerating ORCHESTRATION_PROJECTOR_NAMES get a marked test-side fix routed through isBoardProjectorName.
  • Fork stays at launcher protocol 3 (upstream 2) — recorded as a semantic-conflict watch item.

After merge

Disable the three new pull_request workflows (desktop-macos-preview, mobile-fingerprint-check, web-preview) with gh workflow disable, like the other eight.

Follow-ups (not in this PR)

  • Adopt upstream's new PullRequestService for the board's forge merge (~250 unmarked lines become deletable).
  • Seam the remaining unmarked edits listed in the new debt table.
  • migrate-dev-db awareness of boards.sqlite.
  • Remaining title= props on capitalised components (Button title=…) still render native tooltips; the rule exempts them.

🤖 Generated with Claude Code

t3dotgg and others added 30 commits August 21, 2026 21:04
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>
Adamulek123 and others added 25 commits September 1, 2026 04:07
…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>
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 brentkelly left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +1062 to +1078
<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>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +2653 to +2661
const remoteName = yield* gitCore
.resolvePrimaryRemoteName(cacheKey)
.pipe(Effect.orElseSucceed(() => null));
const defaultBranch =
remoteName === null
? null
: yield* gitCore
.resolveDefaultBranchName(cacheKey, remoteName)
.pipe(Effect.orElseSucceed(() => null));

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 58e8a60. The working, running and awaiting dots carry role="img" alongside their aria-label so the name is announced.

Comment thread docs/t3o/seams.md Outdated
| 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. |

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@brentkelly

Copy link
Copy Markdown
Owner Author

🤖 Automated review loop summary

Termination

  • Converged at round 1 — the round-1 fresh review found no new 🔴/🟡 issues. PR is considered ready to merge. (Mode: --fast.)

✅ What was fixed

  • 🟢 docs/t3o/seams.md:236 — merge-log row out of chronological order (round 1, 58e8a602e)
  • 🟢 apps/web/src/board/BoardCardItem.tsx:303aria-label on a bare <span> not announced; the status dots now carry role="img" (round 1, 58e8a602e)

⏭️ What was rejected

  • 🟢 apps/server/src/git/GitManager.ts:2653 — two git subprocesses per findBranchPullRequest even on a cache hit
    • Author's reasoning: runs only on the board's explicit PR refresh, mirrors remoteStatus; folding it into the cache is a follow-up alongside adopting upstream's PullRequestService.
  • 🟢 apps/web/src/board/BoardCardDetailView.tsx:1062 — hint on a disabled button depends on hover reaching a disabled <button> (WebKit)
    • Author's reasoning: the native title it replaced did not show on a disabled button there either; no regression. Tracked as a BoardHint follow-up.

⚠️ Standing disagreements for human review

None — the loop converged on the first fresh review, so no rereview round ran.

Review: #57 (review)

@brentkelly
brentkelly merged commit 5698920 into t3o Sep 2, 2026
4 of 5 checks passed
@brentkelly
brentkelly deleted the feature/t3o-31-upstream-sync branch September 2, 2026 07:16
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.