Skip to content

fix(executor): scope legacy empty-branch environment fallback per repository - #3595

Merged
carlosflorencio merged 2 commits into
kdlbs:mainfrom
WaleWangPW:fix/workspace-reuse-empty-branch-fallback
Sep 11, 2026
Merged

carlosflorencio merged 2 commits into
kdlbs:mainfrom
WaleWangPW:fix/workspace-reuse-empty-branch-fallback

Conversation

@WaleWangPW

@WaleWangPW WaleWangPW commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Tip

PR walkthrough: Open the visual walkthrough

Summary

Fixes a residual workspace-reuse defect: the legacy empty-branch environment fallback was gated globally instead of per repository.

canonicalInventoryMatches used hasBranchScopedEnvironmentRepoRows to decide whether a legacy empty-branch row could satisfy a slot. That helper returns true when any repository has a branch-scoped row, so a repository that legitimately published a scoped row (a local executor's scoped row carries an empty worktree ID) still had its legacy empty-branch row accepted. A stale legacy row could then over-match the slot after the scoped row already satisfied it.

Change

  • Add repositoryHasBranchScopedRepoRow(rows, repositoryID), which checks only the target repository instead of the whole inventory.
  • Gate the legacy empty-branch fallback on that per-repository check.

Scope

  • apps/backend/internal/orchestrator/executor/executor_environment_reuse.go
  • Regression tests in executor_environment_reuse_inventory_test.go and executor_environment_test.go
  • Spec update in docs/specs/tasks/system-design/additional-session-workspace-reuse.md
  • Plan/work order in docs/plans/workspace-reuse-empty-branch-fallback/

Testing

  • go test ./internal/orchestrator/executor/ passes.
  • New tests cover a scoped local branch suppressing the legacy fallback, and a scoped-branch plus legacy-row inventory still attaching.

Review in cubic

@WaleWangPW
WaleWangPW deployed to opencode-review-trusted September 10, 2026 23:16 — with GitHub Actions Active
@coderabbitai

coderabbitai Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Advanced

Run ID: 5426f9ca-fcd6-4a65-94fc-67b4ead3a8c8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Advanced

Run ID: 455d7e3b-9b47-4d35-84c2-33f6eefcef83

📥 Commits

Reviewing files that changed from the base of the PR and between f817de3 and 4eb2086.

📒 Files selected for processing (6)
  • apps/backend/internal/orchestrator/executor/executor_environment_reuse.go
  • apps/backend/internal/orchestrator/executor/executor_environment_reuse_inventory_test.go
  • apps/backend/internal/orchestrator/executor/executor_environment_test.go
  • docs/plans/workspace-reuse-empty-branch-fallback/plan.md
  • docs/plans/workspace-reuse-empty-branch-fallback/task-01-per-repo-empty-branch-fallback.md
  • docs/specs/tasks/system-design/additional-session-workspace-reuse.md

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Summary

Summary by CodeRabbit

  • Bug Fixes

    • Fixed workspace reuse inventory matching to scope legacy empty-branch fallback behavior per repository.
    • Prevented branch-scoped rows from being over-counted when legacy rows with worktree IDs are also present.
    • Improved launch handling for repositories with branch-scoped rows lacking a worktree ID.
  • Documentation

    • Clarified repository-scoped inventory matching and fallback behavior in workspace reuse documentation.

Walkthrough

The change scopes the legacy empty-branch fallback per repository. Branch-scoped rows suppress the fallback even without a worktree ID. New tests and documentation cover canonical matching and reuse validation.

Changes

Workspace reuse matching

Layer / File(s) Summary
Per-repository fallback matching
apps/backend/internal/orchestrator/executor/executor_environment_reuse.go, docs/specs/tasks/system-design/..., docs/plans/workspace-reuse-empty-branch-fallback/plan.md
canonicalInventoryMatches now checks branch-scoped rows for the requested repository. The new helper ignores worktree IDs. The design and plan documents define this matching behavior.
Matching regression coverage
apps/backend/internal/orchestrator/executor/*test.go, docs/plans/workspace-reuse-empty-branch-fallback/task-01-per-repo-empty-branch-fallback.md
Tests verify that a scoped row plus a legacy empty-branch row produces one match and allows reuse validation to succeed. The task plan records acceptance criteria and verification steps.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Severity of issue fixed: Medium

Suggested reviewers: carlosflorencio, nova28

Merge Risk: ⚪ Minimal · up to 4eb20

The workspace reuse matching fix is covered by regression tests for both matching and attachment behavior, with no remaining merge-blocking risk identified.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description clearly explains the defect, implementation, scope, and validation. However, it does not follow the required template because it omits the required Checklist, uses a Summary heading in… Add the complete required Checklist unchanged, move the summary into direct prose without a Summary heading, use the required Validation heading, remove unnecessary non-template sections if they add no value, and remove the auto-generated a…
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 3 files. (3 skipped: 3… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: scoping the legacy empty-branch environment fallback per repository.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description clearly explains the defect, implementation, scope, and validation. However, it does not follow the required template because it omits the required Checklist, uses a Summary heading instead of direct summary prose, uses non-template section names, and retains a prohibited auto-generated attribution footer.

Resolution

Add the complete required Checklist unchanged, move the summary into direct prose without a Summary heading, use the required Validation heading, remove unnecessary non-template sections if they add no value, and remove the auto-generated attribution footer.

Full details: Docstring Coverage

Explanation

Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 3 files. (3 skipped: 3 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks each branch with care
No stale row can double there
A worktree may be blank or bright
One matching slot now comes out right
Tests guard the path through every night

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the small Pull request changes 0-10 application files label Sep 10, 2026
@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR changes canonical workspace-inventory validation so legacy empty-branch fallback is decided independently for each repository.

  • Adds a repository-scoped branch-row predicate that does not require a worktree ID.
  • Adds unit and validation regressions for a local scoped row coexisting with a stale legacy row.
  • Updates the workspace-reuse system design and adds an implementation plan and work order.
  • The core logic is consistent with the updated contract, but the plan metadata, production comment, and mixed-repository regression coverage need cleanup.

Confidence Score: 4/5

The logic appears behaviorally safe, but the explicit repository requirements for accurate plan state and invariant-focused production comments should be satisfied before merging.

The per-repository predicate correctly fixes legacy-row overmatching, with no blocking runtime defect identified; remaining findings concern two explicit documentation/style requirements and missing regression coverage for the distinguishing mixed-repository case.

Files Needing Attention: apps/backend/internal/orchestrator/executor/executor_environment_reuse.go, apps/backend/internal/orchestrator/executor/executor_environment_test.go, docs/plans/workspace-reuse-empty-branch-fallback/plan.md, docs/plans/workspace-reuse-empty-branch-fallback/task-01-per-repo-empty-branch-fallback.md

Important Files Changed

Filename Overview
apps/backend/internal/orchestrator/executor/executor_environment_reuse.go Replaces global legacy-fallback gating with a repository-specific scoped-row check; behavior is sound, but the helper comment violates the production-comment convention.
apps/backend/internal/orchestrator/executor/executor_environment_test.go Adds a focused same-repository regression but omits the mixed-repository case that distinguishes global from per-repository gating.
apps/backend/internal/orchestrator/executor/executor_environment_reuse_inventory_test.go Verifies admission with a local scoped row and stale legacy row, again using only one repository.
docs/specs/tasks/system-design/additional-session-workspace-reuse.md Documents that legacy fallback is suppressed per repository once any scoped branch row exists for that repository.
docs/plans/workspace-reuse-empty-branch-fallback/plan.md Accurately describes the fix but retains draft, unchecked, and pending metadata after implementation.
docs/plans/workspace-reuse-empty-branch-fallback/task-01-per-repo-empty-branch-fallback.md Defines the implemented work order but still records it as pending with no results.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  S[Repository and branch slot] --> R{Same repository has any scoped branch row?}
  R -- Yes --> M[Match only the requested scoped branch row]
  R -- No --> L{Legacy empty-branch row exists?}
  L -- Yes --> F[Allow legacy row as fallback]
  L -- No --> N[No canonical match]
  M --> C{Exactly one match?}
  F --> C
  N --> X[Refuse workspace reuse]
  C -- Yes --> A[Admit workspace reuse]
  C -- No --> X
Loading

Reviews (1): Last reviewed commit: "fix(executor): scope legacy empty-branch..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @WaleWangPW's task in 3m 3s —— View job


PR Review

  • Gather context
  • Read code review skill
  • Read changed files
  • Analyze correctness of the fix
  • Post inline comments
  • Post findings summary

Reviewed head 4eb2086f against origin/main (f817de3d).

Findings

Suggestion (recommended, doesn't block)

  1. Comment narrates bug history rather than stating the invariant — executor_environment_reuse.go:467-479

    • The repositoryHasBranchScopedRepoRow doc comment describes why the bug existed and how the stale row "over-matches the slot", which is historical narrative. Per CLAUDE.md: "production comments state the invariant, not the argument for it."
    • Fix: rewrite the comment to state what the function guarantees (non-empty branch slug ⇒ scoped, regardless of WorktreeID) without referencing the pre-fix behavior.
    • See inline comment: executor_environment_reuse.go:478
  2. Missing cross-repository test case — the distinguishing scenario is not exercised — executor_environment_test.go:69-79

    • Both new tests use a single repository. The global-vs-per-repository distinction that this PR exists to fix is not directly pinned by a test.
    • The regression case: an inventory where repo-1 has only a legacy empty-branch row and repo-2 has a scoped row. The old global predicate would (incorrectly) disable the fallback for repo-1 because of repo-2; the per-repository fix leaves it enabled. Without a test like this, a hypothetical regression back to the global predicate passes both existing tests.
    • A suggested test with exact values is in the inline comment on executor_environment_test.go:79.
  3. Plan and work order metadata still reflect pre-implementation state — plan.md, task-01-per-repo-empty-branch-fallback.md

    • Both files show status: draft/pending, an unchecked work order checkbox, and Results: Pending, even though the change is implemented and submitted. CLAUDE.md requires keeping plan statuses and results accurate.
    • Inline suggestions at plan.md:4, plan.md:76, plan.md:79, task-01-per-repo-empty-branch-fallback.md:7, task-01-per-repo-empty-branch-fallback.md:87.

Analysis

The core logic is correct. repositoryHasBranchScopedRepoRow is scoped to the target repository and deliberately omits the WorktreeID requirement that hasBranchScopedEnvironmentRepoRows carries — both decisions are right:

  • Per-repository: prevents a scoped row on a different repository from suppressing the fallback for the target repository (the original global over-reach).
  • No WorktreeID requirement: local executors produce scoped rows with empty worktree IDs by design; requiring the ID would misclassify those rows as legacy.

The function's status-agnostic behavior (it does not check DeletedAt or Status) matches the existing predicate's behavior and is noted in the plan as intentional.

The asymmetry between canonicalInventoryMatches (now per-repository) and reuseExistingRepositoryWorktrees (still global via hasBranchScopedEnvironmentWorktrees) is noted in the PR as intentionally out of scope.

Summary

Severity Count
Blocker 0
Suggestion 3

Verdict: Ready with suggestions — the fix is behaviorally correct. The three suggestions (comment wording, missing cross-repo test, stale plan metadata) can be addressed in a follow-up or in this PR before merge.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4eb2086f06

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-10T23:21:17.107140Z 4eb2086 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread docs/plans/workspace-reuse-empty-branch-fallback/plan.md
Comment thread docs/plans/workspace-reuse-empty-branch-fallback/plan.md Outdated
Comment thread docs/plans/workspace-reuse-empty-branch-fallback/plan.md
@carlosflorencio
carlosflorencio self-requested a review September 11, 2026 09:31
@carlosflorencio
carlosflorencio deployed to opencode-review-trusted September 11, 2026 09:40 — with GitHub Actions Active
@carlosflorencio

Copy link
Copy Markdown
Member

Thanks for the review feedback. Commit 9ba038e adds mixed-repository regression coverage, clarifies the scoped-row invariant, and updates the plan and work order with completed status and verification results. Focused and full executor tests plus specification lint pass.

@carlosflorencio
carlosflorencio merged commit 8303178 into kdlbs:main Sep 11, 2026
89 checks passed

This branch was successfully deployed

1 active deployment
opencode-review-trusted — 9ba038e2 Deployed Sep 11, 2026 by carlosflorencio via pr-walkthrough-generate #3447
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe-to-review small Pull request changes 0-10 application files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants