Skip to content

chore(sync): absorb upstream main through 611132c17 - #169

Open
NoahHendrickson wants to merge 192 commits into
claude/sync-2026-10-05from
claude/sync-2026-10-07
Open

NoahHendrickson wants to merge 192 commits into
claude/sync-2026-10-05from
claude/sync-2026-10-07

Conversation

@NoahHendrickson

Copy link
Copy Markdown
Owner

Problem

custom still lacks the orchestrator-V2 sync (#167), and upstream has moved another 188 commits past it (1604ccc9d..611132c17): the auth-scope series (pingdotgg#9786–pingdotgg#9791), GitHub API source control, webhooks, the browser on the environment server, and the thread-notice rework. This PR is stacked on #167's branch; retarget it to custom before #167 merges.

What this does

Merges upstream/main through 611132c17. 19 conflicted files resolved, three override shadows ported by hand, every fork fence accounted for in a census against the pre-merge baseline (only the deltas named below).

Decisions, all fenced and recorded in .fork/customizations.yaml:

Deliberately not adopted, consistent with the manifest: single-list thread drag and context-drag-to-composer, the connected-environment thread search, and the change-request snapshot wiring (knip ignores name them).

Also carries the cherry-pick of #167's Windows-profile test fix so this branch is green on its own.

Verification

  • Typecheck: web, server, desktop, mobile clean.
  • Fork guard suite: 60 files / 492 tests pass.
  • knip, lint-owned, vp lint apps/web/src: clean, 0 errors.
  • Server tests for the fork-touched services, desktop identity/Clerk tests, and the web tests for every conflicted file pass. The scripts cross-arch Windows artifact case fails on Apple Silicon as it does on pristine upstream.

Resolved by Claude Fable 5.1 in Claude Code, with three subagents for the sidebar, composer/chat view, and override shadows.

🤖 Generated with Claude Code

maria-rcks and others added 30 commits October 5, 2026 12:04
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>
…dotgg#15958)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#15951)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…of encoding a fallback (pingdotgg#16118)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ngdotgg#16167)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16170)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pingdotgg#16002)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#15592)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tgg#16200)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…eady passed (pingdotgg#15804)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r cached (pingdotgg#15500)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ng to the inbox (pingdotgg#16204)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
juliusmarminge and others added 18 commits October 6, 2026 20:30
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…#10298)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…rver (pingdotgg#16718)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…g#16741)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…16752)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ngdotgg#16290)

Co-authored-by: spoukyii <61633921+spoukyii@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ices (pingdotgg#16631)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tgg#16762)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s of untracked files (pingdotgg#16771)

Co-authored-by: Braulio Oliveira <brauliobo@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…eep (pingdotgg#16760)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16761)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ingdotgg#16782)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merges pingdotgg/t3code main (188 commits, 1604ccc..611132c) into the
orchestrator-V2 sync branch. 19 conflicted files resolved, three override
shadows ported by hand, every fork fence accounted for in a census against
the pre-merge baseline.

Notable decisions, all fenced and recorded in .fork/customizations.yaml:

- Auth scopes (pingdotgg#9786-pingdotgg#9791): the operate / write gates upstream added land
  on the fork's own controls too (pinned-row drag, pin and settle hover
  actions, rename, the branch-mismatch Restore, the pending-input card and
  the composer's primary actions), so a read-only connection sees the same
  behavior in the fork's chrome as in upstream's.
- Thread notices (pingdotgg#16782, pingdotgg#16631): upstream moved the settled / snoozed /
  woke notices into the timeline-footer status line and replaced the
  resume-compaction card with compact-on-send. The fork keeps its
  "Unsettle" wording on the status line and drops the now-vacuous
  settled-only banner filter; the branch-changed card is the one Figma
  notice card left.
- Fast mode (pingdotgg#16069): rides in the traits label text; the fork's model
  picker drops its bolt.
- Server: the follower keeps its production-only wiring under upstream's
  namespace-import and layerXyz naming (pingdotgg#16267, pingdotgg#16282); the base-remote
  identity pick composes with upstream's new origin identity (pingdotgg#16353).
- Repository remote origin test, CI runner for the new transfer-report job,
  and the Phosphor shim gain the icons upstream newly imports.

Deliberately not adopted, consistent with the manifest: single-list thread
drag and context-drag-to-composer, the connected-environment thread
search, and the change-request snapshot wiring (knip ignores name them).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…le pair

Upstream's DesktopPreReadyFileSystem test migrates "T3 Code (Alpha)" into
"t3code-v2"; the fork's packaged pair is "T3 Code (Fork)" -> "t3code-fork-v2"
(fork-app-identity), so the test failed on every CI run of this branch. The
directory names are fenced to the fork's and the file joins the entry's
watch list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 78b5c2e)
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. labels Oct 7, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do not approve. The rest of this sync port is the right shape — settled/snoozed/woke left the banner stack so composerBannerVisibility correctly disappeared, the fast-mode bolt left with the label text, follower wiring tracked layerXyz, and nothing here newly crosses 1k that wasn’t already last-resort.

The operate-scope port for Questions is not.

apps/web/src/overrides/components/chat/ComposerPendingUserInputPanel.tsx ~L91–98 — wrong boundary. Upstream’s card already has three named inputs and one derived flag: responseDisabled = disabled || isResponding || !canRespond. Folding scope-denied into isResponding makes the hook lie, and it is why a call site can forget the prop. Give useComposerPendingUserInputCard a first-class disabled. Keep isResponding as responding. Derive responseDisabled once. The timer-clear and number-key guards then follow the real invariant.

apps/web/src/components/chat/ChatComposer.tsx L7213 vs L7232 — #9786 was bolted onto one mount (!isComposerCollapsedMobile). The compact mount never gets disabled={!canOperateThread}. That path still runs option clicks, number keys, and the 200ms single-select auto-advance, which calls onAdvance directly. Gating Next/Submit in ComposerPrimaryActions does not close the hole.

Judo: first-class disabled on the hook; pass disabled={!canOperateThread} at both ChatComposer sites; guard both literals so the next sync cannot drop the compact one. Do not leave a second, ungated Questions chrome for the viewport this fork designs for.

(Inline comments omitted — GitHub refused the 13k-file diff.)

Open in Web View Automation 

Sent by Cursor Automation: Thermo nuke 4.6

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 5.0 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.9 KiB — 29.3 KiB ✅
Codex Live turn messages — 2 — 8 ✅
Claude Total thread wire — 5.0 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.8 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 21.2 KiB — 29.3 KiB ✅
Claude Live turn messages — 2 — 8 ✅

Baseline: unavailable · PR result: 33f92a3 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

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

Reviewed at bb1ffab. Changes needed.

[P2] Pass the operate-scope gate to the compact Questions panel too. ChatComposer.tsx:7231

The expanded mount passes disabled={!canOperateThread}, but the isComposerCollapsedMobile mount does not. The shadow defaults disabled to false, so on a read-only connection the compact card still enables option clicks and number-key shortcuts, changes the local answers, and schedules its 200ms auto-advance through onAdvanceActivePendingUserInput. The final onRespondToUserInput scope check does prevent submission; the visible result is an apparently answerable flow that advances and then silently cannot submit. Gate both mounts and add coverage for compact read-only interaction and scope withdrawal during auto-advance. This independently confirms the earlier bot finding; it is still present on the latest head.

Scope: fork-specific merge resolutions and auth-scope/preview/notice/override integration, rather than an exhaustive audit of every imported upstream commit. Focused validation on this head: 13 Questions/primary-action tests, 133 branch-follow/launch/finalization/runtime-layer tests, and 9 desktop identity/profile tests pass. Current CI is green, but those tests do not cover the missing compact prop. No browser verification.

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

Review: #169 absorb through 611132c

Verdict: one upstream hunk was dropped in conflict resolution and two fork-only controls missed the new operate-scope gate. Fix those three and this is good: the server/desktop/CI side is clean, the thread-notice and fast-mode ports are right, the shadows carry upstream's deltas, and the fence census matches the PR's own accounting (fork-composer-banner-surface 17→12, ci-runners 13→14, nothing else moved). GitHub refused inline comments on the 13k-file diff, so anchors are permalinks at this head.

Fix before merge

  1. Collapsed-mobile Questions card is not scope-gated (Cursor's second point is correct). ChatComposer.tsx L7232-L7244: two <ComposerPendingUserInputPanel> mounts; the first (L7213) has disabled={!canOperateThread}, the isComposerCollapsedMobile one has none. Upstream at 611132c gates both (L6703 and L6724), so this is a dropped upstream line, not a fork decision. On a read-only phone client the options stay clickable, number keys work, the hook runs its 200ms single-select auto-advance through every question, and the final submit is swallowed by onRespondToUserInput's scope guard: the UI walks the user through answering and then silently does nothing.

  2. Fork-only "Settle all threads" ignores the operate scope. Sidebar.tsx L4213-L4233 builds settleAllKeysByProjectKey on draft / settledOverride / threadSettlement capability only, and SidebarV2ProjectGroupHeader.tsx L260-L268 disables the item only on settleAllCount === 0. Upstream's bulk settle in the same file uses canOperateThreads(settlingThreads) (L375, L3497). A read-only connection fires one settleThread per thread and gets a toast per rejection. Adding readEnvironmentScope(thread.environmentId, AuthOrchestrationOperateScope) to the key filter zeroes the count and disables the item.

  3. The liveness pill's stop square stays enabled when the scope is denied. ComposerMonitoringPill.tsx L65-L73 is disabled={props.stopping} and ChatView.tsx L7499-L7505 never passes canOperateThread. Upstream's equivalent Stop button is disabled={!canOperateThread || isStoppingBackgroundWork} (one of the five upstream-added ChatView lines absent from this head). handleStopBackgroundWork has the readEnvironmentScope guard so no request fires, but the control looks live and does nothing. Lower severity than 1 and 2, same class.

Cursor bot

  • Point (ii), the ungated compact mount: correct, see 1.
  • Point (i), folding disabled into the hook's isResponding (override L91-L98): functionally equivalent to upstream's responseDisabled (click guard, number-key guard, auto-advance timer cleared when the flag flips; the dismiss button is ungated on both sides). A style nit. A first-class disabled on the hook would make the mount prop harder to forget, which is exactly what happened in 1, so I'd take the suggestion while fixing it.

Nits

  • ChatView.tsx L7803: const backgroundWorkItems = [goalBannerItem].filter(…) is a fork edit (upstream has [goalBannerItem, backgroundWorkBannerItem]) sitting one line above the fork-composer-shell fence that explains it. Pull it inside.
  • __fork_guards__/forkModelPicker.test.ts:232 still says "collapses it (and the bolt)" two lines above the comment saying the bolt is gone.
  • forkLocalCheckoutBranchFollow.ts:14 says t3code/… placeholder; the manifest says t3/…. isTemporaryWorktreeBranch is the source of truth either way.
  • Pre-existing, not from this PR: the pin hover action at Sidebar.tsx L1871 lacks upstream's !sortable?.isDragging; RepositoryIdentityResolver names a gh-marked third remote while upstream's new buildRepositoryOrigin still groups under literal origin (unreachable in the fork's own checkout).

Verified locally (detached checkout of bb1ffab, fresh vp i)

  • Fork guards 492/492; web tests for the conflicted chat/usage/preview/custom files 331/331; server tests for ThreadLaunchService, RunFinalizationService, forkLocalCheckoutBranchFollow, RunExecutionService, RepositoryIdentityResolver 124/124; desktop identity/env/Clerk/assets tests 38/38; vp run knip:check and .fork/lint-owned.mjs clean.
  • Follower still provided only through layerRunFinalizationServiceWithFollowerProvided → effect executor; replay harness builds bare RunFinalizationService.layer, so the no-op default holds. Identity resolver: fork base-remote rule first, falls back to pickPrimaryRemote; composes with pingdotgg#16353's origin identity (fork checkout: base=origin → origin omitted → same grouping key upstream computes).
  • Every ci.yml job on a hosted runner inside a ci-runners fence, check needs transfer-report; release.yml Blacksmith jobs gated on github.repository == 'pingdotgg/t3code'. patchedDependencies exact-pinned and 1:1 with the lockfile (Release Smoke).
  • Upstream-added lines missing from the conflict-resolved files are all deliberate fork variants except the Stop gate in 3 and the mount in 1. composerBannerVisibility.ts has no remaining importers. Both override shadows upstream touched in this range carry the delta.
  • The cherry-picked Windows-profile test fix is byte-identical to #167's, so merging both is a no-op. git merge-tree with #168's branch is conflict-free.

Merge mechanics

Retarget to custom with gh pr edit 169 --base custom before #167 merges (merging #167 with --delete-branch first closes this PR and a reopen triggers a fresh full CI run).

Reviewed by Claude Fable 5.1 via Claude Code (T3 Code), with subagents per cluster; every finding above was re-verified against the source.

Review findings on the absorb: upstream pingdotgg#9786 gates both Questions mounts
and the collapsed-mobile one lost its gate in conflict resolution, so a
read-only phone client could click through answers it could never submit.
The fork's "Settle all threads" built its key list without the scope and
would have fired one rejected settle per thread, and the liveness pill's
stop square stayed enabled while its handler silently declined.

The compact mount passes disabled={!canOperateThread} again and a guard
pins both mounts. useComposerPendingUserInputCard takes `disabled` as its
own input and derives responseDisabled from it, isResponding and
canRespond, so the click, number-key and auto-advance guards follow one
flag; two hook tests cover a read-only card and a scope withdrawn mid-timer.
Settle-all filters its keys through readEnvironmentScope, and the pill
takes canStop from ChatView.

Nits from the same review: the backgroundWorkItems line moves inside the
fence that explains it, the model picker guard stops mentioning the bolt,
and the follower comment names the shorter t3/ placeholder prefix.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

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

Addressed at 720c5f2 (inline anchors still refused on the 13k-file diff, so notes by path).

Fixed

  1. ChatComposer.tsx collapsed-mobile Questions mount: disabled={!canOperateThread} restored, matching upstream's second mount. __fork_guards__/forkPendingUserInput.test.ts now asserts both mounts carry the gate so the next sync cannot drop one.
  2. Sidebar.tsx settle-all: the key builder filters through readEnvironmentScope(…, AuthOrchestrationOperateScope), so a read-only connection sees a zero count and a disabled item instead of one rejection toast per thread.
  3. Liveness pill stop square: ComposerMonitoringPill / resolveComposerLivenessPillProps take canStop; ChatView passes canOperateThread, so the square is inert when the handler would decline.
  4. Cursor point (i), taken as suggested: useComposerPendingUserInputCard has a first-class disabled input and derives responseDisabled = disabled || isResponding || !canRespond; the shadow passes disabled and isResponding separately. Two hook tests cover a read-only card ignoring selection and a scope withdrawn mid-timer cancelling the pending auto-advance.

Nits: backgroundWorkItems now sits inside the fork-composer-shell fence; the model-picker guard comment no longer mentions the bolt; the follower comment names the t3/ prefix.

Left as is (pre-existing, not from this PR, as noted): the pin hover action's !sortable?.isDragging and the gh-marked third-remote vs buildRepositoryOrigin case. Happy to take either in a follow-up.

Verified: web typecheck clean, fork guards 495/495, pending-input / sidebar / chat view / composer web tests 394/394, lint-owned and knip clean.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.