You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fork maintenance: commit stack on upstream, rebase routine and CI #6
The fork's changes live as a small, reviewable commit stack on upstream pingdotgg/t3codemain, and a routine absorbs upstream updates cheaply and safely, so the fork can grow (Model Router, OpenBot mode, VMs) without falling behind.
Acceptance criteria
docs/fork.md (or equivalent) describes the model: upstream main is the base; fork work is a stack of topic commits; features go in new files and packages; upstream edits stay minimal and are listed with their files.
A script or agent routine fetches upstream, rebases the stack, runs the fork's CI, and reports conflicts per upstream file; it never force-pushes a published branch without the same proof.
CI on the fork runs upstream's own checks plus fork tests on every PR and on the rebased stack.
One real upstream update has been absorbed through the routine, with the conflicts and time recorded.
A list of candidate upstream extension points (for example a real parentThreadId on thread.create, a right-panel tab registry) with the patch each would remove. Offering them upstream is a separate human decision.
Non-goals
Sending anything upstream; releases; mobile builds.
Submitted to Model Router as job t3code-6-1101 (source runner at model-router e837872, state dir ~/.local/share/durable-runner-planner-f1213, planner: Claude thread f1213d48). One PR will follow; not merged.
First job t3code-6-1101 falsely failed at runner control (see the new model-router bug) after its worker had already committed 30668ed9b and b0e67c7e4. Cancelled it and continued as t3code-6-cont on the same branch.
Added scripts/fork-maintenance.test.ts: 6 tests driving both scripts against throwaway git fixtures.
Upstream absorption (real, on this branch): range b2b43be..e3e7cc3, 54 commits, verified ancestor with exact count; fetch plus rebase under 2 minutes; conflicts: none. Fresh fetch today confirms upstream tip is still e3e7cc3 (pending 0, cross-checked with git ls-remote).
Proof on 3e2af5351: install pass; typecheck 0 errors; lint exit 0 (pre-existing warnings only); test: one pre-existing upstream failure (build-desktop-artifact cross-arch Windows probe) reproduced on pristine upstream base in a clean worktree, unrelated to this diff; new tests 6/6 pass; fmt --check pass.
Re-verification of candidate 3e2af5351 (PR #9, still the single open PR for this branch, head matches): fresh upstream fetch shows tip still e3e7cc3 (pending 0), so the recorded absorption b2b43be..e3e7cc3 with conflicts: none stands. Fresh proof: install exit 0; typecheck exit 0; lint exit 0; fmt --check exit 0; test exit 1 from exactly one failure, the pre-existing upstream build-desktop-artifact Windows cross-arch probe already reproduced on pristine upstream base e3e7cc3 and unrelated to this diff; new fork-maintenance tests 6/6 pass. No code changes were needed; tree clean.
Elon method review 2026-09-25 (toolboxmd/model-router#106): the user runs the upstream "T3 Code (Alpha).app", so no fork feature reaches them until a fork build is their daily T3. Priority inside this Issue: first a documented way to build and run the fork's desktop app (or server plus web client) as the daily T3, alongside or instead of the upstream app, preserving the user's data; the rebase routine and CI second. Installing it is the user's step.
Issue #6 implementation complete. Final candidate: 7894006fe on chore/6-fork-maintenance.
What changed this turn:
Diagnosed the turn-2 proof failure as environmental: the live T3 Code desktop instance leaves ELECTRON_RUN_AS_NODE=1 in the environment, which breaks upstream scripts/build-desktop-artifact.test.ts assertions that inspect spawned command envs.
Fixed the routine, not the upstream test: scripts/fork-rebase.sh now runs the proof block in a subshell with ELECTRON_RUN_AS_NODE cleared.
pnpm exec vp run -r test: pass — 5360 tests passed, 10 skipped. Required environmental cleanup on this Mac: ELECTRON_RUN_AS_NODE unset, TMPDIR=/private/tmp, PATH stripped of /opt/homebrew/bin, and vp run -r --concurrency-limit 1 test to avoid a flaky upstream openVsxThemes timeout under cross-workload contention.
pnpm exec vp fmt --check: pass
Candidate upstream extension points are listed in docs/fork.md (parentThreadId, thread visibility, right-panel tab registry, thread persona). Offering them upstream remains a separate human decision; nothing was sent upstream.
Found while merging #11: upstream CI jobs run on paid Blacksmith runners (runs-on: blacksmith-* in .github/workflows/ci.yml and mobile-fingerprint-check.yml). The fork has none, so every fork PR's CI stays queued forever. The fork CI part of this Issue must map these to GitHub-hosted runners (e.g. ubuntu-24.04, macos-15) through a small fork-only patch, or run the fork's checks in a separate workflow.
Cost check 2026-09-25: every toolboxmd repo is public (verified), so standard GitHub-hosted runners are free and unlimited (org billing usage shows net $0 for Actions minutes). Decision for the fork CI: map blacksmith-*-ubuntu-2404 to ubuntu-24.04 and blacksmith-*-macos-* to macos-15 in a small fork-only patch. No Blacksmith account or self-hosted runner needed; a self-hosted runner on a public repo would run untrusted fork PR code.
Measure before settling (user, 2026-09-25): once CI runs on GitHub-hosted runners, record wall-clock time per job and per PR run for one commit, next to the same commit's upstream Blacksmith timings (gh api repos/pingdotgg/t3code/actions/runs/<id>/jobs). Report the speedup and whether Blacksmith's 3,000 free min/month would cover our volume (~11 job-minutes per CI run upstream). Switching to Blacksmith needs its GitHub app installed on the org, which is the user's call.
Wall time per PR run: 268s here vs about 140s upstream, so about 2x slower. The critical path is Test on both; a full Check at 2.4x would take about 280s and become the critical path, so expect about 4.5 to 5 minutes per run.
Job time per run: about 21 job-minutes here (includes the 77s macOS job upstream skipped and a partial Check) vs 10.6 upstream. On GitHub-hosted runners this costs $0 (public repo).
Blacksmith's 3,000 free minutes/month at about 11 job-minutes per run cover about 270 CI runs/month. The fork ran 18 CI workflow runs today (a busy day of merges and pushes); at that rate (about 540/month) Blacksmith's free tier would run out mid-month. Measured from one day only, so treat it as an estimate. Recommendation: stay on free GitHub-hosted runners; switching costs about 2.5 minutes per run. Installing the Blacksmith GitHub app is your call.
Current CI state on PR #9: Fork Stack Model, Test, Test Server 1-3, Rust, Release Smoke and both Mobile jobs pass. Check fails in knip: ThreadsToolkitRegistrationLive in apps/server/src/mcp/McpHttpServer.ts:613 is an unused export. #10 added it; PR #9 does not touch that file. The fix is to remove the export keyword (belongs with the #10 follow-up). An earlier run also failed the web test shikiReviewHighlighter.test.ts > initializes source and snippet highlighting without a warmup once; it passed on the rerun (flaky).
PR #9 is merged by squash as merge commit e15afa0.
Landed:
Removed the unused ThreadsToolkitRegistrationLive export from apps/server/src/mcp/McpHttpServer.ts.
Fixed the fork branding dependency in apps/web/src/bundledDev.test.ts by supplying the minimal branding fixture required by the fork's bootError.ts.
Added that upstream-file edit to scripts/fork-upstream-edits.txt and documented it in docs/fork.md.
The replacement GitHub-hosted CI run 36156360212 passed Check, Test, Fork Stack Model, all server shards, Rust, Release Smoke, and mobile checks.
Local proof: bundledDev.test.ts 2/2, scripts/fork-check.sh, and knip:check passed.
Remaining: upstream absorption of the fork's commit stack into toolboxmd/t3code main, using the documented rebase routine and the user-approved force-with-lease step. No upstream absorption was performed here.
Issue #6 handoff: upstream absorption done on a branch. Landing on main is waiting on human approval.
Branch chore/6-absorb-upstream, head 72ba8f658d155a1edd87be68489718ed80dd9c39. PR for CI and review: chore(fork): absorb upstream through de251fc29 (#6) #45. It lands by force-with-lease, not by merge: git push --force-with-lease=main:096e9c0064d83be350b2280308ccbf1598b03661 origin chore/6-absorb-upstream:main
Range b2b43bef7..de251fc29: 128 upstream commits. Stack: 17 fork commits replayed, plus one commit that records the absorption in docs/fork.md (the Absorption log format there). The stack is now 18 of the 20 allowed.
Decisions
All 278 report rows (98 upstream commits) are decided in the PR comments.
Adopt upstream and delete ours: none. No upstream commit provides a fork capability, so the patch set did not shrink this time.
#11846 (per-thread auto-settle switch) is a manual opt-out. It does not replace the automatic child-activity guard (Sidebar: show a parent thread as working while its child threads work #31), so ours stays. Its threadAutoSettleOptOut capability merged beside our issues and issueLinks capabilities.
#13572 (agents banner) covers provider-native background agents only, so it does not replace our sidebar child-working state.
#13516 (sidebar Back) already covers /pull-requests, which also hosts our Issues view. No fork edit is needed.
#13060 (shell commands from chat) merged beside our Issue/PR link handling in ChatMarkdown.tsx.
Everything else is keyword-only or an unrelated auto-merge: keep ours.
Time
Fetch, rebase and the three conflicts took about 2 minutes. Worktree creation to push took about 34 minutes, including the adaptations, the report review and five proof runs.
Proof scripts/fork-rebase.sh --proof on 72ba8f658 passed in 590s:
Nothing failed on the final run, so there was no failure to compare against plain upstream.
One earlier run failed because this fresh worktree's install had no Electron binary: pnpm did not fetch it, and two desktop suites then raced to download it. Running electron/install.js in the worktree fixed it. This is environmental and has not been checked against a plain upstream checkout.
Elon method pass on the absorption (coordinator, 2026-09-27).
Requirement: upstream's 128 changes in fork main and Chromeria without breaking fork features; future absorptions cheap. Proof: CI green on the exact stack plus review of non-replay changes.
Kept: pre-landing CI through a base branch at the upstream candidate (without it main can go red after the force-push); review of the settlement conflict (it caught a real perf regression); the Sidebar: show a parent thread as working while its child threads work #31 guard (upstream's opt-out and agents banner don't cover child threads).
Cut: the absorption log in docs/fork.md: it duplicates the PR and this Issue, costs a stack commit, cannot hold its own SHA, and contradicts AGENTS.md (a merged PR is the implementation record). The record now lives on the absorption PR and here.
Follow-up, not now: require overlap decisions only for real file or code overlaps; keyword-only rows were most of the 278 and carried no decisions of consequence.
Constraint: round trips (review, CI, approval), so fixes go in one push with one re-review and one approval.
Issue #6 update after the review of PR #45 (#45 (comment)). The PR description is now the full absorption record, as docs/fork.md says; this comment is the Issue copy.
New head d7ee6ae1d5fe61f6241dd80f546ee184d7a2179a: 17 fork commits on upstream de251fc29. The in-repo absorption log commit is dropped.
PR chore(fork): absorb upstream through de251fc29 (#6) #45 base is now absorb-base/de251fc29 (a branch at upstream de251fc29), so CI runs. The Routine in docs/fork.md says so, and the record now goes on the PR and this Issue. Landing is still --force-with-lease onto main after approval, then delete absorb-base/de251fc29.
Settlement guard: the all-threads read, settled children included, happens only when a thread is about to settle, once per sweep. Turn-end sweeps keep upstream #13691's gain. The new test covers a settled child with background work on both sweep paths.
CI on d7ee6ae1d: every job passes except Test, and it fails only on upstream's packages/client-runtime/src/platform/persistence.test.ts > encodeShellSnapshotForCache. That test timed out at 5000ms after 7.3s on the GitHub-hosted runner. Upstream's own CI ran it at the same commit de251fc29 in 2.3s on Blacksmith, and it takes 0.6s locally. The fork does not touch its schemas; it is a runner-speed problem with a test new in this range (#13767). The fix is a fork-side decision, not yet made.
Completed. One real upstream update absorbed through the routine: b2b43be..de251fc (128 upstream commits), fork stack 17 commits, landed on main by force-with-lease (096e9c006 -> 8518d0d) with user approval. Record, conflicts, decisions, time and proof: PR #45. CI on main at 8518d0d: CI success, Fork success. Routine now includes the absorb-base/ step so CI runs on absorption PRs.
Activity
lukemaj commentedon Sep 25, 2026
Submitted to Model Router as job
t3code-6-1101(source runner at model-router e837872, state dir~/.local/share/durable-runner-planner-f1213, planner: Claude thread f1213d48). One PR will follow; not merged.lukemaj commentedon Sep 25, 2026
First job
t3code-6-1101falsely failed at runner control (see the new model-router bug) after its worker had already committed 30668ed9b and b0e67c7e4. Cancelled it and continued ast3code-6-conton the same branch.lukemaj commentedon Sep 25, 2026
Issue #6 done via PR #9 (branch chore/6-fork-maintenance, candidate 3e2af5351, base toolboxmd/t3code main, never merged).
Kept the earlier worker's 30668ed9b and b0e67c7e4, verified them, and finished the issue:
Upstream absorption (real, on this branch): range b2b43be..e3e7cc3, 54 commits, verified ancestor with exact count; fetch plus rebase under 2 minutes; conflicts: none. Fresh fetch today confirms upstream tip is still e3e7cc3 (pending 0, cross-checked with git ls-remote).
Proof on 3e2af5351: install pass; typecheck 0 errors; lint exit 0 (pre-existing warnings only); test: one pre-existing upstream failure (build-desktop-artifact cross-arch Windows probe) reproduced on pristine upstream base in a clean worktree, unrelated to this diff; new tests 6/6 pass; fmt --check pass.
lukemaj commentedon Sep 25, 2026
Re-verification of candidate 3e2af5351 (PR #9, still the single open PR for this branch, head matches): fresh upstream fetch shows tip still e3e7cc3 (pending 0), so the recorded absorption b2b43be..e3e7cc3 with conflicts: none stands. Fresh proof: install exit 0; typecheck exit 0; lint exit 0; fmt --check exit 0; test exit 1 from exactly one failure, the pre-existing upstream build-desktop-artifact Windows cross-arch probe already reproduced on pristine upstream base e3e7cc3 and unrelated to this diff; new fork-maintenance tests 6/6 pass. No code changes were needed; tree clean.
lukemaj commentedon Sep 25, 2026
Elon method review 2026-09-25 (toolboxmd/model-router#106): the user runs the upstream "T3 Code (Alpha).app", so no fork feature reaches them until a fork build is their daily T3. Priority inside this Issue: first a documented way to build and run the fork's desktop app (or server plus web client) as the daily T3, alongside or instead of the upstream app, preserving the user's data; the rebase routine and CI second. Installing it is the user's step.
lukemaj commentedon Sep 25, 2026
Issue #6 implementation complete. Final candidate:
7894006feonchore/6-fork-maintenance.What changed this turn:
ELECTRON_RUN_AS_NODE=1in the environment, which breaks upstreamscripts/build-desktop-artifact.test.tsassertions that inspect spawned command envs.scripts/fork-rebase.shnow runs the proof block in a subshell withELECTRON_RUN_AS_NODEcleared.docs/fork.mdto document the cleanup.Commit stack on
chore/6-fork-maintenance:ce536b283docs: Project Direction for the toolboxmd workspace fork (docs: Project Direction for the toolboxmd workspace fork #5)30668ed9bdocs(fork): rebase routine, stack check and fork CIb0e67c7e4fix(fork): fork-rebase listing must survive head closing the pipeb97f1be10test(fork): focused tests for the rebase routine safety rules3e2af5351docs(fork): list maintenance tests and fix formatter whitespace7894006fefix(fork): run proof in a subshell cleared of ELECTRON_RUN_AS_NODEUpstream absorption (already recorded in docs/fork.md and the PR):
b2b43bef7..e3e7cc3fc(54 commits)b2b43bef7(fix(server): preserve racy edits in review diff previews (#12613))e3e7cc3fc(fix(usage): price Claude fast-mode requests at the fast rate (#13599))git fetch upstream main && git rebase upstream/mainviascripts/fork-rebase.shPR: #9 (base:
main, head:chore/6-fork-maintenance), never merged.Proof on final candidate
7894006fe:pnpm install --frozen-lockfile: passpnpm exec vp run -r typecheck: pass, 0 errorspnpm exec vp lint: pass (warnings only, pre-existing)pnpm exec vp run -r test: pass — 5360 tests passed, 10 skipped. Required environmental cleanup on this Mac:ELECTRON_RUN_AS_NODEunset,TMPDIR=/private/tmp,PATHstripped of/opt/homebrew/bin, andvp run -r --concurrency-limit 1 testto avoid a flaky upstreamopenVsxThemestimeout under cross-workload contention.pnpm exec vp fmt --check: passCandidate upstream extension points are listed in
docs/fork.md(parentThreadId, thread visibility, right-panel tab registry, thread persona). Offering them upstream remains a separate human decision; nothing was sent upstream.lukemaj commentedon Sep 25, 2026
Found while merging #11: upstream CI jobs run on paid Blacksmith runners (
runs-on: blacksmith-*in.github/workflows/ci.ymlandmobile-fingerprint-check.yml). The fork has none, so every fork PR's CI stays queued forever. The fork CI part of this Issue must map these to GitHub-hosted runners (e.g.ubuntu-24.04,macos-15) through a small fork-only patch, or run the fork's checks in a separate workflow.lukemaj commentedon Sep 25, 2026
Cost check 2026-09-25: every toolboxmd repo is public (verified), so standard GitHub-hosted runners are free and unlimited (org billing usage shows net $0 for Actions minutes). Decision for the fork CI: map
blacksmith-*-ubuntu-2404toubuntu-24.04andblacksmith-*-macos-*tomacos-15in a small fork-only patch. No Blacksmith account or self-hosted runner needed; a self-hosted runner on a public repo would run untrusted fork PR code.lukemaj commentedon Sep 25, 2026
Measure before settling (user, 2026-09-25): once CI runs on GitHub-hosted runners, record wall-clock time per job and per PR run for one commit, next to the same commit's upstream Blacksmith timings (
gh api repos/pingdotgg/t3code/actions/runs/<id>/jobs). Report the speedup and whether Blacksmith's 3,000 free min/month would cover our volume (~11 job-minutes per CI run upstream). Switching to Blacksmith needs its GitHub app installed on the org, which is the user's call.lukemaj commentedon Sep 25, 2026
Fork CI timing on GitHub-hosted runners (PR #9, commit
2c5f346f0, CI run https://github.com/toolboxmd/t3code/actions/runs/36133328921) against upstream Blacksmith for the same jobs (upstream CI push run https://github.com/pingdotgg/t3code/actions/runs/35982894445 onb2b43bef7, the fork's upstream base).Current CI state on PR #9: Fork Stack Model, Test, Test Server 1-3, Rust, Release Smoke and both Mobile jobs pass. Check fails in
knip:ThreadsToolkitRegistrationLiveinapps/server/src/mcp/McpHttpServer.ts:613is an unused export. #10 added it; PR #9 does not touch that file. The fix is to remove theexportkeyword (belongs with the #10 follow-up). An earlier run also failed the web testshikiReviewHighlighter.test.ts > initializes source and snippet highlighting without a warmuponce; it passed on the rerun (flaky).2 remaining items
docs(fork): list maintenance tests and fix formatter whitespace
docs(fork): Chromeria install, squash-plus-absorption model and GitHu…
ci(fork): check the PR head, not GitHub's merge ref
docs(fork): allowlist the #14 web branding edits
lukemaj commentedon Sep 25, 2026
Issue #6 delivery update.
PR #9 is merged by squash as merge commit e15afa0.
Landed:
Remaining: upstream absorption of the fork's commit stack into toolboxmd/t3code main, using the documented rebase routine and the user-approved force-with-lease step. No upstream absorption was performed here.
docs(fork): Chromeria install, rebase routine and GitHub-hosted CI (#9)
lukemaj commentedon Sep 27, 2026
Issue #6 handoff: upstream absorption done on a branch. Landing on
mainis waiting on human approval.chore/6-absorb-upstream, head72ba8f658d155a1edd87be68489718ed80dd9c39. PR for CI and review: chore(fork): absorb upstream through de251fc29 (#6) #45. It lands by force-with-lease, not by merge:git push --force-with-lease=main:096e9c0064d83be350b2280308ccbf1598b03661 origin chore/6-absorb-upstream:mainb2b43bef7..de251fc29: 128 upstream commits. Stack: 17 fork commits replayed, plus one commit that records the absorption indocs/fork.md(the Absorption log format there). The stack is now 18 of the 20 allowed.Conflicts, per upstream file
apps/web/src/components/onboarding/WelcomeWizard.tsx(fork feat(web): show Chromeria as the product name in the web UI #14 against upstream #13397): upstream'stext-2xlclass, ourAPP_BASE_NAME.knip.jsonc(fork feat(fork): map fork features and report upstream overlap #24 against upstream #13589): both script entries kept.apps/server/src/orchestration/ThreadSettlementReactor.ts(fork Sidebar: show a parent thread as working while its child threads work #31, inside feat(web): GitHub Issues next to PRs, linked to threads, with computed status (#25) #37, against upstream #13691): kept upstream's one-thread read. That read holds no child threads, so the child-activity guard now reads unsettled threads only when the thread would actually settle. New test, which fails without the change (checked by mutation).Adaptations with no conflict (each folded into its owning commit)
planPrismRolePatch(fork feat(web): Prism settings in the Providers layout, lanes only for Worker #35). It now names its return type.Decisions
All 278 report rows (98 upstream commits) are decided in the PR comments.
threadAutoSettleOptOutcapability merged beside ourissuesandissueLinkscapabilities./pull-requests, which also hosts our Issues view. No fork edit is needed.ChatMarkdown.tsx.Time
Fetch, rebase and the three conflicts took about 2 minutes. Worktree creation to push took about 34 minutes, including the adaptations, the report review and five proof runs.
Proof
scripts/fork-rebase.sh --proofon72ba8f658passed in 590s:Nothing failed on the final run, so there was no failure to compare against plain upstream.
One earlier run failed because this fresh worktree's install had no Electron binary: pnpm did not fetch it, and two desktop suites then raced to download it. Running
electron/install.jsin the worktree fixed it. This is environmental and has not been checked against a plain upstream checkout.Unverified
pnpmbinary is not on PATH on this Mac. The proof used a temporarynpx pnpm@11.10.0shim.bb028be18, the stack below the log commit.Fork
mainhas not been touched.lukemaj commentedon Sep 27, 2026
Elon method pass on the absorption (coordinator, 2026-09-27).
mainand Chromeria without breaking fork features; future absorptions cheap. Proof: CI green on the exact stack plus review of non-replay changes.maincan go red after the force-push); review of the settlement conflict (it caught a real perf regression); the Sidebar: show a parent thread as working while its child threads work #31 guard (upstream's opt-out and agents banner don't cover child threads).docs/fork.md: it duplicates the PR and this Issue, costs a stack commit, cannot hold its own SHA, and contradicts AGENTS.md (a merged PR is the implementation record). The record now lives on the absorption PR and here.lukemaj commentedon Sep 27, 2026
Issue #6 update after the review of PR #45 (#45 (comment)). The PR description is now the full absorption record, as
docs/fork.mdsays; this comment is the Issue copy.d7ee6ae1d5fe61f6241dd80f546ee184d7a2179a: 17 fork commits on upstreamde251fc29. The in-repo absorption log commit is dropped.absorb-base/de251fc29(a branch at upstreamde251fc29), so CI runs. The Routine indocs/fork.mdsays so, and the record now goes on the PR and this Issue. Landing is still--force-with-leaseontomainafter approval, then deleteabsorb-base/de251fc29.d7ee6ae1d: every job passes exceptTest, and it fails only on upstream'spackages/client-runtime/src/platform/persistence.test.ts > encodeShellSnapshotForCache. That test timed out at 5000ms after 7.3s on the GitHub-hosted runner. Upstream's own CI ran it at the same commitde251fc29in 2.3s on Blacksmith, and it takes 0.6s locally. The fork does not touch its schemas; it is a runner-speed problem with a test new in this range (#13767). The fix is a fork-side decision, not yet made.docs(fork): Chromeria install, rebase routine and GitHub-hosted CI (#9)
lukemaj commentedon Sep 27, 2026
Completed. One real upstream update absorbed through the routine: b2b43be..de251fc (128 upstream commits), fork stack 17 commits, landed on main by force-with-lease (096e9c006 -> 8518d0d) with user approval. Record, conflicts, decisions, time and proof: PR #45. CI on main at 8518d0d: CI success, Fork success. Routine now includes the absorb-base/ step so CI runs on absorption PRs.