refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup - #263

Merged
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle
Aug 24, 2026
Merged

refactor: raise the worktree seam to one lifecycle module; age-guard orphan cleanup#263
Tryanks merged 1 commit into
mainfrom
refactor/c1-worktree-lifecycle

Conversation

@Tryanks

Copy link
Copy Markdown
Owner

Architecture round, candidate C1 — the hottest churn area in the repo (both recent Windows CI breakages were path-identity facts leaking across this seam).

Problem — the worktree cluster in git.rs was deep but its interface sat below the lifecycle: every caller derived and preserved four correlated identities (root, path, branch, base) and re-read the actual branch afterwards. Draft creation and orchestrate dispatch each assembled that independently.

Change

  • New services/worktree.rs: provision(root, session_id) -> ProvisionedWorktree{path, branch, seed_summary} owns root validation, base resolution, path/branch derivation + collision suffixing, git worktree add, .worktreeinclude seeding, and rollback; merge_back / remove / cleanup_orphans move with unchanged semantics; porcelain parsing + canonical path identity (incl. macOS /var/private/var) exist exactly once.
  • git.rs: 1,883 → 912 lines (keeps diff/branch/status plumbing). sessions.rs worktree prep 82→67 lines; orchestrate resolver 48→28 — runtime keeps only policy (opt-in, fallback, warnings).
  • Bug fix (found via concurrent test runs): orphan cleanup deleted other processes' live worktrees — any entry whose session id isn't in this store looked orphaned. Cleanup now applies a documented ORPHAN_MIN_AGE (1 h) presumption-of-life to fresh entries (decision is a deterministic seam taking now/threshold — the test ages entries without sleeping), and TCODE_WORKTREES_DIR gives tests isolated roots so parallel runs never touch ~/.tcode/worktrees.

Wins — leverage: one interface, both call sites; locality: identity bugs concentrate in one module; dispatch prep became deterministic and directly testable; a cross-process data-loss class is closed.

Tests: all worktree lifecycle tests migrated to the module; new caller-free provision-identity test; fresh-preserved/old-removed age-guard test; dispatch regression on an isolated root. Workspace: 853 passed.

Gates: fmt / clippy -D warnings / full workspace tests — green locally.

🤖 Generated with Claude Code

…module; age-guard orphan cleanup
services/worktree.rs owns the whole lifecycle — provision(root, id)
derives path/branch/base, handles collision suffixing, seeds, rolls
back on failure and returns the identity triple; merge_back/remove/
cleanup_orphans move with their semantics; porcelain parsing and
canonical path identity live here once. git.rs drops from 1,883 to 912
lines; both runtime assemblers (draft creation, orchestrate dispatch)
lose their duplicated identity derivation.
Also fixes a real concurrency bug found via parallel test runs: orphan
cleanup deleted OTHER processes' live worktrees (their sessions aren't
in this store). Cleanup now presumes entries younger than ORPHAN_MIN_AGE
(1h) are live, and TCODE_WORKTREES_DIR lets tests use isolated roots
instead of the user's real ~/.tcode/worktrees.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Tryanks
Tryanks enabled auto-merge (squash) August 24, 2026 07:26
@Tryanks
Tryanks merged commit f31dea0 into mainAug 24, 2026
3 checks passed
@Tryanks
Tryanks deleted the refactor/c1-worktree-lifecycle branch August 24, 2026 07:33
Sign up for freeto 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.

1 participant

@Tryanks