Skip to content

fix(paper-writing): harden PDF review and LaTeX main-file selection - #3887

Merged
nonoqing merged 2 commits into
openBitFun:mainfrom
nonoqing:claude/pdf-review-hardening
Nov 12, 2026
Merged

nonoqing merged 2 commits into
openBitFun:mainfrom
nonoqing:claude/pdf-review-hardening

Conversation

@nonoqing

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #3870. Fixes four problems in the Paper Writing PDF review flow:

  1. Encrypted PDFs showed a save-failure alert as soon as they were opened.
  2. A review file changed outside the window could never be saved again.
  3. Adding one note after a recompile hid the "check positions" warning for every earlier note.
  4. The main-file field rebuilt the review pane, and could start a compile, on every keystroke.

Type and Areas

  • Bug fix.
  • Web UI editor (PDF review, LaTeX workbench), locales, Desktop README.

Motivation / Impact

Encrypted PDFs. Workspace PDFs open through PdfReviewEditor, which parsed them with PDFDocument.load and no ignoreEncryption. Owner-password PDFs, common for publisher downloads, failed there although pdf.js renders them. They now open normally and keep notes in the review sidecar. Save PDF and Export annotated PDF are disabled with an explanation: pdf-lib cannot encrypt the objects it adds and keeps /Encrypt on save, so readers would decrypt the new annotation strings into garbage. PDFs that pdf-lib cannot parse get the same notice instead of a save-failure alert.

Review file conflicts. After <source>.openbitfun-review.json changed on the workspace host, every autosave failed and Retry repeated the same compare-and-swap, so the tab stayed dirty until it was closed and its unsaved notes were lost. A FILE_CONFLICT refusal, or a lost write whose reconciliation finds a different version, now pauses writes and keeps the local notes. The user chooses Replace with my notes (compare-and-swap against the version just read) or Load the file's notes; Undo restores the local notes after loading.

Recompile warning. Every save stamped the current PDF fingerprint into the review, so any edit after a recompile marked all earlier notes as placed on the new build. The fingerprint is now written only with the first save; later edits and Save PDF keep it. The warning stays until the user selects Positions checked.

Main-file entry. The field changed the build target and review owner on every keystroke. Each prefix remounted the review pane and created a review session whose Save All participant stayed registered, and with auto compile on, a pause compiled the partial path. The entry now applies on Enter or blur; Escape restores the applied value. Save All also skips review sessions without unsaved changes, so a session for an abandoned or unreadable path cannot fail saving the source.

Local history has no existing fix; the only follow-ups to #3870 (3a08949c62, b1025b72d4) touch other code.

Verification

On this branch (base a8913094cb) in a clean worktree, after installing dependencies and running pnpm run gen:types:

  • 120 tests passed across 14 focused files, including 14 new tests that each failed before their fix. From src/web-ui:
node scripts/run-vitest.mjs run \
  src/tools/editor/pdf-review \
  src/tools/editor/components/{LatexEditor,PdfViewer,CodeEditor}.test.tsx \
  src/tools/editor/services/{MonacoModelManager,editorViewResidency,EditorDocument}.test.ts \
  src/tools/editor/languages/latex.language.test.ts \
  src/tools/editor/utils/latexDocument.test.ts \
  src/infrastructure/file-export/savePdfFile.test.ts \
  src/infrastructure/api/service-api/LatexAPI.test.ts \
  src/app/workbench/ContentResourceView.shortcuts.test.tsx
  • pnpm exec tsc --noEmit from src/web-ui: passed.
  • pnpm run i18n:audit, pnpm run check:repo-hygiene, pnpm run appearance:contract-audit, pnpm run theme:color-audit:all, and pnpm run theme:visual-contract: passed.
  • ESLint on the changed source files and git diff --check: passed.
  • pnpm run typography:audit reports only the existing violation in unchanged design-system/packages/ui/src/components/Dialog/Dialog.module.css:77, which is also present on the base.
  • Not manually verified in the Desktop app.

Reviewer Notes

  • Two commits: the PDF review fixes, then the LaTeX main-file entry.
  • Conflict detection keys off the FILE_CONFLICT refusal from write_target_checked, which serves local and remote targets on Desktop and the CLI peer host. A host that words the refusal differently still reaches the conflict state on the next save through the existing lost-response reconciliation; a test covers that path.
  • readPdfReviewSource replaces extractReviewedPdf and reports encryption from the same parse it uses to extract an embedded review.
  • The review JSON shape is unchanged, so existing sidecars and embedded reviews load as before. Six new strings are added in en-US, zh-CN, and zh-TW.
  • Live remote workspace, Remote Connect/bot control, Peer Device Mode, and Detached Dispatch were not exercised. These are local DOM, PDF-format, and simulated transport tests.
  • AI-assisted. Testing level: lightly tested (focused automated coverage; no manual Desktop verification).

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, including the existing typography failure.
  • User-facing strings, docs, and locales are updated where applicable.

Open encrypted PDFs with ignoreEncryption and keep their notes in the
review sidecar. pdf-lib cannot encrypt the objects it adds and keeps
/Encrypt when saving, so Save PDF and Export are disabled for these files
instead of producing unreadable annotations. PDFs that pdf-lib cannot
parse get the same notice rather than a save-failure alert.

A FILE_CONFLICT refusal, or a lost write whose reconciliation finds
another version, now pauses review writes and keeps the local notes until
the user replaces that exact host version or loads it; Undo restores the
local notes. Retry previously repeated the same failing write.

Saves no longer stamp the current PDF fingerprint over the build the
notes were placed on, so adding a note after a recompile no longer hides
the position warning. The warning stays until the user confirms the
current layout.

Save All skips review sessions without unsaved changes, so a session for
an abandoned or unreadable path cannot block saving the source.
The main-file field changed the build target and review owner on every
keystroke: each prefix remounted the PDF review pane with a new review
session, and auto compile built partial paths. Keep a draft until Enter
or blur; Escape restores the applied value.
@nonoqing
nonoqing merged commit fb06e1d into openBitFun:main Nov 12, 2026
13 checks passed
@nonoqing
nonoqing deleted the claude/pdf-review-hardening branch November 12, 2026 03:55
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.

1 participant