# agdt-initiate-pull-request-review-workflow

> **General template.** Copy this file to
> `.agdt-temp/EXPECTATIONS-agdt-initiate-pull-request-review-workflow.md` and
> specialize it for your exact command and flags before executing.

## TL;DR

Bootstraps an isolated pull-request-review environment. The command resolves a
PR id and (optionally) a Jira issue key — cross-looking-up whichever is missing
— fetches the PR's source branch, and then either runs the review **in the
current worktree** (when pre-flight passes) or **spawns a background auto-setup**
that creates a sibling worktree on the PR source branch, prepares all review
data, opens VS Code, and starts a Copilot review session. The command itself
prepares data and starts a session; the actual review verdicts are produced
downstream by the Copilot agent.

## Parameters & State Keys

### CLI flags

| Flag | Effect | Default |
|------|--------|---------|
| `--pull-request-id` / `-p` | PR to review. Cross-looked-up from `--issue-key` when omitted. | none |
| `--issue-key` / `-i` | Jira issue key used to find the PR and to scope the worktree. Cross-looked-up from the PR when omitted. | none |
| `--interactive true\|false` | Start the Copilot session attached to the terminal (`true`) or detached/background (`false`). | `false` |
| `--model <id>` | Copilot model for the session. | project config or `gpt-4o` |
| `--engine copilot\|langchain` | Review engine: `copilot` uses the Copilot-agent-based flow; `langchain` uses the autonomous LangGraph pipeline. | `copilot` |
| `--use-langchain` | Shorthand for `--engine langchain`. | off |
| `--no-source-context` | Disable source context enrichment (LangChain engine only). When set, the LangGraph pipeline skips fetching full file content from the source branch. Rejected with a CLI error unless `--engine langchain` or `--use-langchain` is selected. | off |
| `--skip-copilot-session` | Run PR-review setup **synchronously** and start no session. Used by the nested auto-execute invocation inside the background task. | off |
| `--force-rereview` | Force a re-review of the current commit even if the same model/identity already reviewed it. Overwrites the existing per-commit review comment in place instead of posting a skip notice. Propagated to the nested auto-execute invocation. | off |
| `--execution-mode` | Execution safety policy mode: `live` (default behavior), `dry_run` (simulate all external mutations), or `restricted` (block all non-read-only actions). Persisted to `orchestration.execution_mode` in state after scope is established. Honored by the `SafetyEnforcer` in `ToolExecutor`. | resolved from state/env |

### State keys

| Key | Role |
|-----|------|
| `pull_request_id` | Resolved PR id (persisted; written after `jira.issue_key` to protect scope pinning). |
| `jira.issue_key` | Resolved Jira issue key (written first when both ids are present). |
| `copilot.model_id` | Persisted model id for the session. |
| `review.force_rereview` | Persisted `--force-rereview` flag; read by the review scaffold to override same-model skip and re-render the commit's review comment in place. |
| `review.engine` | Persisted engine selection: `copilot` or `langchain`. |
| `review.source_context_enabled` | Whether source context enrichment is enabled (LangChain engine). |
| `orchestration.execution_mode` | Persisted `--execution-mode` value (`live`/`dry_run`/`restricted`); written after bootstrap scope is established; honored by the `SafetyEnforcer`. |
| `review.commit_hash_short` | First 12 chars of the PR merge-source commit; scopes the artifact directory. |
| `review.jira_fetch_failed` | Set `true` when the Jira fetch fails during setup (non-fatal). |
| `review.rebase_conflicts_detected` | Set when sync-with-main rebase hits conflicts (non-fatal). |
| `background.task_id` | Background auto-setup task id (preflight-fail path). |
| `worktree_setup.*` | Parameters consumed by the background setup task. |
| `agdt_run_id` | Run id for the single-commit-per-run amend strategy. |

### Environment overrides

| Variable | Effect |
|----------|--------|
| `AGENTIC_DEVTOOLS_STATE_DIR` | Pins the state directory; skips pin-file writes and bootstrap scope derivation. |
| `AGDT_AUTO_TRUST_COPILOT` | Optional kill-switch for auto-trusting agdt-managed worktree folders before Copilot launch (`0`/`false`/`no`/`off` disables). |
| `AGDT_DRY_RUN` / `dry_run` state | Preview mode honored by the downstream review-summary cascade. |

## Decision Points / Paths

1. **Identifier resolution** — `--pull-request-id` only (look up Jira from PR),
   `--issue-key` only (look up PR from Jira; hard exit if none found), or both
   (no lookup).
2. **Source branch fetch** — required. If the source branch cannot be
   determined (auth/network/PR missing) the command removes the pin file and
   exits `1`.
3. **Pre-flight** — PASS (folder + branch already match the worktree
   identifier) proceeds in-context; FAIL spawns the background auto-setup.
4. **Engine selection** — after pre-flight passes (either immediately or in the
   nested `--skip-copilot-session` re-run), `--engine langchain` (or
   `--use-langchain`) routes to the autonomous LangGraph pipeline
   (`run_langchain_review_background`); `--engine copilot` (default) proceeds
   with the Copilot-agent-based flow. `--no-source-context` is valid only for
   LangChain and is rejected early for Copilot mode. The nested auto-setup
   command preserves the selected engine and `--no-source-context` flag.
5. **`--skip-copilot-session`** — synchronous setup with no session (nested
   auto-execute) vs async setup plus a Copilot session.
6. **`--interactive`** — attached terminal session vs background session.
7. **Worktree existence** — auto-setup reuses an existing worktree or creates a
   new one on the PR source branch.
8. **Rebase conflicts** — flagged via `review.rebase_conflicts_detected`,
   non-fatal.
9. **Jira fetch** — failure sets `review.jira_fetch_failed`, non-fatal.
10. **Re-review semantics** (per reviewed commit, evaluated by the review
    scaffold once the session runs):

    - **Same commit + same model + already completed** → the review is
      **skipped**; a reply is posted on that commit's thread explaining the skip
      and giving the `--force-rereview` command. `--force-rereview` overrides
      this: files are reset and the commit's review comment is re-rendered in
      place.
    - **Same commit + different model** → the new model's review is posted as a
      **reply** within the existing commit thread (no `--force-rereview`
      needed); a re-run of the same additional model updates that reply in place.
    - **Different commit** → a **new top-level thread** is created for the new
      commit; the prior commit is archived into the per-commit registry and
      appears in the "Previous reviews" index (hash + jump link).

11. **`AGENTIC_DEVTOOLS_STATE_DIR`** — when set, pin-file writes and bootstrap
    scope derivation are skipped (the override wins).
12. **Copilot folder trust seeding** — after a worktree is validated/created (not
    before), the workflow best-effort seeds Copilot CLI `trustedFolders` for that
    path (gated by `AGDT_AUTO_TRUST_COPILOT` and project flag
    `auto_trust_copilot_worktrees`).
13. **VS Code / TTY / autostart** — determine whether the session starts via the
    VS Code `folderOpen` task, a terminal fallback, or a background process.

## Execution Flow

1. Parse flags; resolve `model` (falls back to the default model).
2. Resolve bootstrap identity and worktree scope (priority `issue_key` over
   `PR{pull_request_id}`) before any state I/O.
3. Pin the state directory: when `AGENTIC_DEVTOOLS_STATE_DIR` is set, reuse it;
   otherwise delete any stale pin, resolve the scoped state dir, write a pin
   file, and export the env var.
4. Clear workflow tracking state (preserving `agdt_run_id` when
   `--skip-copilot-session` is set); set `copilot.model_id` and
   `orchestration.execution_mode` (when `--execution-mode` was provided);
   remove any stale VS Code auto-start task.
5. Persist the provided identifiers (issue key first when both are present),
   then cross-look-up the missing identifier. Exit `1` if no PR can be resolved.
6. Fetch the PR source branch; exit `1` if it cannot be determined.
7. Run the pre-flight check against the worktree identifier (issue key, else
   `PR{pull_request_id}`), allowing an exact source-branch match.
8. **Pre-flight FAIL** → build the nested auto-execute command (adds
   `--skip-copilot-session` and preserves `--engine langchain` /
   `--no-source-context` when selected) and call `perform_auto_setup(...)`; on
   success print the message and return. (See the background sequence below.)
9. **Engine check** — once pre-flight passes in the current process, when
   `--engine langchain` (or `--use-langchain`), call
   `run_langchain_review_background()` with the resolved PR id, model config,
   and source-context flag. The LangGraph pipeline runs as a background task
   and the command returns immediately with the task id. Step 10 is skipped.
10. **Pre-flight PASS + engine=copilot** → run the setup:

    - `--skip-copilot-session` → run `setup_pull_request_review()`
      synchronously.
    - normal → remove any stale prompt file, spawn the async setup,
      and start the Copilot PR-review session.

### Background auto-setup sequence (preflight-fail path)

The background task (`setup_worktree_in_background_sync`) reuses an existing
worktree or creates a new one on the PR source branch, injects VS Code settings,
runs the repo setup script, runs the nested `--skip-copilot-session` command to
synchronously prepare PR data (Jira fetch, PR details, per-file prompts, review
queue, scaffolded threads, initiate prompt), records
`worktree_setup.auto_execute_exit_code`, injects the VS Code auto-start task,
opens VS Code, and starts the Copilot review session. When worktree reuse/create
succeeds, Copilot trust seeding runs best-effort before launch so `copilot` does
not block on the "Confirm folder trust" prompt.

## Observable Side Effects

- **Worktree** — reused or newly created on the PR source branch (preflight-fail
  path), with `.vscode/settings.json` and `tasks.json` injected.
- **Copilot CLI config** — best-effort update of
  `~/.copilot/config.json` (`COPILOT_HOME` aware) to include the worktree in
  `trustedFolders` once the worktree is confirmed valid, gated by
  `AGDT_AUTO_TRUST_COPILOT` / `auto_trust_copilot_worktrees`.
- **State directory** `.agdt/workflows/{identity}/{worktree_key}/` containing:
  `state.json`, `temp-get-issue-details-response.json`,
  `temp-get-pull-request-details-response.json`,
  `pull-request-review/<commit_hash_short>/` (per-file `file-*.md`,
  `manifest.json`, `answers/` (per-file answer JSONs + the answer ledger),
  `queue.json`, file/threads/issue snapshots), `reviews/review-state.json`, and
  `temp-pull-request-review-initiate-prompt.md`.
- **Pin file** + `runtime-bootstrap.json` scoping state to the worktree.
- **Background task** record + logs (preflight-fail path).
- **Azure DevOps PR** — one consolidated review comment **per reviewed commit**
  (created during setup as a new top-level thread for the current commit). While
  the review is in progress the comment is kept lightweight (status headline
  only); on completion it is re-rendered with full content, rolling over into
  continuation replies past a 50k-character smart cutoff. Prior commits collapse
  into a "Previous reviews" hash+link index.
- **Jira** — read-only fetch of the linked issue for context.
- **Process / VS Code** — a new VS Code window and a `gh copilot` session
  (interactive or background per `--interactive` and environment).

## Success Criteria

1. Pre-flight correctly classifies context (no `_unscoped` fallback dir).
2. When preflight fails, a worktree on the PR source branch is prepared and
   `worktree_setup.auto_execute_exit_code == 0`.
3. PR data is fully prepared before the session starts: PR details, per-file
   prompts, `manifest.json` + scaffolded `answers/`, `queue.json`, and
   `reviews/review-state.json` exist and are mutually consistent. The
   `delegate` step's progress counts (`total/pending/completed/all_complete`)
   derive from `manifest.json` plus the answer ledger — not `queue.json`.
4. Workflow state shows `name=pull-request-review` with the correct PR /
   issue-key context.
5. The per-commit consolidated review comment is visible on the PR (lightweight
   while in progress; full content once complete).
6. Exactly one Copilot session starts (no duplicate from the autostart fallback).
7. Hard-exit paths (no source branch, no PR found) exit `1` and remove the pin
   file rather than creating partial state.

## AI Agent Session Choreography

The initiate command **prepares review data and starts a session**; the actual
review verdicts are produced by the Copilot agent that the session hosts. After
the session opens, the agent is guided through the `pull-request-review` state
machine
([`manager.py`](../../agentic_devtools/cli/workflows/manager.py) →
`PULL_REQUEST_REVIEW_WORKFLOW`) using per-step prompts under
[`agentic_devtools/prompts/pull-request-review/`](../../agentic_devtools/prompts/pull-request-review/).
Each step renders `temp-pull-request-review-<step>-prompt.md` into the state
directory.

### Session entrypoint

- The `gh copilot` session opens on the **initiate** prompt
  (`temp-pull-request-review-initiate-prompt.md`; see
  `_start_copilot_session_for_pr_review` and
  `_WORKFLOW_PROMPT_FILENAMES["pull-request-review"]` in
  [`worktree_setup.py`](../../agentic_devtools/cli/workflows/worktree_setup.py)).
- The initiate prompt is intentionally minimal: it tells the agent to **hand off
  to `@agdt.advance-workflow`** to load the pr-synthesis step, and to **not**
  start reviewing files manually before the handoff completes.

### How the agent is guided between steps

- The v2 chain has a **single delegate path**:
  `initiate → pr-synthesis → delegate → consolidate-and-submit → decision →
  completion`. Every transition is **manual** (`MANUAL_ADVANCE`): the agent runs
  `agdt-advance-workflow <step>`.
- When an orchestration node raises a pending decision (e.g., a tool classified
  as `requires_confirmation` by the decision policy), the agent resolves it with
  `agdt-advance-workflow --decision {approve|deny} --decision-id <ID> [--run-id <RUN_ID>]`
  instead of a step name.
- There is **no** file-review self-loop. During `delegate` the orchestrator fans
  the per-file reviewers out internally (one `file-reviewer` subagent per file)
  and keeps its own context bounded by reading on-disk artifacts.

### Step-by-step choreography

| Step | Prompt presented to the agent | Commands the agent is expected to run | Transition event → next step |
|------|-------------------------------|---------------------------------------|------------------------------|
| `initiate` | `default-initiate-prompt.md` | Hand off to `@agdt.advance-workflow`; do no manual review yet | `MANUAL_ADVANCE` → `pr-synthesis` |
| `pr-synthesis` | `default-pr-synthesis-prompt.md` | `agdt-pr-review-build-manifest`, `agdt-pr-review-triage`; author `pr-context.md`; rubber-duck triage (`--layer mainAgent`); then `agdt-advance-workflow delegate` | `MANUAL_ADVANCE` → `delegate` |
| `delegate` | `default-delegate-prompt.md` | Spawn one `pr-review/file-reviewer@<fileKey>` per file (writes via `agdt-file-review-write`); for `deep` files run ducks (`agdt-pr-review-resolve-ducks --layer subagent`); cross-file synthesis; then `agdt-advance-workflow consolidate-and-submit` | `MANUAL_ADVANCE` → `consolidate-and-submit` |
| `consolidate-and-submit` | `default-consolidate-and-submit-prompt.md` | `agdt-pr-review-refresh-comment` (live) and `agdt-pr-review-submit` (terminal fan-in) + `agdt-task-wait`; then `agdt-advance-workflow decision` | `MANUAL_ADVANCE` → `decision` |
| `decision` | `default-decision-prompt.md` | Make the final call: approve via `agdt-set content` + `agdt-set is_pull_request_approval true` + `agdt-add-pull-request-comment` + `agdt-task-wait`; or request changes via `agdt-set content` + `agdt-add-pull-request-comment` | `MANUAL_ADVANCE` → `completion` |
| `completion` | `default-completion-prompt.md` | Optionally post a Jira summary via `agdt-set jira.comment` + `agdt-add-jira-comment`; then `agdt-clear-workflow` | terminal step |

### Verdict side effects (per file-reviewer + submit)

Each file-reviewer subagent writes only its own scoped answer via
`agdt-file-review-write`; the orchestrator is the sole writer of shared state.
`agdt-pr-review-refresh-comment` keeps the per-commit comment lightweight while
in progress (status headline only — `🔃 In Progress`, reviewer/model, and
`N approved · M need work · X/Y reviewed`). `agdt-pr-review-submit` is the single
terminal mutation: it re-renders the comment with full content (`✅ Approved` /
`📝 Needs Work`) split across the root comment and continuation replies past the
50k smart cutoff, posts line-anchored suggestion threads, and cascades status
(file → folder → overall).

A **different model** reviewing the same commit appends its review as a reply
within the commit thread (updated in place on re-run); a **same-model re-review**
is skipped with a `--force-rereview` hint unless that flag is set; and a **new
commit** starts a fresh top-level thread, archiving the prior commit into the
"Previous reviews" index.

### Subagents

The agent **hands off to the `@agdt.advance-workflow` Copilot Chat subagent** to
move between steps. The v2 review is driven by
`@agdt.pull-request-review.orchestrator`, which spawns
`@agdt.pull-request-review.file-reviewer` (one per file), runs all
`@agdt.pull-request-review.rubber-duck` critics itself, and hands triage to
`@agdt.pull-request-review.triage`. An auditing agent running
[`agdt.test-workflow`](../../.github/prompts/agdt.test-workflow.prompt.md) also
spawns a **rubber-duck subagent** to review its specialized expectations
document before execution.

## Workflow Diagram

```mermaid
flowchart TD
    Start([Command invoked]) --> Parse[Parse flags and resolve model]
    Parse --> FlagCheck{--no-source-context with copilot engine}
    FlagCheck -- Yes --> ExitBadFlags[Exit 2 with CLI usage error]
    FlagCheck -- No --> Scope[Bootstrap identity and worktree scope]
    Scope --> Pin{State dir env override set}
    Pin -- Yes --> UseEnv[Reuse env state dir and skip pin file]
    Pin -- No --> WritePin[Write pin file and export state dir]
    UseEnv --> Clear[Clear workflow tracking state]
    WritePin --> Clear
    Clear --> Ids{Which identifiers provided}
    Ids -- PR id only --> LookupJira[Look up Jira issue from PR]
    Ids -- Issue key only --> LookupPR[Look up PR from Jira issue]
    Ids -- Both --> NoLookup[Use both identifiers]
    LookupPR --> PRFound{PR found}
    PRFound -- No --> ExitNoPR[Remove pin and exit 1]
    PRFound -- Yes --> Branch[Fetch PR source branch]
    LookupJira --> Branch
    NoLookup --> Branch
    Branch --> BranchOK{Source branch known}
    BranchOK -- No --> ExitNoBranch[Remove pin and exit 1]
    BranchOK -- Yes --> Preflight{In correct worktree and branch}
    Preflight -- No --> AutoSetup[Spawn background worktree auto-setup]
    AutoSetup --> Return[Print success and return]
    Preflight -- Yes --> Engine{Engine selection}
    Engine -- langchain --> LangChain[Run LangGraph pipeline as background task]
    LangChain --> LCReturn[Print task id and return]
    Engine -- copilot --> SkipSession{Skip copilot session set}
    SkipSession -- Yes --> SyncSetup[Run PR review setup synchronously]
    SkipSession -- No --> AsyncSetup[Spawn async setup and start Copilot session]

    subgraph BG[Background auto-setup task]
        direction TB
        BG1[Create or reuse worktree on source branch]
        BG1 --> BG1a[Seed Copilot trustedFolders for the validated worktree best effort]
        BG1a --> BG2[Inject VS Code settings and run setup script]
        BG2 --> BG3[Run nested command with skip copilot session and preserved engine flags]
        BG3 --> BG4[Prepare PR data and scaffold per-commit review comment]
        BG4 --> BG4a{Re-review semantics for current commit}
        BG4a -- New commit --> BG4New[POST new top-level thread; archive prior commit into index]
        BG4a -- Same model already reviewed and no force-rereview --> BG4Skip[Reply: review skipped, suggest --force-rereview]
        BG4a -- Same model with force-rereview --> BG4Force[Reset files and re-render comment in place]
        BG4a -- Different model --> BG4Model[Reply with model review inside commit thread]
        BG4New --> BG5[Inject auto start task and open VS Code]
        BG4Skip --> BG5
        BG4Force --> BG5
        BG4Model --> BG5
        BG5 --> BG6[Start Copilot review session]
    end

    subgraph PD[Pending-decision side-channel]
        direction LR
        PD1[Orchestration node requires confirmation] --> PD2[Write decision to pending-decisions.json]
        PD2 --> PD3[Agent resolves: agdt-advance-workflow --decision approve/deny --decision-id ID]
        PD3 --> PD4[Execution resumes from LangGraph checkpoint]
    end

    AutoSetup -.-> BG1
    BG6 -.->|node raises pending decision| PD1
```

## Agent Session Choreography Diagram

This diagram shows the prompt-driven journey the Copilot review agent takes
**after** the session starts, including the command that triggers each
transition.

```mermaid
flowchart TD
    Entry([Copilot session opens on initiate prompt]) --> Handoff[Hand off to agdt.advance-workflow]
    Handoff --> Synthesis[pr-synthesis step: manifest + triage + pr-context]
    Synthesis -->|agdt-advance-workflow delegate| Delegate[delegate step: one file-reviewer per file]
    Delegate --> Fanout{All files answered}
    Fanout -- No, deep file --> Ducks[Run rubber ducks; integrate verdicts]
    Ducks --> Delegate
    Fanout -- Yes --> ToConsolidate[agdt-advance-workflow consolidate-and-submit]
    ToConsolidate --> Consolidate[consolidate-and-submit: refresh + submit]
    Consolidate -->|agdt-advance-workflow decision| Decision[decision step]
    Decision -->|approve: add-pull-request-comment with approval| Completion[completion step]
    Decision -->|request changes: add-pull-request-comment| Completion
    Completion -->|optional Jira summary then agdt-clear-workflow| Done([Review complete])
    Delegate -.->|orchestration node raises pending decision| PendingDec[agdt-advance-workflow --decision approve/deny --decision-id ID]
    PendingDec -.->|execution resumes from checkpoint| Delegate
```

---

This is a **general template**. Copy it to
`.agdt-temp/EXPECTATIONS-agdt-initiate-pull-request-review-workflow.md` and
**specialize** it for your exact command and flags before executing.
