open-code-review/pages
Gongyl01 c35ddd7223
feat(resume): add trusted resume validation and transition lineage (#786) (#845)
* feat(resume): verify input identity before reusing checkpoints

`ocr review --resume` admitted a session whenever the ref text matched, which
is neither sufficient nor necessary evidence about the input: `abc1234` and
`abc1234def` name the same commit, while a branch name that did not change can
name a new one. Resuming then mixed comments computed from one input with
comments computed from another, and nothing in the report distinguished them.

Compare the resolved input identity instead. agent.ResolveIdentity replays the
run's own selection — the same diff load and the same two filter passes — and
returns the identity a real run would record, so the parent manifest and the
child candidate are directly comparable. Any mismatch on mode, repository,
source artifact or rule config rejects the whole resume rather than degrading
to partial reuse. A provider or model change must be asked for with --provider
or --model; one that arrived through config or the environment is rejected.

Two behaviour changes fall out of this. Ref text no longer decides admission,
so ValidateOptions only checks the review mode. A parent that completed zero
items is now admitted: its manifest is verifiable, so its selected set is
simply re-dispatched, which is the case resume exists for.

Reuse is then gated on the parent manifest rather than on the checkpoint lines:
only a fingerprint the manifest claims as completed or reused is reused, which
keeps the manifest the single source of coverage truth. That gate is also what
makes an unreadable checkpoint survivable, so review loads through
LoadReviewResumeState, which drops lines it cannot parse — the file such a line
described is simply reviewed again, instead of one truncated write costing every
other file its checkpoint. Scan keeps the strict LoadResumeState, because with
no manifest to arbitrate, a dropped line cannot be told apart from a checkpoint
that was never written.

Rejection happens strictly before agent.New, because session.New writes
session_start the moment it is called — validating any later would leave an
orphan session behind every rejection. Keeping it there needs the run to review
exactly what was admitted, so the pre-flight hands back the commit endpoints it
resolved that identity from, and a resumed run loads its diff from those instead
of from the refs the user typed; file_read reads at the same sealed head. Both
loads then see the same immutable objects, so a ref moving after admission can
no longer change what the run reviews, and no mid-run re-check is needed to
discover that it did. An accepted resume records one
resume_lineage event naming the parent run and the provider/model endpoints,
surfaced by `ocr session show`; it carries non-secret labels only.

Interrupted runs become unresumable, since session_end is the sole carrier of
run_manifest. That is deliberate: an unverifiable input is exactly what this
change refuses to build on, and the error says so rather than reporting the
parent as unproductive.

Refs #786

* fix(resume): freeze refs before loading identity diff

* test(resume): cover sealed input resolution
2026-08-14 11:31:40 +08:00
..
public feat(pages): add social preview meta tags and og-image (#414) 2026-07-21 14:33:27 +08:00
src feat(resume): add trusted resume validation and transition lineage (#786) (#845) 2026-08-14 11:31:40 +08:00
.gitignore feat: init 2026-05-20 22:03:52 +08:00
eslint.config.js chore: add SPDX license headers and automated verification (#740) 2026-08-05 21:26:27 +08:00
index.html fix(pages): inline critical CSS to remove the initial white flash (#601) (#610) 2026-08-05 15:13:47 +08:00
logo.svg feat: update brand assets (#257) 2026-07-01 19:09:42 +08:00
package.json ci(pages): add smoke test step to verify build output is servable (#741) 2026-08-06 20:25:00 +08:00
postcss.config.cjs ci(pages): add ESLint and bundle size check to CI pipeline (#558) 2026-07-28 20:19:37 +08:00
README.md docs(pages): add landing page development guide (#270) 2026-07-02 16:36:54 +08:00
tailwind.config.cjs ci(pages): add ESLint and bundle size check to CI pipeline (#558) 2026-07-28 20:19:37 +08:00
tsconfig.json feat: init 2026-05-20 22:03:52 +08:00
vitest.config.ts chore: add SPDX license headers and automated verification (#740) 2026-08-05 21:26:27 +08:00
vitest.setup.ts chore: add SPDX license headers and automated verification (#740) 2026-08-05 21:26:27 +08:00
webpack.config.cjs ci(pages): add ESLint and bundle size check to CI pipeline (#558) 2026-07-28 20:19:37 +08:00

OpenCodeReview Landing Page (pages/)

This directory contains the OpenCodeReview landing page, built with TypeScript, React, Webpack, and Tailwind CSS.

Getting Started

Prerequisites

  • Node.js >=18 (recommended: latest LTS)
  • npm (comes with Node.js) or pnpm

Install dependencies

From the pages/ directory:

npm install

Or with pnpm:

pnpm install

Start local dev server

npx webpack serve

Equivalent npm script:

npm run dev

Default dev server settings (from webpack.config.js):

  • URL: http://localhost:3030
  • Host: 0.0.0.0
  • Port: 3030

Build for production

npx webpack

Project script (recommended, sets production mode):

npm run build

Build output is generated in pages/dist/.

Type checking

npm run typecheck

Project Structure

pages/
├── src/                # React + TypeScript source code
│   ├── components/     # Reusable UI components
│   ├── pages/          # Route-level page components
│   ├── i18n/           # Localization resources and i18n context
│   ├── styles/         # Global styles (Tailwind entry, custom CSS)
│   └── index.tsx       # Frontend entry point
├── dist/               # Production build artifacts (generated)
├── index.html          # HTML template used by HtmlWebpackPlugin
├── webpack.config.js   # Bundling + dev server config
├── tailwind.config.js  # Tailwind theme/content configuration
├── postcss.config.js   # PostCSS pipeline (Tailwind + Autoprefixer)
├── tsconfig.json       # TypeScript compiler options
└── package.json        # Dependencies and scripts

Development Guidelines

PR screenshots are required

Any PR that changes files in pages/ must include before/after screenshots of affected views in the PR description.

Please include:

  • What page/section changed
  • Before screenshot
  • After screenshot
  • Desktop or mobile context (if responsive behavior changed)

Code style and formatting

  • Follow existing TypeScript + React style in this directory.
  • Keep components focused and readable; prefer splitting large JSX blocks into smaller components.
  • Prefer utility-first Tailwind classes and reuse existing design tokens from tailwind.config.js.
  • Keep imports and file naming consistent with surrounding code.
  • Run npm run typecheck before opening a PR.

Tailwind CSS configuration notes

  • Tailwind config is in tailwind.config.js.
  • Content scanning targets:
    • ./src/**/*.{ts,tsx}
    • ./index.html
  • PostCSS integration is configured in postcss.config.js with:
    • tailwindcss
    • autoprefixer

TypeScript configuration notes

  • TypeScript config is in tsconfig.json.
  • Important defaults:
    • strict: true
    • jsx: react-jsx
    • target: ES2020
    • noEmit: true (Webpack handles output)

Suggested PR Checklist

  • Dependencies installed and project runs locally
  • npm run typecheck passes
  • npm run build succeeds
  • Before/after screenshots added to PR
  • Scope is limited to one logical change