Skip to content

feat(review): add frozen staged snapshot reviews - #1511

Open
Qiyuanqiii wants to merge 4 commits into
alibaba:mainfrom
Qiyuanqiii:codex/staged-snapshot
Open

Qiyuanqiii wants to merge 4 commits into
alibaba:mainfrom
Qiyuanqiii:codex/staged-snapshot

Conversation

@Qiyuanqiii

@Qiyuanqiii Qiyuanqiii commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Description

Adds ocr review --staged to review the content prepared for the next commit. OCR captures the complete Git index and HEAD at the start of the run, then uses that snapshot for the diff and all built-in code-context tools.

For example, a partially staged file can contain a defect while its working-tree version already contains the fix. Staged review examines the version that will be committed. The captured input stays stable throughout the review, including when files are edited or staged again.

ocr review --staged
ocr review --staged --preview
ocr review --staged --preview --format json
ocr review --staged --format json --output staged-review.json

Snapshot and selection

Capture copies the active index into a private temporary index and writes an immutable Git tree. It checks the original index and the resolved HEAD commit for changes during capture. The tree includes unchanged files used as context. In a repository with no commits, the comparison starts from an empty tree.

Before reading file content, OCR checks the old and new modes in a NUL-delimited raw diff between the captured trees. This rejects changed gitlinks, including pure renames. The review patch retains ordinary rename detection.

The snapshot supplies:

  • The diff, full-file reads, file discovery, and content search.
  • Repository .gitattributes, including attributes used for binary classification.
  • Default project rules in .opencodereview/ and their referenced documents.

Each snapshot rule file, including rule.json, has a 512 KiB limit. Referenced documents must be ordinary files in the snapshot, specified by repository-relative paths. Missing files, absolute paths, oversized files, and symlink references produce an error.

Explicit --rule files, --exclude, global configuration, Git configuration, global attributes, and .git/info/attributes retain their configured sources. Custom MCP servers and external tools use their own data sources and may access the live working tree.

Staged paths remain eligible for review regardless of .gitignore patterns. OCR applies its directory and secret exclusions, supported-file allowlist, and review-rule exclusions to the paths tracked in the index. Preview shows the selected files, exclusion reasons, and input identity. Each invocation captures the current index.

Capture preserves the user's index, working tree, and refs. The private index is removed after capture. Tree objects written to the repository follow Git's normal garbage-collection lifecycle.

Input identity

Staged results use ocr.run-manifest/v2:

Field Value
input.mode staged
input.resolved_base Captured HEAD commit; omitted before the first commit
input.snapshot_tree Tree object ID for the complete index snapshot
input.resolved_head Omitted
input.exact_range Omitted

JSON preview includes the same input identity. Other review modes keep their v1 format. Consumers of staged results need support for the v2 schema and its tree identity.

Usage and Git support

  • Requires Git 2.41 or later.
  • Supports partial staging, initial commits, linked worktrees, alternative GIT_INDEX_FILE paths, and SHA-256 repositories.
  • An empty staged diff completes without an LLM call.
  • --staged is mutually exclusive with --from, --to, --commit, and --resume. Staged sessions currently have no resume support.
  • Unresolved conflicts, intent-to-add entries (git add -N), split indexes, and sparse indexes produce an error.
  • Changed submodule/gitlink entries produce an error before file content is read. This covers additions, updates, deletions, pure renames, and conversions between regular files and gitlinks.
  • Repositories with unchanged submodules support ordinary-file review. Built-in discovery and search exclude gitlink content, and direct reads reject gitlink paths. Symbolic links are read as their stored link blobs.

The CLI reference and architecture pages are updated in English, Chinese, Japanese, Korean, and Russian. Both copies of the review skill route staged-change requests to ocr review --staged and document staged preview, flag conflicts, and resume behavior.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring (no functional changes)
  • Documentation update
  • CI / Build / Tooling

How Has This Been Tested?

At ad3bd56, all GitHub checks passed. The Linux/Windows CI run reports 91.5% Linux coverage and confirms successful execution of the POSIX cancellation and state-preservation regressions.

At fbe46d0, local make check, make build, and the full make coverage suite passed with 91.1% coverage. The diff package passed race tests. A pure gitlink-rename regression reproduced the prior failure and now passes; raw-diff tests cover special path bytes, SHA-256 object IDs, and malformed records. The compiled CLI rejects the same rename fixture while preserving index bytes, HEAD, and refs.

Local validation used Windows/amd64, Go 1.26.5, and Git 2.54.0.windows.1, with implementation baseline cf64e7080f600d507888a26785ad6a8b7a13ab6a:

  • make license-add, make check, and make build passed.
  • The full make test suite passed with the race detector.
  • make coverage reported 91.1%, above the 90% threshold.
  • The compiled CLI produced a staged JSON preview with a valid tree identity, preserved the original index hash and HEAD, and rejected conflicting flags before execution.

Regression coverage includes:

Area Checks
Git inputs Partial staging, initial commits, empty input, linked worktrees, alternative indexes, SHA-256 repositories, additions, renames, deletions, symlink blobs, binary files, and mode-only changes
Snapshot consistency HEAD, index, and working-tree mutations after capture; unchanged context files; staged files removed from the working tree before capture
Built-in tools A local model double restages the repository after its first request; file_read, file_find, code_search, and file_read_diff continue to return the original snapshot
Configuration Captured project rules, referenced documents, and repository attributes; explicit rule overrides; submodule display and recursion settings
State preservation Index bytes, raw HEAD, ref identities, and worktree paths, modes, and contents remain unchanged after capture failure or cancellation; the private index directory is cleaned up
Output and sessions Text/JSON preview identity, saved-session readback, and staged v2 coverage counts in the viewer
Error handling Conflicting flags, unresolved merges, intent-to-add, split/sparse indexes, malformed indexes, cancellation, and changed gitlinks

The during-capture mutation and cancellation tests use POSIX shell shims. A FIFO handshake triggers cancellation after write-tree completes. Linux CI executes these cases; Windows runs the remaining state-preservation cases. Functional tests use local model doubles for deterministic assertions.

Pre-commit review

Ran the repository-required ocr review --audience agent --background ... with OCR v1.11.9 and DeepSeek deepseek-v4-flash. Both review runs completed all 19 selected production files without a failed review item. Their findings were checked against the code and focused regressions, not treated as automatically correct.

Confirmed issues addressed before submission include Git submodule display settings bypassing the changed-gitlink guard; non-blob reads of unchanged gitlinks; implicit content-search recursion into unchanged submodules; lost errors/cancellation during unborn-HEAD probes; and a shared rule-loading deadline that did not scale with the number of documents. The final code also preserves Git diagnostics, uses explicit snapshot parameters, and documents the intentional rule-file restrictions. Focused tests cover the fixes, followed by the full final validation listed above.

The repeated claim that --attr-source requires Git 2.43 was rejected after checking the Git 2.41 source and documentation, which already implement and document the option. No claim of zero raw model findings is made, and this automated review does not replace contributor self-review.

For the wrap-up changes, the configured provider rejected a further ocr review request before review completed; that attempt is not counted as a successful review. OCR v1.12.7 delegation mode supplied file selection and Go rules, and Codex reviewed all three changed files (one selected production file plus both test files, which OCR excludes by default). This review found no blocking issues. Focused race tests cover the affected rules/tool packages and new capture-state tests; make check also passes.

Checklist

  • Code follows the project's automated style and vet checks.
  • I have performed a self-review of my code
  • Added regression tests for the new behavior.
  • New and existing unit tests pass locally as described above.
  • I have updated the documentation accordingly (if applicable)
  • I have signed the CLA

AI/LLM disclosure

OpenAI Codex (GPT-6) assisted with implementation, tests, documentation, and preparation of this description. The repository-required pre-commit review uses the open-code-review CLI; its model and result are recorded in the validation section.

Related Issues

Closes #1510.

@github-actions

github-actions Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

🔍 OpenCodeReview found 1 issue(s) in this PR.

  • ✅ Successfully posted inline: 1 comment(s)

Comment thread internal/config/rules/snapshot.go Outdated
@Qiyuanqiii

Copy link
Copy Markdown
Contributor Author

@NanaseInori review

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

I re-reviewed the latest head (ad3bd56). The additional state-preservation and cancellation coverage is useful, and the earlier snapshot-rule diagnostic issue is fixed. The overall staged-snapshot design also looks coherent to me.

I found one gitlink case that still breaks the stated staged-mode boundary, though.

stagedDiffHasGitlink() detects mode/index headers containing 160000, but a pure rename of an unchanged gitlink does not necessarily emit any of those headers. Git can render it as only:

diff --git a/subold b/subnew
similarity index 100%
rename from subold
rename to subnew

In that case, stagedDiffHasGitlink() returns false and the change proceeds into ParseDiffText(). finalizeDiff() then attempts:

git show <snapshot-tree>:subnew

even though that tree entry is a gitlink/commit rather than a blob.

In the usual case this may fail because the submodule commit object is not present in the superproject. If that object is present, however, git show can render the commit as output and that content can enter the review path as though it were file content. That is exactly the situation the pre-parser gitlink guard is intended to prevent.

I think the gitlink check should use structural mode information rather than relying only on unified-diff headers. For example, a git diff --raw -z --find-renames ... preflight could reject any changed entry whose old or new mode is 160000, including a 100% gitlink rename.

A regression test for renaming an unchanged gitlink from one path to another would pin this case.

There are also two documentation follow-ups worth including with this feature:

  • The localized architecture.md files still describe the diff provider as having only three modes: Workspace, Commit, and Range.
  • Both copies of open-code-review/SKILL.md still say “Stage selectively if you want narrower scope”. That is no longer the right guidance once --staged exists, because bare ocr review still includes staged, unstaged, and untracked changes. The skill should route requests such as “review my staged changes” to ocr review --staged.

I don't currently see another implementation blocker beyond the gitlink-rename case. CI, CodeQL, Pages, translation-sync, and plugin-contract are all green.

@Qiyuanqiii
Qiyuanqiii marked this pull request as ready for review September 21, 2026 07:19
@Qiyuanqiii

Copy link
Copy Markdown
Contributor Author

@NanaseInori review

@chaojixinren

Copy link
Copy Markdown
Contributor

LGTM.
I checked out fbe46d0 and built/tested on this machine:

  • Host: macOS 26.6.2 (25G83), darwin/arm64
  • Go: 1.25.7
  • Git: 2.50.1 (Apple Git-155)
  • Binary: make build → ./dist/opencodereview v1.12.7 (fbe46d0)

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(review): review a frozen Git index snapshot with --staged

3 participants