Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ site/.next/
site/.output/
site/.vercel/
.tmp-bench/
.audit/
2 changes: 1 addition & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"ignorePatterns": ["dist/**", "test/__snapshots__/**", "site/routeTree.gen.ts"],
"ignorePatterns": ["dist/**", "test/__snapshots__/**", "site/routeTree.gen.ts", ".audit/**"],
"printWidth": 100,
"semi": true,
"singleQuote": false
Expand Down
2 changes: 1 addition & 1 deletion .pr-agent/module-layout.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ globs:
- "src/**"
---

Keep public entries: review → `orchestrator/orchestratorRun.ts`, `publish/publishSummaryOnly.ts`, `publish/publishFindingBatch.ts`, `ci/analyzeCi.ts`; workspace → `prWorkspace/index.ts`; intake → `planner.ts` / `applier.ts`; executors → `executors/index.ts`; web → `agentWork/runtime.ts` (`agentWorkWebLive`); worker → `agentWork/workerRuntime.ts` (`agentWorkWorkerLive`). Import GitHub review error helpers (`isLineResolutionPublishError`, etc.) from `src/github/reviewErrors.js` — not via `reviewDiffPlacement.ts` or other placement re-exports.
Keep public entries: review → `orchestrator/orchestratorRun.ts`, `publish/publishSummaryOnly.ts`, `publish/publishFindingBatch.ts`, `ci/analyzeCi.ts`; workspace → `prWorkspace/index.ts`; intake → `planner.ts` / `applier.ts`; executors → `src/agentWork/executors/*.ts`; web → `agentWork/runtime.ts` (`agentWorkWebLive`); worker → `agentWork/worker.ts` (`agentWorkWorkerLive`). Import GitHub review error helpers (`isLineResolutionPublishError`, etc.) from `src/github/reviewErrors.js` — not via `reviewDiffPlacement.ts` or other placement re-exports.
2 changes: 1 addition & 1 deletion CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ This file is **domain language only** — not a specification of how the system
- **Review summary comment** — The completed form of a review progress comment: navigation and overview gates, not duplicated finding bodies from inline review threads. Owns "what's risky" (gates, findings table) and the aggregate **agent fix prompt** accordion below the table; never carries a per-file walkthrough or review map. When a published description agent block includes a **review map**, the summary links to that map instead of duplicating it; short omit-mode PRs get no link.
- **Review overview (`prCharacter`)** — Free-form Note on the review summary comment. Authored at synthesis via `publish_summary`. Uses the same **body scale** map as description writing policy (brief / standard / detailed from workspace size stats) plus ASD-STE100 short active sentences. States what the PR changes and review stakes; never inventories files, restates the findings table, or reports specialist-lane process.
- **Review size (`size`)** — T-shirt scale (`XS`, `S`, `M`, `L`, `XL`, `XXL`) for the magnitude of the change set, not code quality or review cost. Model-authored at synthesis. Shown as the Size row on the **review summary comment** and synced onto the PR as the managed `size:<TOKEN>` label when `FEATURE_REVIEW_LABELS` is on.
- **Finding confidence** — Per-finding certainty level (`c1`–`c5`) shown beside severity in the review summary comment; expresses how sure the reviewer is about one finding, nothing else. Prompts ask models to drop scored findings below the configured minimum (`REVIEW_MIN_CONFIDENCE`, default `1`).
- **Finding confidence** — Per-finding certainty level (`c1`–`c5`) shown beside severity in the review summary comment; expresses how sure the reviewer is about one finding, nothing else. The specialist finding-field contract tells the model to drop anything it would mark `1`.
- **CI summary** — Gate row on the **review progress comment** stub and completed **review summary comment**. Server fetches external check runs, legacy commit statuses, and (when failing) one condensed, redacted, size-bounded CI context for the PR head (Actions job logs, or check output if logs are unavailable; excluding PR Agent’s own check), then a small LLM turn authors structured fields (`headline`, per-failure `reason` / `fixHint`). Failing-head annotation and job-log fetches run concurrently within `REVIEW_CI_SUMMARY_FETCH_CONCURRENCY`; workflow runs are filtered to the reviewed head before any job listing, and raw job logs are bounded to a failure-preserving intake window before condensation. Server owns status facts, check-run completeness, wait/poll, redaction, schema validation, and HTML rendering; the model must not emit the table markup. Ack uses a lightweight non-LLM snapshot only. When CI is still pending at publish, the row stays pending; a later `workflow_run` or `check_suite` completed webhook refreshes the CI cell on the matching summary without a full re-review. A refresh that arrives while a review is still queued or running is retained and retried on the same lane for that head SHA until it can patch or the attempt cap is exhausted. An incomplete check-run page (pagination cap) is **unavailable**, not passing or none, and does not use the grant-Checks copy. Known failures in that partial view stay failing; the headline notes the partial view. A later complete poll or refresh can replace the snapshot. Missing Checks permission shows a grant-Checks row; missing Actions permission on a red head keeps the failure row and adds a grant-Actions note. Caps live in code constants (`REVIEW_CI_SUMMARY_*`). See [ADR 0018](docs/adr/0018-llm-authored-ci-summary.md).
- **Prose contract** — Changed Markdown that defines behavior (agent instructions, skill definitions, configuration docs) rather than merely describing it. The review orchestrator checks prose contracts for internal consistency: counts vs listed items, cross-references that resolve, command examples that are neither broken nor destructive, stated defaults vs the rest of the diff. Contradictions are ordinary findings, not style nits.
- **Truncated change set** — File listing for an orchestrated review run where some changed files are omitted due to configured caps; the run continues with explicit truncation metadata.
Expand Down
6 changes: 3 additions & 3 deletions docs/adr/0009-review-location-validation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ADR 0009 — Cached diff validation and best-effort inline publish

> **Changelog:** §6 revised 2026-05-25narrowed **Public-output sanitizer** after false-positive whole-field redaction on normal review prose (see PR #38).
> **Changelog:** §6 revised 2026-05-25, narrowed **Public-output sanitizer** after false-positive whole-field redaction on normal review prose (see PR #38). 2026-09-05, §1 names the workspace ingest path and §5 names `MAX_THREAD_PUBLISH_CALLS` after unused `MAX_REVIEW_PUBLISH_CALLS` was removed.

## Status

Expand All @@ -12,15 +12,15 @@ Structured review publish could fail when GitHub rejected inline review anchors

## Decision

1. **Cached diff index** — Capture `listPullRequestFiles` output during the review run and derive `commentableRightLineRanges` per file. Do not fetch a fresh diff at publish time.
1. **Cached diff index** — Load GitHub pull-request file listing into the cached diff index during workspace setup (`ingestListPullRequestFilesResult` in `src/review/placement/reviewDiffIndex.ts`, fed by `src/github/listPullRequestFiles.ts`). Derive `commentableRightLineRanges` per file. Do not fetch a fresh diff at publish time.

2. **Server-side placement** — Validate each finding against cached ranges before calling GitHub. Unresolvable findings become **summary-only findings**; the model does not choose placement.

3. **Summary always publishes** — Always upsert the structured PR conversation summary when the run succeeds. Incremental inline batches ([ADR 0020](0020-orchestrated-review.md)) are best-effort; GitHub rejections are logged privately and become **summary-only findings**.

4. **Deterministic failure notice** — When publish is exhausted, upsert a neutral review failure notice without model-authored fallback prose, attempt counts, or internal API details.

5. **Publish execution budget** — Cap valid `submitReview` publish executions with `MAX_REVIEW_PUBLISH_CALLS` (default 2), separate from model recovery phases.
5. **Publish execution budget** — Cap incremental inline GitHub review batches with `MAX_THREAD_PUBLISH_CALLS` (default 8), separate from model recovery phases. The older `MAX_REVIEW_PUBLISH_CALLS` cap on `submitReview` was unused after orchestrated publish landed and is gone.

6. **Public-output sanitizer** — At the pre-publish boundary (`prepareReviewPayloadForPublish`), replace credential- and assignment-shaped substrings in PR-visible review text with `[redacted]` (shared `BOT_SECRET_PATTERNS` via `redactOutboundSecrets`). Do not whole-field redact code-review vocabulary (`submitReview`, `GitHub API`, etc.). Internal failure phrasing on overview fields (`prCharacter`, `securityConcerns`, `followUps`) is rejected by **Review payload** validation (repair loop), not silently redacted. Finding fields are not checked for internal phrasing.

Expand Down
4 changes: 0 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,6 @@ An orchestrated review computes its hard return deadline from the pg-boss job st
| ---------------------------------------- | --------------------------------------------------------------- |
| `MAX_TOOL_ROUNDS` | 24 for orchestrator reconnaissance and specialist investigation |
| `ORCHESTRATOR_JUDGMENT_MAX_TOOL_ROUNDS` | 4 per specialist judgment turn |
| `MAX_REVIEW_PUBLISH_CALLS` | 2 valid calls for the retained structured review tool contract |
| `REVIEW_MIN_CONFIDENCE` | 1, drop scored findings below this |
| `MAX_PR_FILES_LISTED` | 300, within the GitHub API cap |
| `MAX_PR_FILES_PATCH_BYTES` | 500000 |
| `REVIEW_ANCHOR_MENU_MAX_FILES` | 40 |
Expand All @@ -306,8 +304,6 @@ An orchestrated review computes its hard return deadline from the pg-boss job st
| `SESSION_CACHE_ID_MAX_LENGTH` | 64 — OpenAI-style `prompt_cache_key` clamp for Pi session ids |
| `VALIDATION_REPAIR_ROUNDS` | 3 |
| `PUBLISH_RECOVERY_ROUNDS` | 4 summary recovery sends |
| `PUBLISH_BUDGET_EXHAUSTED_MESSAGE` | Structured review tool guard |
| `REVIEW_DIFF_CACHE_REQUIRED_MESSAGE` | Structured review diff-cache guard |
| `REVIEW_ANCHOR_MENU_BLOCK_LABEL` | Untrusted anchor menu block label |
| `ReviewValidationFailureKind` | Validation failure metric categories |
| `ReviewPhase` | Review metric categories |
Expand Down
28 changes: 14 additions & 14 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ Binding review rules live in [`.pr-agent/*.mdc`](../.pr-agent/) — this guide i

## Module layout (production)

| Area | Path | Public entry |
| -------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Review run + publish | `src/review/` | `orchestrator/orchestratorRun.ts`, `publish/publishSummaryOnly.ts`, `publish/publishFindingBatch.ts`, `ci/analyzeCi.ts` (LLM CI summary: `ci/authorCiSummary.ts`); metrics/footer helpers under `run/` |
| Local PR workspace | `src/prWorkspace/` | `index.ts` (`withPrRepositoryView`); `workspaceResource.ts` owns temp-root allocation, ownership marker/heartbeat, credentials, and idempotent release |
| Code index (optional FTS) | `src/codeIndex/` | `chunker.ts` (linear per-line recognition), `buildJob.ts`, `search.ts`, `repository.ts` |
| Agent work intake | `src/agentWork/intake/` | `planner.ts` (pure), `applier.ts` (Postgres + pg-boss) |
| Agent work execution | `src/agentWork/executors/` | `index.ts` |
| Web / worker layers | `src/agentWork/runtime.ts`, `workerRuntime.ts` | `agentWorkWebLive` (web); `agentWorkWorkerLive` (worker-only import graph) |
| Ask / description / verification | `src/agent/` | `ask/askRun.ts`, `description/descriptionRun.ts`, `verification/verificationRun.ts` |
| Pi session seam | `src/agent/runtime/` | `piSession.ts` (`createPiSession`, `createFakePiSession`); `createFeaturePiSession` wraps `send` and `restartWithFallback` so fallback sessions keep checkpoint/snapshot persistence — feature harnesses must not import raw Pi SDK sessions |
| PR surface seam | `src/github/` | `prSurface.ts` (`createPrSurface`, `createFakePrSurface`); leased mutation recovery is `recoverPrSurfaceMutation.ts` — worker/feature code must not import `prSurfaceImpl.ts` or thread installation tokens |
| Agent tool outputs | `src/agent/tools/` | `toolOutputBudget.ts`, `localWorkspaceTools.ts`, `codeIndexTools.ts`, `context7Tools.ts`; review sessions fence results with `wrapUntrustedEvidence` in `src/review/run/reviewRunSetup.ts` |
| Outbound security | `src/security/` | `redactOutboundSecrets.ts`, `context7OutboundPolicy.ts` |
| Analytics facade | `src/analytics/` | `index.ts` (`initAnalytics`, `captureEvent`, `captureException`, `shutdownAnalytics`) |
| Area | Path | Public entry |
| -------------------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Review run + publish | `src/review/` | `orchestrator/orchestratorRun.ts`, `publish/publishSummaryOnly.ts`, `publish/publishFindingBatch.ts`, `ci/analyzeCi.ts` (LLM CI summary: `ci/authorCiSummary.ts`); metrics/footer helpers under `run/` |
| Local PR workspace | `src/prWorkspace/` | `index.ts` (`withPrRepositoryView`); `workspaceResource.ts` owns temp-root allocation, ownership marker/heartbeat, credentials, and idempotent release |
| Code index (optional FTS) | `src/codeIndex/` | `chunker.ts` (linear per-line recognition), `buildJob.ts`, `search.ts`, `repository.ts` |
| Agent work intake | `src/agentWork/intake/` | `planner.ts` (pure), `applier.ts` (Postgres + pg-boss) |
| Agent work execution | `src/agentWork/executors/` | individual executor files imported by `worker.ts` |
| Web / worker layers | `src/agentWork/runtime.ts`, `worker.ts` | `agentWorkWebLive` (web); `agentWorkWorkerLive` (worker-only import graph) |
| Ask / description / verification | `src/agent/` | `ask/askRun.ts`, `description/descriptionRun.ts`, `verification/verificationRun.ts` |
| Pi session seam | `src/agent/runtime/` | `piSession.ts` (`createPiSession`, `createFakePiSession`); `createFeaturePiSession` wraps `send` and `restartWithFallback` so fallback sessions keep checkpoint/snapshot persistence — feature harnesses must not import raw Pi SDK sessions |
| PR surface seam | `src/github/` | `prSurface.ts` (`createPrSurface`, `createFakePrSurface`); leased mutation recovery is `recoverPrSurfaceMutation.ts` — worker/feature code must not import `prSurfaceImpl.ts` or thread installation tokens |
| Agent tool outputs | `src/agent/tools/` | `toolOutputBudget.ts`, `localWorkspaceTools.ts`, `codeIndexTools.ts`, `context7Tools.ts`; review sessions fence results with `wrapUntrustedEvidence` in `src/review/run/reviewRunSetup.ts` |
| Outbound security | `src/security/` | `redactOutboundSecrets.ts`, `context7OutboundPolicy.ts` |
| Analytics facade | `src/analytics/` | `index.ts` (`initAnalytics`, `captureEvent`, `captureException`, `shutdownAnalytics`) |

Review, ask, description, and verification take the prepared Local PR workspace object. Verification derives the Pi session working directory from `workspace.agentCwd` and uses that object's `grepLiteral` and cached PR-patch diffs. It does not keep a second string checkout path.

Expand Down
Loading
Loading