Skip to content

feat(review): add forge-backed review thread fetching - #7907

Merged
ralphbean merged 18 commits into
fullsend-ai:mainfrom
csoceanu:aisdlc-118/fetch-resolved-threads
Oct 8, 2026
Merged

ralphbean merged 18 commits into
fullsend-ai:mainfrom
csoceanu:aisdlc-118/fetch-resolved-threads

Conversation

@csoceanu

@csoceanu csoceanu commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add forge-backed fetching of pull-request and merge-request review threads for review-agent context.

This PR provides the fullsend-side abstraction, normalization, CLI command, and provider-specific integrations. Agent-side consumption of the generated context remains a separate follow-up in the agents repository.

Related issues

Changes

  • Add ListPullRequestReviewThreads to the forge abstraction.
  • Add fullsend fetch-review-threads for normalized review-thread output.
  • Add GitHub GraphQL review-thread fetching with pagination and truncation metadata.
  • Add GitLab merge-request discussion fetching through the forge client.
  • Preserve all comments, positions, resolution state, and resolver identity.
  • Preserve removed-line locations by using old_path when only old_line is available.
  • Include effective actor roles and explicit verification metadata for comment authors and resolvers.
  • Resolve GitHub roles from collaborator permissions and GitLab roles from project membership, with per-request caching and fail-closed lookup handling.
  • Recognize GitLab bot and human actors without treating an unknown actor as verified.
  • Keep the existing <!-- finding:f_... --> marker format. This change copies finding IDs into thread context but does not create or modify IDs.
  • Keep the supported per-repo workflow compatible with the review agent's pre-script and configured app-set identity.
  • Keep agent-side ledger and disposition updates out of this PR.

Follow-up integration

A separate change in the agents repository will consume the normalized review-thread output and apply verified human-resolution context to the review-findings ledger.

This PR intentionally does not implement dismissed_by_human or other ledger disposition behavior.

Testing

  • Go tests for the CLI, forge abstraction, GitHub, GitLab, and poller packages.
  • GitHub GraphQL pagination, role lookup, caching, and lookup-failure tests.
  • GitLab discussion resolution, resolver ordering, actor lookup, role mapping, caching, failure, and position tests.
  • CLI output and validation tests.
  • Workflow alignment tests.
  • Pre-commit hooks pass with Go 1.26.5 and module mode.

@csoceanu
csoceanu requested a review from a team as a code owner October 1, 2026 13:31
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

E2E tests are running

Authorization passed for this commit. See the E2E Tests workflow for results.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Pre-fetch human-resolved threads for review agent runs

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Fetch human-resolved PR review threads before agent runs to preserve dismissal context.
• Exclude bot resolutions and write an empty result when fetching fails, preserving review
 availability.
• Pass the result path to the agent step; agent consumption requires a follow-up change.
Diagram

graph TD
  Workflow["Review workflow"] --> Fetch["Thread prefetch"] --> API["GitHub GraphQL"] --> Filter{"Human resolved?"} -->|Yes| Output["Resolution JSON"] --> Agent["Agent run"]
  Filter -->|No| Empty["Empty result"] --> Agent
  API -->|Error| Empty
Loading
High-Level Assessment

Keep the GraphQL pre-fetch alongside the existing prior-review pre-fetch: it obtains resolution state, resolver identity, and comments before the agent runs while failing open. A REST-based fetch would require more API coordination for the same context. Agent-side consumption remains a separate follow-up.

Files changed (4) +610 / -0

Enhancement (2) +223 / -0
reusable-review.ymlRun resolved-thread pre-fetch before review +13/-0

Run resolved-thread pre-fetch before review

• Adds a pre-fetch step after prior-review retrieval and passes its output file path to the review agent step. This wires the context into the workflow but does not make the agent consume it.

.github/workflows/reusable-review.yml

pre-fetch-resolved-threads.shCollect human-resolved review thread context +210/-0

Collect human-resolved review thread context

• Fetches paginated GitHub review threads, excludes bot resolutions and incomplete comment pages, and records finding IDs and human responses in JSON. API failures yield an empty result so review can proceed.

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh

Other (2) +387 / -0
MakefileInclude resolved-thread tests in script-test +1/-0

Include resolved-thread tests in script-test

• Runs the new shell test suite as part of the existing script-test target.

Makefile

pre-fetch-resolved-threads-test.shTest thread filtering and fail-open behavior +386/-0

Test thread filtering and fail-open behavior

• Adds 12 mocked GraphQL cases covering human and bot resolutions, finding IDs, incomplete comments, output metadata, and API failure.

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads-test.sh

@qodo-code-review

qodo-code-review Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Large reviews omit resolved threads ✓ Resolved
Description
The pagination loop stops after 20 pages even when GitHub reports more review threads, then writes
the collected subset without a truncation flag. On a pull request with more than 2,000 threads,
human resolutions on later pages are absent from the file passed to the agent, while the metadata
counts only the fetched threads.
Code

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[R76-79]

+  if [[ "${page}" -gt 20 ]]; then
+    echo "::warning::Resolved-threads pagination hit page cap — remaining threads skipped"
+    break
+  fi
Relevance

●●● Strong

Unbounded review-thread truncation is a concrete correctness bug; repository history accepts
robustness fixes in scaffold scripts.

PR-#6947

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Each page requests at most 100 threads, the loop breaks before page 21 regardless of has_next, and
the output metadata reports counts derived only from accumulated nodes.

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[42-46]
internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[69-79]
internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[184-204]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The 20-page cap silently makes the JSON incomplete for pull requests with more than 2,000 review threads; the workflow warning does not tell a consumer that the file is partial.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[74-79]
- internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[187-204]

## Recommended Fix
Retain the safety cap, but record an explicit incomplete or truncated status in the output whenever more pages remain. Ensure consumers can distinguish that partial result from a complete set, and test the cap boundary.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Other reviewers' replies become dismissals ✓ Resolved
Description
human_response selects the last comment by any human, and resolution_context calls any such
comment an explicit_dismissal without checking whether that person resolved the thread or what
they said. When one reviewer comments and another resolves the thread, the output presents the first
reviewer's reply as the resolution rationale; even a reply promising a fix receives the dismissal
label.
Code

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[R170-173]

+        human_response: (
+          [.comments.nodes[] | select(.author.login != $bot and .author.login != $shared_bot and .author.__typename == "User")]
+          | last // null
+          | if . then (.body | .[0:500]) else null end
Relevance

●●● Strong

The unrestricted human-comment classification can mislabel intent, matching accepted precedents
correcting ambiguous semantic classifications.

PR-#2341

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The output separately records the resolver's login, but the reply filter excludes only bot
identities and accepts every User. The classification then tests only whether that unrestricted set
is nonempty.

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[159-179]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The fetcher attributes any human reply to the resolver and treats its presence as an explicit dismissal, even when the reply came from someone else or says the finding will be fixed.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[170-179]
- internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads-test.sh[150-170]

## Recommended Fix
Keep human replies as context without inferring dismissal from their presence. If a resolver-specific rationale is needed, match the comment author to `resolvedBy.login`; add tests for another person's reply and a reply that accepts the finding.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. Review fetching bypasses the forge layer ✓ Resolved
Description
pre-fetch-resolved-threads.sh constructs a GitHub GraphQL query and sends it with gh api graphql
outside internal/forge/github/. The new workflow runs this script for each review, creating a
direct GitHub API call in the scaffolded script rather than routing it through the required forge
abstraction.
Code

internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[R81-85]

+  gh_args=(api graphql
+    -f owner="${OWNER}"
+    -f name="${NAME}"
+    -F number="${PR_NUM}"
+    -f query="${QUERY}")
Relevance

● Weak

Recent precedents rejected findings requiring direct GitHub API calls to move from workflows or
scripts into forge abstractions.

PR-#5578
PR-#7484

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The cited script defines a GitHub review-threads GraphQL query and passes it directly to `gh api
graphql; the checklist restricts direct GitHub API calls to internal/forge/github/`.

Rule 1062054: Restrict direct GitHub API calls to internal/forge/github
internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[42-66]
internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[81-90]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new review-thread fetch makes a direct GitHub GraphQL call from a script outside the designated forge package.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[42-66]
- internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh[81-90]

## Recommended Fix
Move the GitHub-specific request into the designated forge abstraction and have the review workflow invoke that abstraction.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Review workflow lacks the guide check ⊘ Outdated
Description
reusable-review.yml adds a step that passes the minted review token to a new script, but neither
the PR description nor an inline comment says docs/contributing/ci-workflows.md was consulted.
This runs in a reusable review job that can receive pull_request_target context and secrets,
making the missing consultation relevant to the new step.
Code

.github/workflows/reusable-review.yml[R158-161]

+      - name: Pre-fetch human-resolved review threads
+        id: resolved-threads
+        env:
+          GH_TOKEN: ${{ steps.app-token.outputs.token }}
Relevance

● Weak

Recent precedent explicitly rejected this exact guide-consultation finding for a pull_request_target
workflow using secrets.

PR-#7845

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new step receives the review token. The workflow is reusable, has declared secrets, and contains
a pull_request_target checkout path; the PR text and changed step provide no explicit
guide-consultation statement required by the checklist.

Rule 3201588: Consult CI workflow guide when modifying GitHub Actions workflows or secrets
.github/workflows/reusable-review.yml[34-50]
.github/workflows/reusable-review.yml[158-168]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR adds token-using review workflow logic without recording consultation of the CI workflow guide.

## Fix Focus Areas
- .github/workflows/reusable-review.yml[158-168]

## Recommended Fix
Review `docs/contributing/ci-workflows.md` against the new step and state in the PR description that the guide was consulted.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 79 rules
✅ Cross-repo context — repo relationships
  Explored: repo: fullsend-ai/experiments (sha: 3f1614fa) — View relationship
  Explored: repo: fullsend-ai/.fullsend (sha: 7c163cad) — View relationship
  Explored: repo: fullsend-ai/pi-xai-vertex (sha: 8f50bdda) — View relationship
  Explored: repo: fullsend-ai/scribe (sha: 0f3eb528) — View relationship
  Explored: repo: fullsend-ai/agents (sha: 3af27dde) — View relationship
  Explored: repo: fullsend-ai/mlflow-assessments (sha: 46f42987) — View relationship
  Explored: repo: fullsend-ai/pi-anthropic-vertex (sha: 960eff35) — View relationship
  Explored: repo: fullsend-ai/metrics (sha: c47da589) — View relationship
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 5/18, lines 610/200; both must reach the floor). Router rationale: This adds substantial, security-adjacent workflow behavior and complex GraphQL pagination/filtering/parsing across a new script, with many independent edge cases that could evade a single review pass.

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Findings visible per group, which tucks the rest behind a View link

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh Outdated
@codecov

codecov Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.08537% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/forge/gitlab/mr.go 98.46% 1 Missing and 1 partial ⚠️
internal/forge/github/github.go 99.28% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@csoceanu
csoceanu force-pushed the aisdlc-118/fetch-resolved-threads branch from 17271c7 to a07841a Compare October 1, 2026 13:40
csoceanu added a commit to csoceanu/fullsend that referenced this pull request Oct 1, 2026
Address Qodo review findings on PR fullsend-ai#7907:

1. human_response and resolution_context now only consider comments
   from the resolvedBy user, not any human. When one reviewer comments
   and another resolves the thread, the first reviewer's reply is no
   longer misattributed as the resolution rationale.

2. Add truncated flag to metadata when the 20-page cap is hit, so
   consumers know the resolved-threads list may be incomplete.

Add test cases: different commenter produces silent_resolution,
resolver's own comment produces explicit_dismissal, truncated flag
is false under the page cap.

Signed-off-by: csoceanu <csoceanu@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rh-hemartin

