The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

Description

@pseudoseed

The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
budget searching for the branch files, hits an auto-rejected directory permission, and produces no
verdict.

Reproduced twice, identically, on PR #205:

Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
Glob "**/.git" in . · 0 matches
"The files on disk are main, not the PR branch. I'll locate the builder worktree..."
Read .consult/pr-205.diff [offset=976, limit=800]
permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
Glob "**/bugfix-196*/**" failed in /Users/chris/dev
Error: The user rejected permission to use this specific tool call.

It then ran out of road and the lane failed with:

opencode produced a review with no VERDICT line. A review that states no verdict is not a
verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

That failure is correct and should not change.#20's rule worked exactly as designed: no silent
approval. The defect is upstream of it.

Why it happens

The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
files live at .builders/<id>/…, which is inside the workspace — but the lane searched
/Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
directories outside the workspace. So it looked in the one place it is not allowed, having not been
told the one place it is.

It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
it hunting for the real files in the first place.

Why this matters more than it did yesterday

opencode is the designated substitute lane — the one reviewer on an account none of the others
share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
leaving one lane on a 24-file change.

A substitute that cannot review the thing it is substituting for is not a substitute.

Ask

  1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
    and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
    one exists.
  2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
    large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
    much), the hunt would not start.
  3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
    worked.

Related: #20 (a lane that did not review is not an approval), #195.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/consultMulti-agent consultation CLI

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e 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

      The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

      Description

      @pseudoseed

      The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
      budget searching for the branch files, hits an auto-rejected directory permission, and produces no
      verdict.

      Reproduced twice, identically, on PR #205:

      Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
      Glob "**/.git" in . · 0 matches
      "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
      Read .consult/pr-205.diff [offset=976, limit=800]
      permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
      Glob "**/bugfix-196*/**" failed in /Users/chris/dev
      Error: The user rejected permission to use this specific tool call.
      

      It then ran out of road and the lane failed with:

      opencode produced a review with no VERDICT line. A review that states no verdict is not a
      verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

      That failure is correct and should not change.#20's rule worked exactly as designed: no silent
      approval. The defect is upstream of it.

      Why it happens

      The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
      files live at .builders/<id>/…, which is inside the workspace — but the lane searched
      /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
      directories outside the workspace. So it looked in the one place it is not allowed, having not been
      told the one place it is.

      It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
      it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
      it hunting for the real files in the first place.

      Why this matters more than it did yesterday

      opencode is the designated substitute lane — the one reviewer on an account none of the others
      share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
      codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
      only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
      leaving one lane on a 24-file change.

      A substitute that cannot review the thing it is substituting for is not a substitute.

      Ask

      1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
        and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
        one exists.
      2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
        large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
        much), the hunt would not start.
      3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
        worked.

      Related: #20 (a lane that did not review is not an approval), #195.

      Activity

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

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        area/consultMulti-agent consultation CLI

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , '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

          The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

          Description

          @pseudoseed

          The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
          budget searching for the branch files, hits an auto-rejected directory permission, and produces no
          verdict.

          Reproduced twice, identically, on PR #205:

          Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
          Glob "**/.git" in . · 0 matches
          "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
          Read .consult/pr-205.diff [offset=976, limit=800]
          permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
          Glob "**/bugfix-196*/**" failed in /Users/chris/dev
          Error: The user rejected permission to use this specific tool call.
          

          It then ran out of road and the lane failed with:

          opencode produced a review with no VERDICT line. A review that states no verdict is not a
          verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

          That failure is correct and should not change.#20's rule worked exactly as designed: no silent
          approval. The defect is upstream of it.

          Why it happens

          The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
          files live at .builders/<id>/…, which is inside the workspace — but the lane searched
          /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
          directories outside the workspace. So it looked in the one place it is not allowed, having not been
          told the one place it is.

          It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
          it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
          it hunting for the real files in the first place.

          Why this matters more than it did yesterday

          opencode is the designated substitute lane — the one reviewer on an account none of the others
          share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
          codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
          only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
          leaving one lane on a 24-file change.

          A substitute that cannot review the thing it is substituting for is not a substitute.

          Ask

          1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
            and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
            one exists.
          2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
            large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
            much), the hunt would not start.
          3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
            worked.

          Related: #20 (a lane that did not review is not an approval), #195.

          Activity

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

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            area/consultMulti-agent consultation CLI

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , '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 \u003e 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

              The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

              Description

              @pseudoseed

              The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
              budget searching for the branch files, hits an auto-rejected directory permission, and produces no
              verdict.

              Reproduced twice, identically, on PR #205:

              Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
              Glob "**/.git" in . · 0 matches
              "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
              Read .consult/pr-205.diff [offset=976, limit=800]
              permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
              Glob "**/bugfix-196*/**" failed in /Users/chris/dev
              Error: The user rejected permission to use this specific tool call.
              

              It then ran out of road and the lane failed with:

              opencode produced a review with no VERDICT line. A review that states no verdict is not a
              verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

              That failure is correct and should not change.#20's rule worked exactly as designed: no silent
              approval. The defect is upstream of it.

              Why it happens

              The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
              files live at .builders/<id>/…, which is inside the workspace — but the lane searched
              /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
              directories outside the workspace. So it looked in the one place it is not allowed, having not been
              told the one place it is.

              It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
              it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
              it hunting for the real files in the first place.

              Why this matters more than it did yesterday

              opencode is the designated substitute lane — the one reviewer on an account none of the others
              share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
              codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
              only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
              leaving one lane on a 24-file change.

              A substitute that cannot review the thing it is substituting for is not a substitute.

              Ask

              1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
                and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
                one exists.
              2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
                large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
                much), the hunt would not start.
              3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
                worked.

              Related: #20 (a lane that did not review is not an approval), #195.

              Activity

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

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                area/consultMulti-agent consultation CLI

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , '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

                  The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

                  Description

                  @pseudoseed

                  The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
                  budget searching for the branch files, hits an auto-rejected directory permission, and produces no
                  verdict.

                  Reproduced twice, identically, on PR #205:

                  Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
                  Glob "**/.git" in . · 0 matches
                  "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
                  Read .consult/pr-205.diff [offset=976, limit=800]
                  permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
                  Glob "**/bugfix-196*/**" failed in /Users/chris/dev
                  Error: The user rejected permission to use this specific tool call.
                  

                  It then ran out of road and the lane failed with:

                  opencode produced a review with no VERDICT line. A review that states no verdict is not a
                  verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

                  That failure is correct and should not change.#20's rule worked exactly as designed: no silent
                  approval. The defect is upstream of it.

                  Why it happens

                  The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
                  files live at .builders/<id>/…, which is inside the workspace — but the lane searched
                  /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
                  directories outside the workspace. So it looked in the one place it is not allowed, having not been
                  told the one place it is.

                  It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
                  it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
                  it hunting for the real files in the first place.

                  Why this matters more than it did yesterday

                  opencode is the designated substitute lane — the one reviewer on an account none of the others
                  share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
                  codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
                  only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
                  leaving one lane on a 24-file change.

                  A substitute that cannot review the thing it is substituting for is not a substitute.

                  Ask

                  1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
                    and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
                    one exists.
                  2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
                    large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
                    much), the hunt would not start.
                  3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
                    worked.

                  Related: #20 (a lane that did not review is not an approval), #195.

                  Activity

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

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    area/consultMulti-agent consultation CLI

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , '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

                      The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

                      Description

                      @pseudoseed

                      The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
                      budget searching for the branch files, hits an auto-rejected directory permission, and produces no
                      verdict.

                      Reproduced twice, identically, on PR #205:

                      Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
                      Glob "**/.git" in . · 0 matches
                      "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
                      Read .consult/pr-205.diff [offset=976, limit=800]
                      permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
                      Glob "**/bugfix-196*/**" failed in /Users/chris/dev
                      Error: The user rejected permission to use this specific tool call.
                      

                      It then ran out of road and the lane failed with:

                      opencode produced a review with no VERDICT line. A review that states no verdict is not a
                      verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

                      That failure is correct and should not change.#20's rule worked exactly as designed: no silent
                      approval. The defect is upstream of it.

                      Why it happens

                      The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
                      files live at .builders/<id>/…, which is inside the workspace — but the lane searched
                      /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
                      directories outside the workspace. So it looked in the one place it is not allowed, having not been
                      told the one place it is.

                      It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
                      it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
                      it hunting for the real files in the first place.

                      Why this matters more than it did yesterday

                      opencode is the designated substitute lane — the one reviewer on an account none of the others
                      share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
                      codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
                      only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
                      leaving one lane on a 24-file change.

                      A substitute that cannot review the thing it is substituting for is not a substitute.

                      Ask

                      1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
                        and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
                        one exists.
                      2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
                        large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
                        much), the hunt would not start.
                      3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
                        worked.

                      Related: #20 (a lane that did not review is not an approval), #195.

                      Activity

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

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        area/consultMulti-agent consultation CLI

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , '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

                          The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

                          Description

                          @pseudoseed

                          The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
                          budget searching for the branch files, hits an auto-rejected directory permission, and produces no
                          verdict.

                          Reproduced twice, identically, on PR #205:

                          Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
                          Glob "**/.git" in . · 0 matches
                          "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
                          Read .consult/pr-205.diff [offset=976, limit=800]
                          permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
                          Glob "**/bugfix-196*/**" failed in /Users/chris/dev
                          Error: The user rejected permission to use this specific tool call.
                          

                          It then ran out of road and the lane failed with:

                          opencode produced a review with no VERDICT line. A review that states no verdict is not a
                          verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

                          That failure is correct and should not change.#20's rule worked exactly as designed: no silent
                          approval. The defect is upstream of it.

                          Why it happens

                          The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
                          files live at .builders/<id>/…, which is inside the workspace — but the lane searched
                          /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
                          directories outside the workspace. So it looked in the one place it is not allowed, having not been
                          told the one place it is.

                          It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
                          it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
                          it hunting for the real files in the first place.

                          Why this matters more than it did yesterday

                          opencode is the designated substitute lane — the one reviewer on an account none of the others
                          share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
                          codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
                          only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
                          leaving one lane on a 24-file change.

                          A substitute that cannot review the thing it is substituting for is not a substitute.

                          Ask

                          1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
                            and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
                            one exists.
                          2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
                            large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
                            much), the hunt would not start.
                          3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
                            worked.

                          Related: #20 (a lane that did not review is not an approval), #195.

                          Activity

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

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            area/consultMulti-agent consultation CLI

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , '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

                              The opencode lane cannot review builder-worktree PRs: it globs the parent dir, gets auto-rejected, and produces no verdict #207

                              Description

                              @pseudoseed

                              The opencode lane cannot review a PR whose changes live in a builder worktree. It burns its
                              budget searching for the branch files, hits an auto-rejected directory permission, and produces no
                              verdict.

                              Reproduced twice, identically, on PR #205:

                              Read packages/codev/src/agent-farm/utils/harness.ts <- reads MAIN, not the branch
                              Glob "**/.git" in . · 0 matches
                              "The files on disk are main, not the PR branch. I'll locate the builder worktree..."
                              Read .consult/pr-205.diff [offset=976, limit=800]
                              permission requested: external_directory (/Users/chris/dev/*); auto-rejecting
                              Glob "**/bugfix-196*/**" failed in /Users/chris/dev
                              Error: The user rejected permission to use this specific tool call.
                              

                              It then ran out of road and the lane failed with:

                              opencode produced a review with no VERDICT line. A review that states no verdict is not a
                              verdict — porch would read it as a non-blocking COMMENT and count it as an approval.

                              That failure is correct and should not change.#20's rule worked exactly as designed: no silent
                              approval. The defect is upstream of it.

                              Why it happens

                              The consult run executes with the workspace root as cwd, and the workspace is on main. The changed
                              files live at .builders/<id>/…, which is inside the workspace — but the lane searched
                              /Users/chris/dev (the parent) for **/bugfix-196*/**, and opencode's sandbox auto-rejects
                              directories outside the workspace. So it looked in the one place it is not allowed, having not been
                              told the one place it is.

                              It succeeded on earlier PRs by falling back to .consult/pr-<n>.diff, so the capability exists —
                              it just is not reliably reached, and on a large diff the fallback is truncated, which is what sends
                              it hunting for the real files in the first place.

                              Why this matters more than it did yesterday

                              opencode is the designated substitute lane — the one reviewer on an account none of the others
                              share, reached for when a default lane is quota-exhausted. On 2026-08-29 that was not hypothetical:
                              codex was quota-exhausted account-wide until ~15:40 and agy was rate-limited, so opencode was the
                              only second opinion available on two HIGH-tier PRs. It failed on both attempts for #205's re-review,
                              leaving one lane on a 24-file change.

                              A substitute that cannot review the thing it is substituting for is not a substitute.

                              Ask

                              1. Tell the lane where the branch files are. The consult run already knows the PR's head branch
                                and can resolve the builder worktree path. Pass it in the prompt, or set cwd to the worktree when
                                one exists.
                              2. Or make the diff sufficient. The lane reaches for real files because the diff is truncated on
                                large PRs. If the diff were complete (or the lane told explicitly that it is truncated and by how
                                much), the hunt would not start.
                              3. Whatever the fix, the lane's failure mode should stay loud. It is the one part of this that
                                worked.

                              Related: #20 (a lane that did not review is not an approval), #195.

                              Activity

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

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                area/consultMulti-agent consultation CLI

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions