0xgeorgemathew/t3trade
←
upstream pingdotgg/t3code
The fork has diverged substantially from upstream. This report maps exactly how the two mains have split, which upstream changes are missing, where the fork will fight back, and which integration path minimizes risk to the trading layer. No branches, commits, or remotes were modified — this is analysis only.
Both branches share a common ancestor at a8e05cbb
(chore(release): prepare v0.0.31, 2026-07-29). Since then they have moved in parallel for six days.
The numbers below come from git rev-list --count and
git merge-tree against the freshly-fetched remotes.
Integration decisions must rest on evidence, not guesses. The left column is verifiable from the remotes; the right column is reasoned inference that an execution agent should confirm before acting.
main branches descend from a8e05cbb (v0.0.31 release prep).035_TradingDomain, upstream = 035_ProjectionThreadTitleRegeneration.git merge-tree dry-run reports exactly 12 textual conflicts and 41 clean auto-merges.scripts/check-fork-independence.ts guard that rejects upstream infrastructure URLs.searchThreads and ThreadTitleRegeneration additions to contracts/orchestration.ts are additive and should coexist with fork's trading command additions (inferred from diff regions).README.md, docs/README.md) are intentional fork divergences and should resolve in favor of the fork (inferred from fe092c004 chore(branding)).bootService/selfUpdate conflicts likely involve fork's fork-independence hardening — must preserve fork intent (inferred from check-fork-independence.ts existence).A single merge-base, two fast-moving tips. The fork's 143 commits are almost entirely new packages and trading features; upstream's 80 touch many of the same shared files (contracts, orchestration, web UI, cloud services).
From git merge-tree --write-tree upstream/main origin/main.
Risk is scored by combining how many lines each side changed in overlapping regions and whether the
file is load-bearing for the trading layer.
| File | Conflict region | Fork Δ | Upstream Δ | Risk |
|---|---|---|---|---|
| packages/contracts/src/orchestration.tsWS methods, command unions, OrchestrationThread | +88 lines | +76 lines | High | |
| apps/server/src/serverRuntimeStartup.tsservice wiring / startup layers | +2 lines | +342 lines | High | |
| apps/server/src/cloud/bootService.tsfork-independence hardening vs upstream rewrite | +6 lines | +288 lines | High | |
| apps/server/src/cloud/selfUpdate.tsupdate endpoint / rollback logic | +4 lines | +463 lines | High | |
| apps/web/src/components/settings/SettingsSidebarNav.tsxsidebar nav entries | +5 lines | +288 lines | Medium | |
| apps/server/src/cloud/bootService.test.tstest scaffolding | +2 lines | +611 lines | Medium | |
| apps/server/src/persistence/Migrations.tsimport list + migration manifest | +20 lines | +6 lines | High | |
| apps/desktop/src/app/DesktopEnvironment.tsenvironment identity | +6 lines | +24 lines | Medium | |
| apps/mobile/app.config.tsapp metadata / scheme | +12 lines | +22 lines | Medium | |
| apps/server/src/cli/connect.tsconnect command | +2 lines | +15 lines | Low | |
| README.mdbranding (intentional fork divergence) | +177 lines | +27 lines | Low | |
| docs/README.mddocs index (branding) | fork-only | +upstream | Low |
Files like apps/server/src/orchestration/decider.ts (fork +220 / upstream +38) and
apps/server/src/ws.ts (fork +68 / upstream +141) auto-merge without textual conflict,
but they are load-bearing for the trading state machine. Auto-merge success does not guarantee
semantic correctness — a typecheck and the trading test suite are mandatory after any integration.
These problems do not appear as <<<<<<< markers. They are silent collisions
in shared numeric namespaces and version catalogs. An execution agent that ignores them will produce a
tree that typechecks but is broken at runtime.
Both sides claimed migration slot 35. The fork uses it for
035_TradingDomain.ts (creates the core trading tables); upstream uses it for
035_ProjectionThreadTitleRegeneration.ts (thread title regen column).
If both files land under the same number, the migration loader will apply only one and the
other's schema change silently never runs — leading to missing tables or missing columns
depending on load order. The fork's migrations 035–044 must be renumbered to 036–045
(or higher) so upstream's 035 keeps its slot. This is a manual edit to
Migrations.ts plus a file rename — it will not surface as a text conflict.
Upstream bumped the entire Effect catalog from 4.0.0-beta.102 to
4.0.0-beta.103 (commit 2b1d4fecb). The fork still sits on β.102.
A β-bump can carry breaking schema/API changes — upstream's own
contracts/orchestration.ts edit (removing effect/Option import,
adding TrimmedString) is evidence of API drift. The integration must adopt
β.103 wholesale and re-run the full typecheck. pnpm-lock.yaml will conflict
but should be regenerated rather than merged by hand.
The fork ships scripts/check-fork-independence.ts, which fails CI if any source
file references pingdotgg/t3code infrastructure. Upstream's
bootService.ts, selfUpdate.ts, and connect.ts naturally
contain such references. Resolving those conflicts "in favor of upstream" would re-introduce a
live dependency on upstream's infra and break the guard. These three files must be resolved
in favor of the fork's redirection logic, then re-validated by running the independence check.
Five viable paths, each with a different trade-off between history cleanliness, conflict exposure, and reversibility. The green-bordered card is the recommendation.
Create sync/upstream-2026-08-04 off origin/main, run
git merge upstream/main, resolve the 12 conflicts plus the migration renumber,
typecheck, test, then fast-forward main. History is preserved; a merge commit
records the synchronization point.
# 0. Backup the current tip git branch backup/main-pre-sync-$(date +%Y%m%d) origin/main # 1. Fresh integration branch off the fork git checkout -b sync/upstream-2026-08-04 origin/main # 2. Ensure upstream is current git fetch upstream # 3. Merge — expect 12 conflicts git merge upstream/main --no-ff --no-commit # 4. Resolve conflicts (see phased plan), then: git add -A git commit -m "sync(upstream): merge pingdotgg/t3code main (80 commits) into T3 Trade - renumber fork migrations 035-044 -> 036-045 to free slot 035 for upstream - adopt Effect catalog beta.103 - preserve fork-independence hardening in bootService/selfUpdate/connect - resolve 12 textual conflicts per upstream-integration-analysis-2026-08-04" # 5. Verify before pushing pnpm install pnpm run typecheck pnpm test run apps/server/src/persistence packages/contracts packages/trading-contracts # 6. Push the branch and open a PR — do NOT force-push main git push -u origin sync/upstream-2026-08-04
Replay all 143 fork commits on top of upstream/main. Produces a perfectly linear
history, but every fork commit that touches a conflicting file may pause for resolution,
and the same conflict can recur multiple times across the 143-commit range.
ORIG_HEAD.# Backup is mandatory — rebasing rewrites history git branch backup/main-pre-rebase origin/main git checkout -b rebase/upstream-2026-08-04 origin/main git fetch upstream git rebase upstream/main # On each conflict: resolve, git add, git rebase --continue # To abandon: git rebase --abort # Force-push ONLY after full verification git push --force-with-lease origin rebase/upstream-2026-08-04
Pick individual upstream commits (e.g. 5c9358aca title regen,
4b71a2ae2 thread search, 61514c129 npx t3 pair) onto
origin/main. Useful if you want only a subset of upstream and can defer the rest.
git checkout -b cherry/upstream-selective origin/main git fetch upstream # Example: thread title regeneration + search (additive to contracts) git cherry-pick 5c9358aca # feat(web): regenerate thread titles git cherry-pick 4b71a2ae2 # feat(search): find threads by content git cherry-pick abc409c2d # project file picker + content search # Resolve per-commit, then: pnpm run typecheck && pnpm test run packages/contracts git push -u origin cherry/upstream-selective
Point main at upstream/main, then re-apply the trading layer as a
new commit (or series of commits) on top. Cleanest possible base, but discards all fork
history and requires re-porting 143 commits worth of work.
# MANDATORY backup git branch backup/main-pre-reset origin/main git checkout main git fetch upstream git reset --hard upstream/main git push --force-with-lease origin main # Then manually re-port the trading layer from backup/main-pre-reset
Split upstream's 80 commits into thematic batches (contracts/schema, web UI, mobile, desktop, cloud/infra, deps) and merge or cherry-pick each batch separately behind its own feature branch and PR. Slower, but each batch is independently reviewable and revertible.
Answer honestly, then follow the recommendation. This encodes the trade-offs above into a decision path grounded in the observed fork state (143 ahead, 80 behind, 12 conflicts).
Strategy A (merge) on a dedicated sync/upstream-2026-08-04 branch, merged
via PR. It is the safest strategy (no force-push, fully reversible, both histories preserved),
the fastest reasonable one (one conflict-resolution pass, not 143), and the cleanest long-term
(the merge commit becomes a durable record of the synchronization point). If you later want
finer-grained review, Strategy E is the natural fallback.
Six phases for Strategy A. Each phase is independently verifiable and abortable. Do not skip the
backup — if anything goes sideways, backup/main-pre-sync-* is the restore point.
backup/main-pre-sync-YYYYMMDD pointing at current origin/main.sync/upstream-2026-08-04 off origin/main..vscode/settings.json change and untracked artifacts/reports/*).git fetch upstream to ensure upstream/main is current.git merge upstream/main --no-ff --no-commit — expect 12 textual conflicts.git diff --name-only --diff-filter=U.035_TradingDomain→036, …, 044_TradingAccountObservations→045; update Migrations.ts import list and manifest array to match. Leave upstream's 035_ProjectionThreadTitleRegeneration as slot 35.pnpm-workspace.yaml (β.103); discard the fork's lock fragment. Regenerate pnpm-lock.yaml with pnpm install rather than merging it.bootService.ts, selfUpdate.ts, connect.ts — keep the fork's redirection logic; re-apply upstream's behavioral fixes around it, not over it.README.md, docs/README.md → take fork side (intentional divergence).apps/server/src/cli/connect.ts → re-apply fork's redirect on top of upstream's new behavior.apps/mobile/app.config.ts, apps/desktop/src/app/DesktopEnvironment.ts, apps/web/.../SettingsSidebarNav.tsx → merge both sides' additions.apps/server/src/cloud/bootService.test.ts → keep fork's assertions, add upstream's new cases.packages/contracts/src/orchestration.ts → union both sides' WS methods, command additions, and OrchestrationThread fields. Both are additive.apps/server/src/serverRuntimeStartup.ts, bootService.ts, selfUpdate.ts → port upstream's fixes, preserve fork's independence layer.pnpm install (regenerates lockfile at β.103).pnpm run typecheck — must pass; watch for Effect β.103 API drift.pnpm test run apps/server/src/persistence — proves migrations load 036–045 + upstream's 035.pnpm test run packages/contracts packages/trading-contracts — proves the unioned schemas decode.pnpm test run apps/server/src/orchestration — proves decider/projector still behave.scripts/check-fork-independence.ts — must still pass (no upstream infra URLs leaked in).git commit with the message template from Strategy A.git push -u origin sync/upstream-2026-08-04 — not a force-push.main; request review before merging.backup/main-pre-sync-* until the next sync is green.Interactive — click a row to mark it done. This is the contract between this analysis and whoever runs the integration. Do not begin execution until every "before" box is checked.
backup/main-pre-sync-YYYYMMDD created from origin/main..vscode/settings.json committed/stashed, untracked reports stashed.git fetch upstream run; upstream/main confirmed at 2b1d4fecb.sync/upstream-2026-08-04 created off origin/main.pnpm-lock.yaml regenerated, not hand-merged.bootService.ts, selfUpdate.ts, connect.ts.git diff --diff-filter=U is empty.README.md, docs/README.md) resolved in favor of the fork.pnpm install succeeds with no lockfile drift.pnpm run typecheck is green (watch for Effect β.103 API changes).scripts/check-fork-independence.ts still passes.sync/upstream-2026-08-04 (no force-push to main).git checkout main && git reset --hard backup/main-pre-sync-YYYYMMDD — no force-push to shared main without sign-off.
If verification fails and a clean fix is not obvious, abort the merge
(git merge --abort if unresolved, or abandon the branch), restore from
backup/main-pre-sync-YYYYMMDD, and re-attempt with Strategy E (phased) to
isolate which upstream batch introduced the failure. Never force-push main
without explicit sign-off.