Copy link
Copy Markdown
Member

Hello! Could you explore doing this within pre-script on the review agent? It should be able to detect the variable GITHUB_ACTIONS and then pull the resolved threads.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Three findings below: two HIGH and one MEDIUM.

Comment thread internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh Outdated
Comment thread .github/workflows/reusable-review.yml Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh Outdated
Benkapner added a commit to Benkapner/fullsend that referenced this pull request Oct 4, 2026
Treat a non-string findings[].id as missing so the rest of the review
still posts. Scan the id like other finding fields and drop the stamp
if it looks like a secret. Point the regex comment at fullsend-ai#7907.

Addresses: AISDLC-122
Signed-off-by: Benjamin Kapner <bkapner@redhat.com>
csoceanu added a commit to csoceanu/fullsend that referenced this pull request Oct 4, 2026
Address Qodo review findings on PR fullsend-ai#7907:

1. human_response and resolution_context now only consider comments
   from the resolvedBy user, not any human. When one reviewer comments
   and another resolves the thread, the first reviewer's reply is no
   longer misattributed as the resolution rationale.

2. Add truncated flag to metadata when the 20-page cap is hit, so
   consumers know the resolved-threads list may be incomplete.

Add test cases: different commenter produces silent_resolution,
resolver's own comment produces explicit_dismissal, truncated flag
is false under the page cap.

Signed-off-by: csoceanu <csoceanu@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@csoceanu
csoceanu force-pushed the aisdlc-118/fetch-resolved-threads branch from a01a4b9 to 6abd14d Compare October 4, 2026 11:38
@csoceanu

csoceanu commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

@rh-hemartin - Thanks for the suggestion. The pre-script path now checks GITHUB_ACTIONS=true before fetching resolved threads, and invokes the fullsend CLI through the forge client to write human-resolved-threads.json.
The agent-side consumption of that file remains a separate follow-up in the agents repository, as planned for Workstream A. This PR is limited to the fullsend-side fetch and workflow wiring.

@csoceanu
csoceanu requested a review from waynesun09 October 5, 2026 08:51

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Four findings below: one HIGH and three MEDIUM.

Comment thread .github/workflows/reusable-dispatch.yml Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh Outdated
Comment thread internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh Outdated
Comment thread internal/cli/fetchreviewthreads.go
csoceanu added a commit to csoceanu/fullsend that referenced this pull request Oct 6, 2026
Address Qodo review findings on PR fullsend-ai#7907:

1. human_response and resolution_context now only consider comments
   from the resolvedBy user, not any human. When one reviewer comments
   and another resolves the thread, the first reviewer's reply is no
   longer misattributed as the resolution rationale.

2. Add truncated flag to metadata when the 20-page cap is hit, so
   consumers know the resolved-threads list may be incomplete.

Add test cases: different commenter produces silent_resolution,
resolver's own comment produces explicit_dismissal, truncated flag
is false under the page cap.

Signed-off-by: csoceanu <csoceanu@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@csoceanu
csoceanu force-pushed the aisdlc-118/fetch-resolved-threads branch 3 times, most recently from 68bd354 to 2430ff3 Compare October 6, 2026 07:24
@Benkapner

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:28 AM UTC · Completed 7:46 AM UTC

Commit: 2430ff3 · View workflow run →

Runtime: pi · Model: openai/gpt-6.1-sol → gpt-6.1-sol · Effort: high · Cost: $3.13

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Site preview

Preview: https://3ab9884c-site.fullsend-ai.workers.dev

Commit: 6b28b0c208def2e2a1b3f7fe2b7323c1edbd6ff6

@fullsend-ai-review fullsend-ai-review Bot added the risk/elevated PR risk: elevated label Oct 6, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Risk Assessment: elevated (3/5)

Details

Elevated risk is driven by large change volume modifying two protected reusable workflows in an active codebase with high churn and author contention, balanced by additive-only context collection and graceful fallbacks.

Previous run

Risk Assessment: elevated (3/5)

Details

Score assigned due to large change size touching protected CI workflows and high historical churn on modified files, balanced by clean issue scope alignment, absent risk labels, and additive fail-safe context gathering.

@fullsend-ai-review

fullsend-ai-review Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Review

Reason: missing-context

This PR was NOT reviewed. Do not count this as an approval.

Previous run

Review

Findings

High

  • [api-contract] .github/workflows/reusable-dispatch.yml:966 — The new context-fetching CLI installation conflicts with the subsequent review-agent installation when both build from source. Both .github/actions/install-fullsend-cli/action.yml and the root action.yml initialize ${RUNNER_TEMP}/fullsend-src and unconditionally add its origin remote. For a non-vendored installation pinned to an unreleased workflow SHA, the second installer encounters an existing origin and exits before running the review agent. The same sequence appears in reusable-review.yml.
    Remediation: Reuse the CLI installed for context fetching, use distinct source directories, or make checkout initialization idempotent. Add a regression test exercising both installations sequentially with an unreleased SHA.

Medium

  • [protected-path] .github/workflows/reusable-dispatch.yml — This PR modifies protected infrastructure files .github/workflows/reusable-dispatch.yml and .github/workflows/reusable-review.yml. The linked issues and PR description explain the context-fetching changes; human approval is always required for protected-path changes, regardless of that context.

Low

  • [naming-convention] internal/cli/fetchreviewthreads.go:47 — The forge flag's default uses the raw domain value github instead of repos.ForgeGitHub, contrary to the explicit typed-constant convention in docs/contributing/go-code.md.
    Remediation: Import internal/repos and use repos.ForgeGitHub as the forge flag default.

  • [doc-style] internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh:20 — The header attributes required environment variables to the review agent, although the reusable workflows set them and execute this script before the agent. It also places optional FULLSEND_BIN in the required list and omits the optional FULLSEND_APP_SET identity prefix.
    Remediation: Attribute the variables to the workflow and separate required inputs from optional FULLSEND_BIN and FULLSEND_APP_SET, following pre-fetch-prior-review.sh.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

Review

Findings

High

  • [logic-error] .github/workflows/reusable-dispatch.yml:957 — CLI install-mode detection runs after 'Checkout upstream defaults', which explicitly checks out action.yml into .defaults. Consequently, a non-vendored installation without a caller binary selects mode=vendored. The installer then requires .fullsend/bin/fullsend and exits with 'vendored binary not found', preventing the review agent from running. The same faulty detection appears in reusable-review.yml:141. The added alignment test asserts the condition's presence rather than exercising the checkout sequence.
    Remediation: Determine vendored mode from the actual caller binary, or record whether defaults were vendored before the upstream checkout. Apply the correction to both workflows and test a non-vendored checkout after upstream defaults have been populated.

Medium

  • [logic-error] internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh:100 — The resolver filter excludes suffixed bot logins but not the unsuffixed organization, shared, or configured app-set review identities that the comment filter explicitly recognizes. An unsuffixed bot resolver can therefore pass the human-resolution filter. For a complete thread with a recognized Bot finding comment containing a finding marker, the transformation can emit that bot's resolution as human-resolved context. Existing resolver-exclusion fixtures use suffixed logins. See also: [auth-bypass] finding at this location.
    Remediation: Exclude the known unsuffixed organization, shared, and custom app-set review logins as resolvers as well as their suffixed forms. Add fixtures covering unsuffixed bot resolvers.

  • [api-contract] internal/forge/github/github.go:3629 — The GraphQL operation appends /graphql to the client's REST API base URL. GitHub Enterprise Server client construction derives that base as https://HOST/api/v3, producing https://HOST/api/v3/graphql instead of the enterprise GraphQL endpoint https://HOST/api/graphql. Enterprise review-thread fetching therefore targets the wrong endpoint. The CLI test explicitly asserts /api/v3/graphql and encodes the same error.
    Remediation: Resolve the GraphQL endpoint separately from the REST base URL, preserving /graphql for api.github.com and using /api/graphql for GitHub Enterprise Server. Update the CLI test to verify the enterprise endpoint.

  • [auth-bypass] internal/scaffold/fullsend-repo/scripts/pre-fetch-resolved-threads.sh:101 — The human-resolution boundary relies on login suffixes rather than the resolver's actor type. GraphQL bot logins are unsuffixed, and the query fetches only resolvedBy.login. An unsuffixed bot resolver can pass the filter and be represented as a human decision for an otherwise eligible finding thread. If that resolver also commented, lines 134–143 can label the bot's text as human_response and explicit_dismissal. This PR produces misleading trusted context; actual downstream suppression is deferred to the agents repository. See also: [logic-error] finding at this location.
    Remediation: Fetch resolvedBy.__typename, preserve the resolver actor type in the normalized forge structure, and require a positively identified human User before including a resolution. Add tests for unsuffixed shared, org-specific, custom app-set, and unrelated bot resolvers.

  • [protected-path] .github/workflows/reusable-dispatch.yml — The PR modifies protected workflow files: .github/workflows/reusable-dispatch.yml, .github/workflows/reusable-review.yml. The linked issues and PR description explain the review-context collection rationale, but human approval is always required for protected-path changes, regardless of context.

Low

  • [deprecated-architecture] .github/workflows/reusable-dispatch.yml:1006 — The new review-thread fetch extends per-org compatibility through FULLSEND_DIR: ${{ inputs.install_mode == 'per-repo' && '.fullsend' || '' }}. The same addition appears in reusable-review.yml:191. ADR 0044 and repository instructions prohibit extending the deprecated per-org installation model; this new feature should use the canonical per-repo layout.
    Remediation: Avoid introducing new per-org branching for this feature and use the per-repo .fullsend/ script layout consistently in both review entry points.

  • [missing-doc] docs/contributing/documentation.md:125 — The 'Minor commands' documentation index lists commands with lighter documentation footprints but omits the newly introduced fetch-review-threads command. The command itself is documented in cli-internals.md, so this is an index omission rather than a lack of user-facing command documentation.
    Remediation: Add fetch-review-threads to the minor commands list in docs/contributing/documentation.md.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

Comment thread internal/forge/gitlab/mr.go Outdated
Comment thread internal/forge/gitlab/mr.go
Comment thread internal/forge/forge.go Outdated
@rh-hemartin

Copy link
Copy Markdown
Member

I think the title and body PR can change as this no longer add the script, but just the command line.

Expose verified actor roles for review threads.

Keep GitLab resolution attribution and documentation consistent.

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: csoceanu <csoceanu@redhat.com>
@csoceanu csoceanu changed the title feat(review): fetch human-resolved review threads before agent runs feat(review): add forge-backed review thread fetching Oct 7, 2026
@csoceanu

csoceanu commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

@ralphbean @rh-hemartin , all three requested changes are implemented and tested. The PR now contains the forge abstraction, CLI command, GitHub/GitLab review-thread integrations, verified actor-role metadata, and the related documentation. Agent-side consumption remains a separate follow-up. The PR title and description were updated to reflect the current scope. Could you please re-review the current head 6b28b0c?

Comment thread .github/workflows/reusable-dispatch.yml
@ralphbean ralphbean added the ok-to-test Allow e2e CI to run after maintainer review (must be re-applied after each push) label Oct 7, 2026
@ralphbean
ralphbean enabled auto-merge October 7, 2026 19:12

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Two MEDIUM findings below. Both concern the output contract that the agents-side consumer will rely on. Neither blocks merge, and a follow-up issue is fine.

Comment thread internal/forge/github/github.go
Comment thread internal/forge/github/github.go

This branch was successfully deployed

2 active deployments
dev — 6b28b0c2 Deployed Oct 8, 2026 by ralphbean via run / behaviour #4205
site-preview — 6b28b0c2 Deployed Oct 7, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Allow e2e CI to run after maintainer review (must be re-applied after each push)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants