Skip to content

Fix Cleanup, LastOpenedFiles and XMP reset and import#15874

Merged
calixtus merged 13 commits into
mainfrom
fix-cleanup-reset-import
Jun 7, 2026
Merged

Fix Cleanup, LastOpenedFiles and XMP reset and import#15874
calixtus merged 13 commits into
mainfrom
fix-cleanup-reset-import

Conversation

@calixtus

@calixtus calixtus commented Jun 1, 2026

Copy link
Copy Markdown
Member

Related issues and pull requests

Follow-up to #15870

PR Description

  • Migrated Cleanup, LastFilesOpened and XmpPreferences

  • Fixed and added region comments

      `jabref-contrib-policy:4.2:reviewed​:ok`
    

Steps to test

Run JabRef
Open Preferences
Mess around with preferences
Save
Reopen
Reset
See preferences reset

AI usage


Claude Code (model claude-sonnet-4-6)

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (always required)
  • [.] I added JUnit tests for changes (if applicable)
  • [.] I added screenshots in the PR description (if change is visible to the user)
  • [.] I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • [.] I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • [.] I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@calixtus calixtus added component: cleanup-ops status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers dev: code-quality Issues related to code or architecture decisions component: preferences labels Jun 1, 2026
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix preferences reset, import, and cleanup migration

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Fixed reset and import functionality for CleanupPreferences, LastFilesOpenedPreferences, and
  XmpPreferences
• Migrated preferences to use factory methods and setAll patterns for proper state management
• Removed unused CliPreferences injection from SavingPropertiesView
• Added default preference values and region comments for code organization
• Fixed preference migration to handle missing keys with proper defaults
Diagram
flowchart LR
  A["Preferences Classes<br/>Cleanup, LastFiles, Xmp"] -->|"Add getDefault()<br/>and setAll()"| B["Factory Methods"]
  B -->|"Use in clear()"| C["Reset Functionality"]
  B -->|"Use in import()"| D["Import Functionality"]
  E["JabRefCliPreferences"] -->|"Remove getDefaultCleanupPreset()"| F["Simplified API"]
  G["SavingPropertiesView"] -->|"Remove CliPreferences injection"| H["Cleaner Dependencies"]

Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/libraryproperties/saving/SavingPropertiesView.java ✨ Enhancement +1/-5

Remove unused CliPreferences dependency

• Removed unused CliPreferences injection and import
• Removed @Inject annotation for preferences field
• Updated SavingPropertiesViewModel instantiation to remove preferences parameter

jabgui/src/main/java/org/jabref/gui/libraryproperties/saving/SavingPropertiesView.java


2. jabgui/src/main/java/org/jabref/gui/libraryproperties/saving/SavingPropertiesViewModel.java ✨ Enhancement +2/-5

Remove CliPreferences dependency from ViewModel

• Removed CliPreferences field and constructor parameter
• Changed preferences.getDefaultCleanupPreset() to CleanupPreferences.getDefault()
• Simplified constructor to only require BibDatabaseContext

jabgui/src/main/java/org/jabref/gui/libraryproperties/saving/SavingPropertiesViewModel.java


3. jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java 🐞 Bug fix +1/-1

Fix cleanup preferences migration with defaults

• Fixed upgradeCleanups() method to provide default empty string when key is missing
• Changed prefs.get(V5_8_CLEANUP_FIELD_FORMATTERS) to `prefs.get(V5_8_CLEANUP_FIELD_FORMATTERS,
 "")`

jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java


View more (5)
4. jablib/src/main/java/org/jabref/logic/cleanup/CleanupPreferences.java ✨ Enhancement +35/-2

Add factory methods and default values

• Added static DEFAULT_ACTIVE_JOBS and DEFAULT_FIELD_FORMATTER_CLEANUPS constants
• Added private no-arg constructor for default initialization
• Added getDefault() factory method
• Added setAll() method for state synchronization
• Updated constructor to use DEFAULT_SAVE_ACTIONS instead of empty ArrayList

jablib/src/main/java/org/jabref/logic/cleanup/CleanupPreferences.java


5. jablib/src/main/java/org/jabref/logic/preferences/CliPreferences.java ✨ Enhancement +0/-2

Remove getDefaultCleanupPreset method

• Removed getDefaultCleanupPreset() method from interface

jablib/src/main/java/org/jabref/logic/preferences/CliPreferences.java


6. jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java 🐞 Bug fix +74/-66

Refactor preferences migration and reset logic

• Removed default values for XMP and cleanup preferences from constructor
• Removed getDefaultCleanupPreset() implementation
• Removed getDefaultCleanupJobs() helper method
• Added getCleanupPreferencesFromBackingStore() method with proper defaults handling
• Added getLastFilesOpenedPreferencesFromBackingStore() method with key existence checks
• Updated getFileHistory() to accept and use defaults parameter
• Added getXmpPreferencesFromBackingStore() method with proper defaults
• Updated clear() method to call setAll() with default preferences for Cleanup, LastFilesOpened,
 and Xmp
• Updated importPreferences() method to call setAll() with backing store methods for Cleanup,
 LastFilesOpened, and Xmp
• Added region comments for code organization

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java


7. jablib/src/main/java/org/jabref/logic/preferences/LastFilesOpenedPreferences.java ✨ Enhancement +18/-0

Add factory methods and state synchronization

• Added private no-arg constructor for default initialization
• Added getDefault() factory method
• Added setAll() method for state synchronization and file history updates

jablib/src/main/java/org/jabref/logic/preferences/LastFilesOpenedPreferences.java


8. jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java ✨ Enhancement +35/-5

Add factory methods and default XMP filter fields

• Added static DEFAULT_XMP_PRIVACY_FILTER constant with standard fields
• Added private no-arg constructor for default initialization
• Changed ObjectProperty to SimpleObjectProperty for keywordSeparator
• Updated constructor to accept ReadOnlyObjectProperty and bind keywordSeparator
• Added defensive copying of xmpPrivacyFilter set
• Added getDefault() factory method
• Added setAll() method for state synchronization

jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (2) 📎 Requirement gaps (0) 🎨 UX issues (0)

Grey Divider


Action required

1. Empty cleanup jobs crash ✓ Resolved 🐞 Bug ☼ Reliability
Description
JabRefCliPreferences#getCleanupPreferencesFromBackingStore can throw when CLEANUP_JOBS exists
but is blank/empty, because it calls EnumSet.copyOf(...) on an empty collected set. This can break
preferences loading (and potentially app startup) after users disable all cleanup steps, since the
key can remain present with an empty value.
Code

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[R1827-1831]

Evidence
The preference writer stores CLEANUP_JOBS using putStringList(...) without removing the key when
the active job list is empty, while the reader unconditionally calls EnumSet.copyOf(...) when the
key exists. Since blank strings deserialize to an empty list, an empty active job configuration is
representable and can reach the failing code path.

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1807-1833]
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[588-596]
jablib/src/main/java/org/jabref/logic/cleanup/CleanupPreferences.java[66-81]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`getCleanupPreferencesFromBackingStore` builds an `EnumSet` via `EnumSet.copyOf(collectedSet)` when `hasKey(CLEANUP_JOBS)` is true. If the stored list is empty/blank, `convertStringToList` returns an empty list, leading to an empty `Set` and an exception from `EnumSet.copyOf(...)`.
### Issue Context
This is not prevented by the current `hasKey(CLEANUP_JOBS)` guard, because `hasKey` returns true even when the stored value is an empty string.
### Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1814-1833]
### Suggested fix approach
- In `getCleanupPreferencesFromBackingStore`, after parsing the list, if it is empty, return `EnumSet.noneOf(CleanupStep.class)` (or fall back to defaults) instead of calling `EnumSet.copyOf`.
- Optionally also adjust the active-jobs listener: if `cleanupPreferences.getActiveJobs()` is empty, `remove(CLEANUP_JOBS)` instead of writing an empty string, to keep `hasKey` false for the empty case.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. XmpPreferences boolean flag constructor 📘 Rule violation ⚙ Maintainability
Description
The modified public XmpPreferences(...) constructor includes a boolean-flag parameter
(useXmpPrivacyFilter) that toggles behavior, which reduces API clarity. This violates the
guideline to avoid boolean parameters in public APIs.
Code

jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java[R38-43]

Evidence
PR Compliance ID 12 forbids boolean parameters in public methods/APIs. The modified constructor
public XmpPreferences(boolean useXmpPrivacyFilter, ...) introduces/keeps a boolean flag in a
modified public API surface.

AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods: AGENTS.md: Avoid Boolean Parameters in Public Methods
jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java[38-43]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`XmpPreferences` exposes a public constructor with a boolean flag parameter (`useXmpPrivacyFilter`) that changes behavior.
## Issue Context
Per the checklist, public APIs should avoid boolean parameters and instead provide intention-revealing methods/factories.
## Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java[38-43]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Logic changes lack test updates 📘 Rule violation ☼ Reliability
Description
This PR modifies core logic preferences behavior (defaults/reset/import) in org.jabref.logic
without any corresponding test changes in the diff. This increases regression risk for preference
reset/import behavior.
Code

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[R868-882]

Evidence
PR Compliance IDs 21 and 22 require updating/adding tests when behavior changes in
org.jabref.logic. The diff shows behavioral changes in preference reset/import and new
default/setAll logic in the logic layer, but no tests are updated in the provided PR diff.

AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes): AGENTS.md: JabRef Model/Logic Changes Must Include Corresponding Test Updates (Excluding Import-Only Changes)
AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions: AGENTS.md: Testing: Update/Add Tests for Behavior Changes; Keep Tests Deterministic and Fast; Do Not Disable/Weaken Assertions
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[868-916]
jablib/src/main/java/org/jabref/logic/cleanup/CleanupPreferences.java[12-65]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Core logic behavior around preference reset/import/defaults was changed, but the PR does not show corresponding test additions/updates.
## Issue Context
Preference defaults/reset/import are behavior-critical and should be validated by automated tests to prevent regressions.
## Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[868-916]
- jablib/src/main/java/org/jabref/logic/cleanup/CleanupPreferences.java[12-65]
- jablib/src/main/java/org/jabref/logic/preferences/LastFilesOpenedPreferences.java[23-46]
- jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java[18-52]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Empty focused path persisted ✓ Resolved 🐞 Bug ≡ Correctness
Description
LastFilesOpenedPreferences.getDefault() uses Path.of("") to represent “no last focused file”,
but JabRefCliPreferences persists any non-null focused path via toAbsolutePath(), turning the
empty path into the current working directory. Because clear() now resets last-opened prefs via
setAll(getDefault()), a reset can incorrectly write the current directory as LAST_FOCUSED and
also load it when the key is missing.
Code

jablib/src/main/java/org/jabref/logic/preferences/LastFilesOpenedPreferences.java[R23-28]

Evidence
The default constructor explicitly claims there is “No last focused file” but sets an empty Path.
Reset now calls setAll(getDefault()), and persistence writes LAST_FOCUSED for any non-null path
by converting it to an absolute path; loading also constructs a Path even when LAST_FOCUSED is
absent by falling back to the default empty path string.

jablib/src/main/java/org/jabref/logic/preferences/LastFilesOpenedPreferences.java[23-35]
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[841-879]
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1869-1874]
jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1891-1894]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LastFilesOpenedPreferences` uses an empty `Path` as a sentinel for “no last focused file”. Persistence treats any non-null `Path` as valid and stores `toAbsolutePath()`, which converts the empty path to the current working directory; after this PR, `clear()` calls `setAll(LastFilesOpenedPreferences.getDefault())`, so reset/clear can persist an unintended focused path.
### Issue Context
The persistence layer already uses `null` as the signal to remove `LAST_FOCUSED`, so using an empty `Path` defeats that contract.
### Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/preferences/LastFilesOpenedPreferences.java[23-35]
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[841-879]
- jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java[1869-1894]
### Suggested fix approach
- Change `LastFilesOpenedPreferences.getDefault()` to use `null` for `lastFocusedFile`.
- In `getLastFilesOpenedPreferencesFromBackingStore`, only create a `Path` when `hasKey(LAST_FOCUSED)` and the stored string is non-blank; otherwise set `lastFocusedFile` to `null`.
- In the `lastFocusedFileProperty` listener, treat blank/empty paths the same as `null` (remove the key) to avoid persisting a sentinel value.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

lastFilesOpened = defaults.getLastFilesOpened();
}

Path lastFocused = null;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice - I hope this will work (again) after this PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Qodo says yes, and i did test it manually. So i hope so too. Otherweise there will be a followup PR.

Comment thread jablib/src/main/java/org/jabref/logic/xmp/XmpPreferences.java Outdated

@koppor koppor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some small questions - but we could merge as is.

@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers labels Jun 2, 2026
@calixtus calixtus added status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers and removed status: changes-required Pull requests that are not yet complete labels Jun 4, 2026
@calixtus calixtus requested a review from Siedlerchr June 4, 2026 21:16
@calixtus calixtus enabled auto-merge June 7, 2026 09:56
@calixtus calixtus added this pull request to the merge queue Jun 7, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Jun 7, 2026
Merged via the queue into main with commit 902094d Jun 7, 2026
88 of 90 checks passed
@calixtus calixtus deleted the fix-cleanup-reset-import branch June 7, 2026 20:49
Siedlerchr added a commit that referenced this pull request Jun 8, 2026
* upstream/main: (22 commits)
  Chore(deps): Bump com.github.andygoossens:gradle-modernizer-plugin from 1.13.0 to 1.14.0 in /build-logic (#15922)
  Chore(deps): Bump jablib/src/main/resources/csl-styles from `5bb8c99` to `e98c9e1` (#15900)
  Add ability to view citation previews on hover in 'Citations' tab (#15914)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (#15925)
  Chore(deps): Bump org.glassfish.grizzly:grizzly-bom in /versions (#15923)
  Chore(deps): Bump com.uber.nullaway:nullaway in /versions (#15924)
  SLR : Added performRawSearchQuery to Search Based Fetcher interface (#15916)
  Fix typos in .jbang/JabKitLauncher.java (#15919)
  Fix permission (#15918)
  New Crowdin updates (#15912)
  Harden CAYWResource against XSS and other security issues (#15868)
  Fix Cleanup, LastOpenedFiles and XMP reset and import (#15874)
  Add guard blocking PowerShell here-strings in Bash git commits (#15898)
  Fix ImporterPreferences reset and import (#15908)
  Chore(deps): Bump com.uber.nullaway:nullaway in /versions (#15906)
  Fix: Preserve field focus when navigating entries with keyboard shortcuts (#14943) (#15732)
  Localization consitency for some of the keys (#15824)
  chore(deps): update dependency org.glassfish.grizzly:grizzly-http-server to v5.0.2 (#15911)
  chore(deps): update dependency org.glassfish.grizzly:grizzly-framework to v5.0.2 (#15910)
  Chore(deps): Bump net.ltgt.nullaway from 3.0.0 to 3.1.0 in /jablib (#15905)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: cleanup-ops component: preferences dev: code-quality Issues related to code or architecture decisions status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants